/* ============================================================================
   Rich-page layouts (Calendar + Payments) — inline so they ship with the page
   and never collide with the legacy calendar-fix.css / payments-fix.css files.
   Tokens are sourced from dashboard-v2.css :root.
   ========================================================================== */

/* Premium-polish foundations: layered surfaces, glass, easing, space tokens.
   Mirrors dashboard-v2.css :root additions; declared here defensively so this
   page renders correctly even if loaded with a stale cached external CSS.
   NOTE: Anthropic-grade restraint pass — dark is the default; tokens here
   only fill in what's not covered by dashboard-v2.css. */
:root {
  --glass-blur:        saturate(140%) blur(14px);
  --ease-out:          cubic-bezier(0.2, 0, 0, 1);
  --ease-in-out:       cubic-bezier(0.4, 0, 0.2, 1);
  --space-1:  4px;  --space-2:  8px;  --space-3: 12px;
  --space-4: 16px;  --space-5: 20px;  --space-6: 24px;
  --space-7: 32px;  --space-8: 40px;  --space-9: 48px; --space-10: 64px;
  --card-pad:          36px;
  --card-pad-tight:    22px;
  --card-radius:       12px;
  --card-radius-data:   8px;
  --content-max:        960px;
  --content-max-narrow: 720px;
}
@media (max-width: 700px) {
  :root { --card-pad: 22px; }
}

/* === Motion choreography (mirrored from dashboard-v2.css) ================ */
@keyframes bs-fade-up {
  from { opacity: 0; transform: translateY(8px); }
  to   { opacity: 1; transform: translateY(0); }
}
[data-stagger] {
  opacity: 0;
  animation: bs-fade-up 0.5s var(--ease-out, cubic-bezier(0.2, 0, 0, 1)) forwards;
  animation-delay: calc(var(--bs-stagger-i, 0) * 60ms);
}
.metric-value, .pay-amt, .rec-hero-stat-value {
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum" 1, "lnum" 1;
}
.site-card.spotlight, .rec-hero.spotlight, .connect-card.spotlight {
  position: relative;
  isolation: isolate;
}
.site-card.spotlight::after,
.rec-hero.spotlight::after,
.connect-card.spotlight::after {
  content: '';
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: radial-gradient(circle at var(--bs-spot-x, 50%) var(--bs-spot-y, 50%), oklch(64.5% 0.16 38 / 0.10), transparent 40%);
  border-radius: inherit;
  opacity: 0;
  transition: opacity 0.3s var(--ease-out, cubic-bezier(0.2, 0, 0, 1));
  z-index: 1;
}
.site-card.spotlight:hover::after,
.rec-hero.spotlight:hover::after,
.connect-card.spotlight:hover::after { opacity: 1; }
.site-card.spotlight > *,
.rec-hero.spotlight > *,
.connect-card.spotlight > * { position: relative; z-index: 2; }
@keyframes bs-page-in {
  from { opacity: 0; transform: translateY(4px); }
  to   { opacity: 1; transform: translateY(0); }
}
main, .dash, .pg, .rich-page {
  animation: bs-page-in 0.32s var(--ease-out, cubic-bezier(0.2, 0, 0, 1));
}
@keyframes bs-shimmer {
  0%   { background-position: -200% 0; }
  100% { background-position: 200% 0; }
}
.skeleton {
  background-color: var(--cream-2);
  background-image: linear-gradient(90deg, transparent, oklch(96% 0.012 80 / 0.55), transparent);
  background-size: 200% 100%;
  animation: bs-shimmer 1.6s linear infinite;
  border-radius: 6px;
  color: transparent !important;
  pointer-events: none;
}
.skeleton-line { height: 0.9em; display: inline-block; vertical-align: middle; min-width: 4ch; }
.skeleton-block { height: 100px; width: 100%; border-radius: 12px; }
@media (prefers-reduced-motion: reduce) {
  [data-stagger] { opacity: 1 !important; transform: none !important; animation: none !important; }
  .site-card.spotlight::after,
  .rec-hero.spotlight::after,
  .connect-card.spotlight::after { display: none; }
  main, .dash, .pg, .rich-page { animation: none; }
  .skeleton { animation: none; background: var(--cream-2); }
}

/* Paper-texture overlay on body — handled by dashboard-v2.css per theme.
   This rule is left intentionally empty so the inline style block does
   not override the theme-aware noise filter. */

/* Frosted decorative divider utility */
.frosted-rule {
  border: 0;
  height: 1px;
  background: linear-gradient(90deg, transparent, var(--hairline-2) 18%, var(--hairline-2) 82%, transparent);
  margin: var(--space-6) 0;
}

/* Pulse-dot animation utility (live status) */
@keyframes bs-pulse-dot {
  0%, 100% { transform: scale(1); opacity: 1; }
  50%      { transform: scale(1.4); opacity: 0.55; }
}
.pulse-dot {
  display: inline-block;
  width: 6px; height: 6px;
  border-radius: 50%;
  background: currentColor;
  animation: bs-pulse-dot 2.4s ease-in-out infinite;
}
@media (prefers-reduced-motion: reduce) {
  .pulse-dot { animation: none; }
}

/* Numbered section markers — removed in chrome-less restraint pass */
.section-marker { display: none; }

/* Editorial typography moments — Newsreader serif italic 500 only */
.serif-moment {
  font-family: 'Newsreader', Georgia, serif;
  font-style: italic;
  font-weight: 500;
  font-feature-settings: "liga", "dlig", "kern";
  letter-spacing: -0.005em;
}
.pull-quote {
  position: relative;
  padding: var(--space-3) var(--space-3) var(--space-3) var(--space-5);
  border-left: 2px solid var(--hairline-3);
  background: transparent;
  border-radius: 0 8px 8px 0;
  margin: var(--space-2) 0;
}
.pull-quote-text {
  font-family: 'Newsreader', Georgia, serif;
  font-style: italic;
  font-weight: 500;
  font-size: 1rem;
  color: var(--ink);
  line-height: 1.5;
}
.pull-quote-attribution {
  display: block;
  margin-top: var(--space-2);
  font-family: 'JetBrains Mono', monospace;
  font-size: 0.62rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-faint);
  font-style: normal;
  font-weight: 500;
}

/* Lead capture top-level page — split: Configure left, live preview right. */
main.dash:has(.lc-page),
.pg:has(.lc-page),
.rich-page:has(.lc-page) {
  max-width: 1500px;
}
.lc-page { padding-bottom: 64px; }
.lc-split {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 420px;
  gap: 32px;
  align-items: start;
}
@media (max-width: 1180px) {
  .lc-split { grid-template-columns: 1fr; }
}
.lc-config { min-width: 0; }
.lc-config .set-block { margin-top: 0; }
.lc-config .set-block .set-section + .set-section {
  border-top: 1px solid var(--ink-line);
  padding-top: 22px;
  margin-top: 18px;
}

/* Booking window grid — three card-like checkboxes for Morning/Afternoon/Evening */
.lc-window-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 8px;
  width: 100%;
  max-width: 360px;
}
@media (max-width: 540px) {
  .lc-window-grid { grid-template-columns: 1fr; }
}
.lc-window {
  display: flex; align-items: flex-start; gap: 8px;
  padding: 10px 12px;
  border: 1px solid var(--ink-line);
  border-radius: 8px;
  background: var(--cream-1, transparent);
  cursor: pointer;
  transition: border-color 0.15s, background 0.15s;
}
.lc-window:hover { border-color: var(--ink-mute); }
.lc-window:has(input:checked) {
  border-color: var(--ink);
  background: var(--cream-2);
}
.lc-window input { margin-top: 2px; }
.lc-window-text { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.lc-window-name { font-size: 0.86rem; font-weight: 500; color: var(--ink); }
.lc-window-hours {
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-size: 0.72rem;
  color: var(--ink-mute);
}

.lc-preview { min-width: 0; }
.lc-preview-sticky {
  position: sticky;
  top: 24px;
  border: 1px solid var(--ink-line);
  border-radius: 14px;
  background: var(--cream-2, #FBFBFB);
  padding: 14px;
  display: flex; flex-direction: column; gap: 10px;
}
.lc-preview-tabs {
  display: inline-flex;
  gap: 4px;
  padding: 3px;
  background: var(--cream-3, rgba(0,0,0,0.05));
  border-radius: 999px;
  align-self: flex-start;
}
.lc-preview-tab {
  border: 0;
  background: transparent;
  padding: 6px 14px;
  font: inherit;
  font-size: 0.84rem;
  border-radius: 999px;
  color: var(--ink-mute);
  cursor: pointer;
  transition: background 0.16s, color 0.16s;
}
.lc-preview-tab.is-on {
  background: var(--ink, #1F1611);
  color: var(--cream-1, #FBFBFB);
}
.lc-preview-frame {
  width: 100%;
  height: 640px;
  border-radius: 10px;
  overflow: hidden;
  background: var(--cream-1, #FFFFFF);
  border: 1px solid var(--ink-line);
}
.lc-preview-frame iframe {
  width: 100%; height: 100%;
  border: 0; display: block;
}
.lc-preview-hint {
  font-size: 0.78rem;
  color: var(--ink-mute);
  text-align: center;
}
@media (max-width: 1180px) {
  .lc-preview-sticky { position: static; }
  .lc-preview-frame { height: 560px; }
}

/* Shared rich-page header */
.rich-head {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 14px;
  align-items: end;
  margin-bottom: 4px;
}
.rich-head-text { min-width: 0; }
.rich-eye {
  /* deprecated mono caps eyebrow — hidden in chrome-less restraint pass */
  display: none !important;
}
.rich-title {
  font-family: 'Geist', 'Inter Tight', 'Inter', sans-serif;
  font-size: 1.6rem;
  font-weight: 500;
  margin: 0 0 6px;
  letter-spacing: -0.02em;
  line-height: 1.1;
  color: var(--ink);
}
.rich-subtitle {
  font-family: 'Geist', 'Inter Tight', 'Inter', sans-serif;
  font-size: 13px;
  letter-spacing: normal;
  text-transform: none;
  color: var(--ink-mute);
  display: flex; align-items: center; gap: 10px;
  flex-wrap: wrap;
}
.rich-subtitle .dot {
  display: inline-block; width: 3px; height: 3px;
  border-radius: 50%; background: var(--ink-faint);
}
.rich-actions { display: flex; gap: 8px; align-items: center; }

/* Toggle group: Today / Week / Month */
.toggle-group {
  display: inline-flex;
  background: var(--cream-2);
  border: 1px solid var(--hairline);
  border-radius: 8px;
  padding: 3px;
  gap: 2px;
}
.toggle-group button {
  background: transparent;
  border: 0;
  padding: 6px 12px;
  font-family: inherit;
  font-size: 0.78rem;
  font-weight: 500;
  color: var(--ink-mute);
  border-radius: 6px;
  cursor: pointer;
  transition: background 0.18s cubic-bezier(0.2, 0, 0, 1), color 0.18s cubic-bezier(0.2, 0, 0, 1);
}
.toggle-group button:hover { color: var(--ink); }
.toggle-group button.is-on {
  background: var(--ink);
  color: var(--cream);
  border-radius: 6px;
}

/* Filter chips: All / Sent / Paid / Overdue / Draft */
.chip-row {
  display: flex; gap: 6px; flex-wrap: wrap;
  margin: 4px 0 14px;
}
.chip {
  background: transparent;
  border: 1px solid var(--hairline-2);
  padding: 6px 12px;
  border-radius: 6px;
  font-family: inherit;
  font-size: 0.78rem;
  font-weight: 500;
  color: var(--ink-mute);
  cursor: pointer;
  transition: background 0.12s, border-color 0.12s, color 0.12s;
}
.chip:hover { border-color: var(--hairline-3); color: var(--ink); }
.chip.is-on {
  background: var(--ink);
  border-color: var(--ink);
  color: var(--cream);
}
.chip-count {
  font-family: 'JetBrains Mono', monospace;
  font-size: 0.6rem;
  margin-left: 6px;
  color: var(--ink-faint);
  font-weight: 600;
}
.chip.is-on .chip-count { color: rgba(255,255,255,0.6); }

/* ============================================================================
   Calendar — week grid
   ========================================================================== */
.cal-card {
  background: var(--paper);
  border: 1px solid var(--hairline);
  border-radius: var(--card-radius);
  overflow: hidden;
  transition: border-color 0.18s cubic-bezier(0.2, 0, 0, 1);
}
.cal-card:hover { border-color: var(--hairline-2); }
.cal-week-head {
  display: grid;
  grid-template-columns: 56px repeat(7, 1fr);
  border-bottom: 1px solid var(--hairline);
  background: var(--cream);
}
.cal-week-head-cell {
  padding: 12px 10px;
  border-left: 1px solid var(--hairline);
  text-align: left;
}
.cal-week-head-cell:first-child { border-left: 0; }
.cal-week-head-cell .cal-dow {
  font-family: 'JetBrains Mono', monospace;
  font-size: 0.56rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--ink-faint);
  font-weight: 600;
}
.cal-week-head-cell .cal-dom {
  font-family: 'Geist', 'Inter Tight', 'Inter', sans-serif;
  font-size: 1.05rem;
  font-weight: 600;
  color: var(--ink);
  margin-top: 2px;
  letter-spacing: -0.01em;
}
.cal-week-head-cell.is-today .cal-dow { color: var(--ink); }
.cal-week-head-cell.is-today .cal-dom { color: var(--ink); }
.cal-week-head-cell.is-today {
  background: var(--cream-2);
}

.cal-grid {
  display: grid;
  grid-template-columns: 56px repeat(7, 1fr);
  position: relative;
}
.cal-time-col {
  border-right: 1px solid var(--hairline);
}
.cal-time-cell {
  height: 56px;
  font-family: 'JetBrains Mono', monospace;
  font-size: 0.56rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ink-faint);
  padding: 4px 8px 0;
  text-align: right;
}
.cal-day-col {
  border-left: 1px solid var(--hairline);
  position: relative;
  background-image: linear-gradient(to bottom, transparent calc(56px - 1px), var(--hairline) calc(56px - 1px), var(--hairline) 56px);
  background-size: 100% 56px;
  min-height: 616px; /* 11 hours × 56px */
}
.cal-day-col:first-of-type { border-left: 0; }
.cal-day-col.is-today { background-color: var(--cream-2); }

.cal-event {
  position: absolute;
  left: 4px; right: 4px;
  border-radius: var(--card-radius-data);
  padding: 6px 8px;
  font-size: 0.74rem;
  line-height: 1.3;
  cursor: pointer;
  border: 1px solid transparent;
  overflow: hidden;
  transition: border-color 0.12s, background 0.12s;
}
.cal-event:hover { border-color: var(--hairline-3); }
.cal-event-time {
  font-family: 'JetBrains Mono', monospace;
  font-size: 0.58rem;
  letter-spacing: 0.08em;
  font-weight: 600;
  margin-bottom: 2px;
}
.cal-event-name { font-weight: 600; line-height: 1.25; }
.cal-event-meta {
  font-size: 0.68rem;
  margin-top: 1px;
  opacity: 0.72;
  line-height: 1.25;
}
/* Job blocks are coloured by TYPE (3D-gradients) now, not by past/today
   state (founder 2026-06-05). Past events just fade back a little so the
   type colour still reads. */
.cal-event.is-past { opacity: 0.5; }

/* Calendar P1. Live grid event modifiers, working-hours bands, header nav.
   These rules sit alongside the legacy .cal-event styles above and only
   apply to elements that opt-in via the .cal-event--* modifier. */
.cal-event-title {
  font-weight: 600;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.cal-event--booking {
  background: linear-gradient(180deg, #3dbe75, #1f9d57);
  color: #fff;
  border: 1px solid #1f9d57;
  box-shadow: 0 2px 6px -1px rgba(31, 157, 87, 0.32), inset 0 1px 0 rgba(255, 255, 255, 0.22);
}
.cal-event--booking:hover {
  box-shadow: 0 5px 14px rgba(31, 157, 87, 0.34), inset 0 1px 0 rgba(255, 255, 255, 0.22);
  z-index: 3;
}
.cal-event--gcal {
  background: linear-gradient(180deg, #5b9bf5, #4285F4);
  color: #fff;
  border: 1px solid #3b78e0;
  box-shadow: 0 2px 6px -1px rgba(66, 133, 244, 0.32), inset 0 1px 0 rgba(255, 255, 255, 0.22);
}
.cal-event--gcal:hover {
  box-shadow: 0 5px 14px rgba(66, 133, 244, 0.34), inset 0 1px 0 rgba(255, 255, 255, 0.22);
  z-index: 3;
}
.cal-event--block {
  background: repeating-linear-gradient(
    45deg,
    var(--cream-2) 0,
    var(--cream-2) 7px,
    #e6e0d6 7px,
    #e6e0d6 14px
  );
  color: var(--ink-mute);
  border: 1px solid var(--hairline-2);
  box-shadow: none;
}
.cal-event--sm8 {
  background: linear-gradient(180deg, #3fb6d8, #1b7cb0);
  color: #fff;
  border: 1px solid #1b7cb0;
  box-shadow: 0 2px 6px -1px rgba(27, 124, 176, 0.32), inset 0 1px 0 rgba(255, 255, 255, 0.22);
}
.cal-event--sm8:hover {
  box-shadow: 0 5px 14px rgba(27, 124, 176, 0.34), inset 0 1px 0 rgba(255, 255, 255, 0.22);
  z-index: 3;
}

/* === Calendar month grid (P6) =========================================
   Day cells (not hour columns). 7 weekday-header cells + 42 day cells
   (6 weeks). Each cell shows day number, up to 3 event pills, and a
   "+N more" link if there's overflow. Click pill -> openEventModal,
   click day-num or "+N more" -> drop into today view, click empty cell
   area -> openNewJobModal pre-filled at 9am that day. */
.cal-month-card {
  border-radius: 14px;
  overflow: hidden;
  background: var(--paper);
  border: 1px solid var(--hairline-2);
}
.cal-month-head {
  display: grid;
  grid-template-columns: repeat(7, minmax(0, 1fr));
  background: var(--cream);
  border-bottom: 1px solid var(--hairline-2);
}
.cal-month-head-cell {
  padding: 10px 12px;
  font-size: 0.7rem;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--ink-mute);
  font-weight: 600;
  text-align: left;
}
.cal-month-grid {
  display: grid;
  grid-template-columns: repeat(7, minmax(0, 1fr));
  grid-auto-rows: minmax(110px, 1fr);
}
.cal-month-cell {
  position: relative;
  padding: 8px;
  border-right: 1px solid var(--hairline-2);
  border-bottom: 1px solid var(--hairline-2);
  background: var(--paper);
  display: flex;
  flex-direction: column;
  gap: 4px;
  min-height: 0;
  cursor: pointer;
  transition: background-color 100ms ease;
}
.cal-month-cell:hover { background: var(--cream); }
.cal-month-cell.is-weekend { background: var(--cream); }
.cal-month-cell.is-weekend:hover { background: var(--cream-2); }
.cal-month-cell.is-other { background: rgba(31, 22, 17, 0.015); }
.cal-month-cell.is-other .cal-month-day-num { color: rgba(31, 22, 17, 0.32); }
.cal-month-cell.is-other:hover { background: rgba(31, 22, 17, 0.04); }
.cal-month-cell.is-today { background: rgba(27, 22, 16, 0.03); }
.cal-month-cell.is-today .cal-month-day-num {
  background: var(--ink, #1F1611);
  color: var(--cream, #FAFAFA);
}
.cal-month-grid > .cal-month-cell:nth-child(7n) { border-right: none; }
.cal-month-grid > .cal-month-cell:nth-last-child(-n+7) { border-bottom: none; }

.cal-month-day-num {
  align-self: flex-start;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 22px;
  height: 22px;
  padding: 0 6px;
  border-radius: 11px;
  border: none;
  background: transparent;
  font: inherit;
  font-size: 0.78rem;
  font-weight: 600;
  color: var(--ink);
  cursor: pointer;
  transition: background-color 100ms ease;
}
.cal-month-day-num:hover {
  background: var(--cream-2);
}
.cal-month-cell.is-today .cal-month-day-num:hover {
  background: var(--ink, #1F1611);
  filter: brightness(0.85);
}

.cal-month-pills {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-height: 0;
  overflow: hidden;
}
.cal-month-pill {
  display: flex;
  align-items: center;
  gap: 4px;
  padding: 2px 6px;
  border-radius: 4px;
  font-size: 0.72rem;
  line-height: 1.4;
  cursor: pointer;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  transition: filter 100ms ease;
}
.cal-month-pill:hover { filter: brightness(0.95); }
.cal-month-pill-time {
  font-weight: 600;
  font-size: 0.68rem;
  opacity: 0.85;
  flex-shrink: 0;
}
.cal-month-pill-title {
  flex: 1;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.cal-month-pill.cal-event--booking {
  background: var(--ink, #1F1611);
  color: var(--cream, #FAFAFA);
}
.cal-month-pill.cal-event--gcal {
  background: transparent;
  color: var(--ink);
  border: 1px solid var(--hairline-2);
  border-left: 3px solid var(--ink-soft);
  padding-left: 5px;
}
.cal-month-pill.cal-event--block {
  background: repeating-linear-gradient(45deg, var(--cream-2) 0, var(--cream-2) 4px, var(--cream) 4px, var(--cream) 8px);
  color: var(--ink-mute);
  border: 1px dashed var(--hairline-2);
}
.cal-month-pill.cal-event--sm8 {
  background: transparent;
  color: var(--ink);
  border: 1px solid var(--hairline-2);
  border-left: 3px dotted var(--ink-soft);
  padding-left: 5px;
}

.cal-month-overflow {
  align-self: flex-start;
  border: none;
  background: transparent;
  font: inherit;
  font-size: 0.7rem;
  color: var(--ink-mute);
  cursor: pointer;
  padding: 2px 4px;
  border-radius: 3px;
  margin-top: 2px;
}
.cal-month-overflow:hover {
  color: var(--ink);
  background: var(--cream-2);
}

.cal-month-loading {
  min-height: 480px;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
}

/* Mobile: collapse min-row-height a touch so 6 rows fit on tablet. */
@media (max-width: 720px) {
  .cal-month-grid { grid-auto-rows: minmax(80px, 1fr); }
  .cal-month-cell { padding: 6px 4px; }
  .cal-month-pill-title { display: none; }
  .cal-month-pill { padding: 2px 4px; }
}

/* === Calendar event detail modal (P2) ============================== */
.cem-backdrop { position: fixed; inset: 0; background: rgba(31, 22, 17, 0.45); backdrop-filter: blur(2px); -webkit-backdrop-filter: blur(2px); z-index: 9990; opacity: 0; transition: opacity 0.15s ease-out; }
.cem-backdrop.is-in { opacity: 1; }
.cem-card { position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%) scale(0.98); background: var(--paper); color: var(--ink); border: 1px solid var(--hairline-2); border-radius: 12px; box-shadow: 0 18px 50px rgba(31, 22, 17, 0.28); width: calc(100% - 32px); max-width: 480px; max-height: calc(100vh - 64px); display: flex; flex-direction: column; z-index: 9991; opacity: 0; transition: opacity 0.18s ease-out, transform 0.18s ease-out; font-family: inherit; }
.cem-card.is-in { opacity: 1; transform: translate(-50%, -50%) scale(1); }
.cem-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; padding: 22px 28px 12px; }
.cem-head-text { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.cem-title { font-family: 'Geist', 'Inter Tight', 'Inter', sans-serif; font-size: 1.06rem; font-weight: 600; letter-spacing: -0.01em; color: var(--ink); margin: 0; word-break: break-word; }
.cem-pill { display: inline-flex; align-items: center; align-self: flex-start; padding: 2px 8px; font-size: 0.72rem; font-weight: 500; border-radius: 999px; border: 1px solid var(--hairline-2); color: var(--ink-mute); background: var(--cream-2); letter-spacing: 0.01em; }
.cem-pill.is-pending  { color: #8a5a00; border-color: rgba(200, 138, 0, 0.30); background: rgba(255, 200, 80, 0.14); }
.cem-pill.is-confirmed { color: var(--orange-deep); border-color: var(--orange-wash); background: var(--orange-wash); }
.cem-pill.is-cancelled { color: var(--ink-faint); text-decoration: line-through; }
.cem-pill.is-done      { color: var(--ink-mute); }
.cem-pill.is-gcal      { color: var(--orange-deep); border-color: var(--orange-wash); background: var(--orange-wash); }
.cem-close { width: 30px; height: 30px; border-radius: 6px; border: 1px solid transparent; background: transparent; color: var(--ink-mute); cursor: pointer; display: inline-flex; align-items: center; justify-content: center; font-size: 1.1rem; flex-shrink: 0; transition: background 0.18s, color 0.18s, border-color 0.18s; }
.cem-close:hover { background: var(--cream-2); color: var(--ink); border-color: var(--hairline-2); }
.cem-body { padding: 8px 28px 16px; overflow-y: auto; flex: 1 1 auto; }
.cem-row { display: grid; grid-template-columns: 92px 1fr; gap: 12px; padding: 8px 0; font-size: 0.86rem; line-height: 1.55; border-top: 1px solid var(--hairline-2); }
.cem-row:first-child { border-top: 0; }
.cem-row-label { color: var(--ink-mute); font-size: 0.78rem; text-transform: uppercase; letter-spacing: 0.04em; padding-top: 2px; }
.cem-row-value { color: var(--ink); word-break: break-word; }
.cem-row-value a { color: var(--orange-deep); text-decoration: none; border-bottom: 1px solid transparent; transition: border-color 0.18s; }
.cem-row-value a:hover { border-bottom-color: var(--orange-deep); }
.cem-row-value .cem-multiline { white-space: pre-wrap; }
.cem-map-link { font-size: 0.78rem; color: var(--ink-mute); margin-left: 6px; }
.cem-source-line { font-size: 0.78rem; color: var(--ink-mute); padding: 10px 0 4px; border-top: 1px solid var(--hairline-2); margin-top: 6px; }
.cem-s8-badge { display: inline-flex; align-items: center; font-size: 0.74rem; color: var(--orange-deep); background: var(--orange-wash); border: 1px solid var(--orange-wash); padding: 2px 8px; border-radius: 999px; margin-top: 6px; }
.cem-foot { display: flex; align-items: center; justify-content: flex-end; gap: 8px; padding: 14px 28px 22px; border-top: 1px solid var(--hairline-2); flex-wrap: wrap; }
.cem-btn { display: inline-flex; align-items: center; justify-content: center; gap: 6px; padding: 8px 14px; font-family: inherit; font-size: 0.84rem; font-weight: 500; border-radius: 8px; border: 1px solid var(--hairline-2); background: var(--paper); color: var(--ink); cursor: pointer; transition: background 0.18s, border-color 0.18s, color 0.18s; text-decoration: none; }
.cem-btn:hover { border-color: var(--hairline-3); background: var(--cream-2); }
.cem-btn[disabled] { opacity: 0.5; cursor: not-allowed; }
.cem-btn.is-primary { background: var(--orange); border-color: var(--orange); color: #fff; }
.cem-btn.is-primary:hover { background: var(--orange-deep); border-color: var(--orange-deep); }
.cem-btn.is-danger { color: #a83a14; }
.cem-btn.is-danger:hover { background: rgba(168, 58, 20, 0.06); border-color: rgba(168, 58, 20, 0.30); }
.cem-loading, .cem-error { padding: 32px 4px; text-align: center; color: var(--ink-mute); font-size: 0.88rem; }
.cem-error a { color: var(--orange-deep); cursor: pointer; border-bottom: 1px solid transparent; }
.cem-error a:hover { border-bottom-color: var(--orange-deep); }
.cem-spinner { display: inline-block; width: 18px; height: 18px; border: 2px solid var(--hairline-2); border-top-color: var(--orange-deep); border-radius: 50%; animation: cem-spin 0.7s linear infinite; margin-bottom: 10px; }
@keyframes cem-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) { .cem-backdrop, .cem-card { transition: none; } .cem-spinner { animation: none; } }

/* Inline page-loading spinner — the same ring as the global #bs-load-overlay
   .bs-load-spin (founder 2026-06-20: use the exact page loading spinner):
   28px, 2.5px ring, dark ink top, 0.8s rotation. Shown immediately (no
   delayed fade-in — the placeholder only renders once we're already loading),
   centred by the text-align:center on its placeholder. */
.bs-page-spinner {
  display: inline-block; box-sizing: border-box; width: 28px; height: 28px;
  border-radius: 50%;
  border: 2.5px solid rgba(31, 22, 17, 0.12); border-top-color: #1F1611;
  animation: bs-page-spin-rot 0.8s linear infinite;
}
@keyframes bs-page-spin-rot { to { transform: rotate(360deg); } }
[data-theme="dark"] .bs-page-spinner { border-color: rgba(255, 255, 255, 0.15); border-top-color: #F7F7F7; }
@media (prefers-reduced-motion: reduce) { .bs-page-spinner { animation: none; } }
/* The spinner is centred in the middle of the page by its placeholder, which
   is a tall flex container (.leads-loading / .lp-loading: min-height ~viewport,
   align/justify center). In-flow centring — no fixed/absolute positioning,
   which gets trapped + clipped by main.dash's transform containing block
   (founder 2026-06-20). */

/* === Calendar working-hours + blocks slide-outs + integrations ===== */
.cal-actions-section { display: flex; flex-direction: column; gap: 14px; margin-top: 28px; }
.cal-actions-eyebrow { font-family: 'JetBrains Mono', 'IBM Plex Mono', monospace; font-size: 0.7rem; letter-spacing: 0.16em; text-transform: uppercase; color: var(--ink-faint); margin: 0; font-weight: 500; }
.cal-actions-row { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; }
@media (max-width: 720px) { .cal-actions-row { grid-template-columns: 1fr; } }
.cal-action-btn { display: flex; flex-direction: row; align-items: center; gap: 13px; padding: 15px 16px; border: 1px solid var(--card-bd, rgba(31,22,17,0.08)); border-radius: 14px; background: #fff; color: var(--ink); text-align: left; text-decoration: none; font-family: inherit; cursor: pointer; box-shadow: 0 1px 2px rgba(31,22,17,0.04), inset 0 1px 0 rgba(255,255,255,0.7); transition: border-color 0.18s cubic-bezier(0.2, 0, 0, 1), transform 0.18s cubic-bezier(0.2, 0, 0, 1), box-shadow 0.18s cubic-bezier(0.2, 0, 0, 1); width: 100%; min-width: 0; }
.cal-action-btn:hover { transform: translateY(-1px); box-shadow: 0 6px 18px rgba(31, 22, 17, 0.08), inset 0 1px 0 rgba(255,255,255,0.7); }
.cal-action-btn:focus-visible { outline: 2px solid var(--orange-deep); outline-offset: 2px; }
.cal-action-btn.is-connected { cursor: default; }
.cal-action-btn.is-connected:hover { transform: none; box-shadow: none; border-color: var(--hairline-2); }
.cal-action-btn-body { display: flex; flex-direction: column; gap: 4px; min-width: 0; flex: 1; }
.cal-action-btn-title { font-family: 'Geist', 'Inter Tight', 'Inter', sans-serif; font-size: 0.96rem; font-weight: 600; letter-spacing: -0.01em; color: var(--ink); }
.cal-action-btn-sub { font-size: 0.82rem; color: var(--ink-mute); line-height: 1.4; }
.cal-action-btn--link { color: var(--ink); }
.cal-action-btn-brand { display: inline-flex; align-items: center; justify-content: center; width: 44px; height: 44px; border-radius: 12px; background: linear-gradient(180deg, #ffffff, #f1efe9); border: 1px solid var(--card-bd, rgba(31,22,17,0.08)); box-shadow: inset 0 1px 0 rgba(255,255,255,0.8); flex-shrink: 0; overflow: hidden; color: var(--ink); align-self: flex-start; }
.cal-action-btn-brand img { display: block; width: 27px; height: 27px; border-radius: 6px; }
.cal-action-btn-brand svg { display: block; }
.cal-action-btn-status { display: flex; align-items: center; gap: 6px; font-size: 0.82rem; color: var(--ink); margin-top: 2px; min-width: 0; }
.cal-action-btn-status-email { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; flex: 1; }
.cal-status-dot { width: 7px; height: 7px; border-radius: 50%; background: #2E7D32; display: inline-block; flex-shrink: 0; box-shadow: 0 0 0 2px rgba(46, 125, 50, 0.12); }
.cal-action-btn-meta { font-size: 0.78rem; color: var(--ink-mute); line-height: 1.4; font-variant-numeric: tabular-nums; }
.cal-action-btn-controls { display: inline-flex; align-items: center; gap: 6px; margin-top: 4px; font-size: 0.82rem; }
.cal-action-btn-controls-sep { color: var(--ink-faint); }
.cal-link-btn { background: transparent; border: 0; padding: 0; cursor: pointer; font: inherit; font-size: 0.82rem; color: var(--ink); text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 3px; transition: opacity 0.12s; }
.cal-link-btn:hover { opacity: 0.7; }
.cal-link-btn:disabled { opacity: 0.5; cursor: not-allowed; }
.cal-action-btn-queued { color: var(--ink-mute); font-variant-numeric: tabular-nums; }
.cal-action-btn-warn { display: block; margin-top: 8px; padding: 7px 10px; background: rgba(217, 84, 30, 0.08); border-left: 2px solid var(--orange-deep, #B5532E); border-radius: 4px; font-size: 0.78rem; color: var(--ink); line-height: 1.4; }
.cal-action-btn-reconnect { display: inline-flex; align-items: center; gap: 6px; margin-top: 8px; padding: 7px 14px; background: var(--orange-deep, #B5532E); color: #fff; font-family: 'Geist', 'Inter Tight', 'Inter', sans-serif; font-size: 0.82rem; font-weight: 600; text-decoration: none; border-radius: 8px; transition: background 0.18s, transform 0.18s; align-self: flex-start; }
.cal-action-btn-reconnect:hover { background: var(--orange, #C95C28); transform: translateY(-1px); }
.cal-action-btn-reconnect:focus-visible { outline: 2px solid var(--ink); outline-offset: 2px; }
.cal-action-btn.is-needs-attention { border-color: var(--orange-deep, #B5532E); border-left-width: 3px; }
.cal-action-btn.is-needs-attention .cal-status-dot { background: var(--orange-deep, #B5532E); box-shadow: 0 0 0 2px rgba(181, 83, 46, 0.12); }

/* ── Calendar bottom, matched to the My Website / Forms design system
   (founder 2026-06-05). Uses the global .set-section / .set-row primitives;
   these add the summary, agenda, nav-rows and status-wash connect cards. ── */
.cal-sum { display: grid; grid-template-columns: repeat(4, 1fr); }
.cal-sum-c { text-align: center; padding: 2px 6px 4px; border-right: 1px solid var(--hairline); }
.cal-sum-c:last-child { border-right: 0; }
.cal-sum-n { font-family: 'Geist', 'Inter Tight', sans-serif; font-size: 1.35rem; font-weight: 650; letter-spacing: -0.03em; line-height: 1; font-variant-numeric: tabular-nums; color: var(--ink); }
.cal-sum-n--blue { color: #2563eb; }
.cal-sum-l { font-size: 0.62rem; font-weight: 600; text-transform: uppercase; letter-spacing: 0.04em; color: var(--ink-faint); margin-top: 5px; }

.cal-up { display: flex; align-items: center; gap: 12px; padding: 13px 0; border-bottom: 1px solid var(--hairline); text-decoration: none; color: inherit; cursor: pointer; -webkit-tap-highlight-color: transparent; }
.cal-up:last-child { border-bottom: 0; }
.cal-up:active { background: rgba(31, 22, 17, 0.02); }
.cal-up-when { flex: 0 0 50px; display: flex; flex-direction: column; line-height: 1.2; }
.cal-up-when .d { font-size: 0.6rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.04em; color: var(--ink-faint); }
.cal-up-when .t { font-size: 0.82rem; font-weight: 600; font-variant-numeric: tabular-nums; color: var(--ink); }
.cal-up-dot { width: 9px; height: 9px; border-radius: 50%; flex-shrink: 0; }
.cal-up-dot.is-booking { background: linear-gradient(180deg, #3dbe75, #1f9d57); box-shadow: 0 0 0 3px rgba(31, 157, 87, 0.14); }
.cal-up-dot.is-gcal { background: linear-gradient(180deg, #5b9bf5, #4285F4); box-shadow: 0 0 0 3px rgba(66, 133, 244, 0.14); }
.cal-up-dot.is-sm8 { background: linear-gradient(180deg, #3fb6d8, #1b7cb0); }
.cal-up-dot.is-block { background: var(--ink-faint); }
.cal-up-bd { flex: 1; min-width: 0; }
.cal-up-nm { display: block; font-size: 0.9rem; font-weight: 600; color: var(--ink); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.cal-up-sb { display: block; font-size: 0.77rem; color: var(--ink-mute); margin-top: 1px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

/* Schedule nav rows — a .set-row rendered as a tappable button/link. */
.cal-navrow { width: 100%; text-align: left; background: transparent; cursor: pointer; -webkit-tap-highlight-color: transparent; border-top: 0; border-left: 0; border-right: 0; font: inherit; color: inherit; text-decoration: none; }
.cal-navrow:visited { color: inherit; }
.cal-navrow:active { background: rgba(31, 22, 17, 0.02); }
.cal-navrow .set-row-control { display: flex; align-items: center; justify-content: flex-end; gap: 2px; }
.cal-navval { color: var(--ink-mute); font-size: 0.84rem; font-weight: 500; white-space: nowrap; font-variant-numeric: tabular-nums; }
.cal-navchev { color: var(--ink-faint); flex-shrink: 0; margin-left: 4px; }

/* Connect cards — logo + status wash, mirrors the Forms fhub-status-card. */
.cal-conn-card { display: flex; align-items: center; gap: 12px; margin: 0 0 11px; padding: 14px 15px; border-radius: 14px; background: var(--paper); border: 1px solid var(--hairline); box-shadow: 0 1px 2px rgba(31, 22, 17, 0.04); text-decoration: none; color: var(--ink); }
.cal-conn-card[hidden] { display: none; }
.cal-conn-logo { width: 42px; height: 42px; border-radius: 11px; flex-shrink: 0; display: flex; align-items: center; justify-content: center; background: linear-gradient(180deg, #fff, #f1efe9); border: 1px solid var(--card-bd, rgba(31, 22, 17, 0.08)); box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.8); overflow: hidden; }
.cal-conn-logo img { border-radius: 6px; display: block; }
.cal-conn-bd { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.cal-conn-nm { font-size: 0.95rem; font-weight: 650; letter-spacing: -0.01em; }
.cal-conn-sub { font-size: 0.8rem; color: var(--ink-mute); line-height: 1.4; }
.cal-conn-cta { flex-shrink: 0; height: 34px; display: inline-flex; align-items: center; padding: 0 15px; border-radius: 9px; font-size: 0.82rem; font-weight: 600; color: #fff; background: linear-gradient(180deg, #5aa2ff, #2563eb); box-shadow: 0 1px 2px rgba(37, 99, 235, 0.35), inset 0 1px 0 rgba(255, 255, 255, 0.3); }
/* connected (live) variant — column layout + green wash */
.cal-conn-card--live { display: block; background: color-mix(in srgb, #2e9e5b 7%, var(--paper, #fff)); border-color: color-mix(in srgb, #2e9e5b 28%, transparent); }
.cal-conn-card--live.is-warn { background: color-mix(in srgb, #d99a2e 9%, var(--paper, #fff)); border-color: color-mix(in srgb, #d99a2e 32%, transparent); }
.cal-conn-head { display: flex; align-items: center; gap: 9px; }
.cal-conn-head .cal-conn-logo { width: 34px; height: 34px; border-radius: 9px; }
.cal-conn-head .cal-conn-nm { flex: 1; min-width: 0; }
.cal-conn-dot { width: 8px; height: 8px; border-radius: 50%; flex-shrink: 0; background: #2e9e5b; box-shadow: 0 0 0 3px rgba(46, 158, 91, 0.18); }
.cal-conn-card--live.is-warn .cal-conn-dot { background: #d99a2e; box-shadow: 0 0 0 3px rgba(217, 154, 46, 0.2); }
.cal-conn-state { font-size: 0.82rem; color: var(--ink-mute); flex-shrink: 0; }
.cal-conn-btn { flex-shrink: 0; }
.cal-conn-purpose { margin: 9px 0 0; font-size: 0.8rem; line-height: 1.5; color: var(--ink-mute); }
.cal-conn-purpose strong { color: var(--ink); font-weight: 600; }
.cal-conn-warn { margin-top: 9px; padding: 9px 11px; border-radius: 9px; background: rgba(217, 154, 46, 0.12); font-size: 0.78rem; line-height: 1.45; color: #7a5310; }
.cal-conn-warn[hidden] { display: none; }
.cal-conn-links { margin-top: 10px; display: flex; gap: 14px; }
.cal-conn-reconnect { display: inline-flex; align-items: center; margin-top: 10px; height: 34px; padding: 0 14px; border-radius: 9px; font-size: 0.82rem; font-weight: 600; color: #fff; background: var(--ink, #241a12); text-decoration: none; }
.cal-conn-reconnect[hidden] { display: none; }

/* Slide-out backdrop + panel */
.cal-slideout-backdrop { position: fixed; inset: 0; background: rgba(31, 22, 17, 0.40); backdrop-filter: blur(2px); -webkit-backdrop-filter: blur(2px); z-index: 9990; opacity: 0; transition: opacity 0.20s ease-out; }
.cal-slideout-backdrop.is-in { opacity: 1; }
.cal-slideout { position: fixed; top: 0; right: 0; bottom: 0; width: 100%; max-width: 480px; background: var(--paper); color: var(--ink); border-left: 1px solid var(--hairline-2); box-shadow: -16px 0 40px rgba(31, 22, 17, 0.12); z-index: 9991; display: flex; flex-direction: column; transform: translateX(100%); transition: transform 0.22s ease-out; font-family: inherit; }
.cal-slideout.is-in { transform: translateX(0); }
.cal-slideout-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; padding: 20px 24px 14px; border-bottom: 1px solid var(--hairline-2); flex-shrink: 0; }
.cal-slideout-head-text { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.cal-slideout-title { font-family: 'Geist', 'Inter Tight', 'Inter', sans-serif; font-size: 1.06rem; font-weight: 600; letter-spacing: -0.01em; color: var(--ink); margin: 0; }
.cal-slideout-sub { font-size: 0.82rem; color: var(--ink-mute); line-height: 1.45; margin: 0; }
.cal-slideout-close { width: 30px; height: 30px; border-radius: 6px; border: 1px solid transparent; background: transparent; color: var(--ink-mute); cursor: pointer; display: inline-flex; align-items: center; justify-content: center; font-size: 1.1rem; flex-shrink: 0; transition: background 0.18s, color 0.18s, border-color 0.18s; }
.cal-slideout-close:hover { background: var(--cream-2); color: var(--ink); border-color: var(--hairline-2); }
.cal-slideout-body { padding: 16px 24px 24px; overflow-y: auto; flex: 1 1 auto; }
.cal-slideout-body p { font-size: 0.86rem; color: var(--ink-mute); line-height: 1.5; margin: 0 0 16px; }
.cal-slideout-foot { display: flex; align-items: center; justify-content: flex-end; gap: 8px; padding: 14px 24px; border-top: 1px solid var(--hairline-2); flex-shrink: 0; }
.cal-slideout-status { flex: 1 1 auto; font-size: 0.80rem; color: var(--ink-mute); }
.cal-slideout-status.is-error { color: #a83a14; }
.cal-slideout-btn { display: inline-flex; align-items: center; justify-content: center; gap: 6px; padding: 8px 14px; font-family: inherit; font-size: 0.84rem; font-weight: 500; border-radius: 8px; border: 1px solid var(--hairline-2); background: var(--paper); color: var(--ink); cursor: pointer; transition: background 0.18s, border-color 0.18s, color 0.18s; }
.cal-slideout-btn:hover { border-color: var(--hairline-3); background: var(--cream-2); }
.cal-slideout-btn[disabled] { opacity: 0.5; cursor: not-allowed; }
.cal-slideout-btn.is-primary { background: var(--orange); border-color: var(--orange); color: #fff; }
.cal-slideout-btn.is-primary:hover { background: var(--orange-deep); border-color: var(--orange-deep); color: #fff; }

/* Working-hours rows */
.cal-hrs-list { display: flex; flex-direction: column; gap: 10px; }
.cal-hrs-row { display: grid; grid-template-columns: 56px 1fr auto auto; align-items: center; gap: 10px; padding: 10px 12px; border: 1px solid var(--hairline-2); border-radius: 10px; background: var(--paper); }
.cal-hrs-row.is-closed { background: var(--cream-2); opacity: 0.85; }
.cal-hrs-day { font-size: 0.86rem; font-weight: 600; color: var(--ink); letter-spacing: -0.005em; }
.cal-hrs-toggle { display: inline-flex; align-items: center; gap: 6px; font-size: 0.78rem; color: var(--ink-mute); cursor: pointer; user-select: none; }
.cal-hrs-toggle input { margin: 0; }
.cal-hrs-time { height: 32px; padding: 0 8px; border: 1px solid var(--hairline-2); border-radius: 6px; background: var(--paper); color: var(--ink); font-family: inherit; font-size: 0.84rem; width: 95px; }
.cal-hrs-time:disabled { opacity: 0.5; cursor: not-allowed; }
.cal-hrs-dash { color: var(--ink-mute); font-size: 0.82rem; }

/* Block-time-off form + list */
.cal-blk-form { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; padding: 14px; border: 1px solid var(--hairline-2); border-radius: 10px; background: var(--cream-2); margin-bottom: 18px; }
.cal-blk-form-field { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.cal-blk-form-field.is-full { grid-column: 1 / -1; }
.cal-blk-form-field label { font-size: 0.74rem; color: var(--ink-mute); text-transform: uppercase; letter-spacing: 0.04em; font-weight: 500; }
.cal-blk-input { height: 34px; padding: 0 10px; border: 1px solid var(--hairline-2); border-radius: 6px; background: var(--paper); color: var(--ink); font-family: inherit; font-size: 0.86rem; }
.cal-blk-input:disabled { opacity: 0.5; cursor: not-allowed; }
.cal-blk-form-allday { display: inline-flex; align-items: center; gap: 6px; font-size: 0.84rem; color: var(--ink); cursor: pointer; user-select: none; padding: 4px 0; }
.cal-blk-form-allday input { margin: 0; }
.cal-blk-form-actions { grid-column: 1 / -1; display: flex; justify-content: flex-end; }
.cal-blk-list { display: flex; flex-direction: column; gap: 8px; }
.cal-blk-row { display: grid; grid-template-columns: 1fr auto; align-items: center; gap: 12px; padding: 12px 14px; border: 1px solid var(--hairline-2); border-radius: 10px; background: var(--paper); }
.cal-blk-row-text { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.cal-blk-row-date { font-size: 0.86rem; font-weight: 600; color: var(--ink); }
.cal-blk-row-meta { font-size: 0.78rem; color: var(--ink-mute); }
.cal-blk-row-del { width: 28px; height: 28px; border-radius: 6px; border: 1px solid transparent; background: transparent; color: var(--ink-mute); cursor: pointer; display: inline-flex; align-items: center; justify-content: center; font-size: 0.96rem; transition: background 0.18s, border-color 0.18s, color 0.18s; }
.cal-blk-row-del:hover { background: rgba(168, 58, 20, 0.06); border-color: rgba(168, 58, 20, 0.30); color: #a83a14; }
.cal-blk-empty { text-align: center; font-size: 0.84rem; color: var(--ink-mute); padding: 18px 8px; border: 1px dashed var(--hairline-2); border-radius: 10px; background: var(--paper); }

@media (max-width: 540px) { .cal-slideout { max-width: 100%; } .cal-blk-form { grid-template-columns: 1fr; } .cal-hrs-row { grid-template-columns: 56px 1fr; row-gap: 6px; } .cal-hrs-row > .cal-hrs-toggle { grid-column: 1 / -1; justify-content: flex-end; } }
@media (prefers-reduced-motion: reduce) { .cal-slideout-backdrop, .cal-slideout { transition: none; } }

/* === Calendar new-job modal (P3) =================================== */
.nj-backdrop { position: fixed; inset: 0; background: rgba(31, 22, 17, 0.45); backdrop-filter: blur(2px); -webkit-backdrop-filter: blur(2px); z-index: 9990; opacity: 0; transition: opacity 0.15s ease-out; }
.nj-backdrop.is-in { opacity: 1; }
.nj-card { position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%) scale(0.98); background: var(--paper); color: var(--ink); border: 1px solid var(--hairline-2); border-radius: 12px; box-shadow: 0 18px 50px rgba(31, 22, 17, 0.28); width: calc(100% - 32px); max-width: 480px; max-height: calc(100vh - 64px); display: flex; flex-direction: column; z-index: 9991; opacity: 0; transition: opacity 0.18s ease-out, transform 0.18s ease-out; font-family: inherit; }
.nj-card.is-in { opacity: 1; transform: translate(-50%, -50%) scale(1); }
.nj-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; padding: 22px 28px 12px; }
.nj-head-text { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.nj-title { font-family: 'Geist', 'Inter Tight', 'Inter', sans-serif; font-size: 1.06rem; font-weight: 600; letter-spacing: -0.01em; color: var(--ink); margin: 0; word-break: break-word; }
.nj-sub { font-size: 0.82rem; color: var(--ink-mute); line-height: 1.45; margin: 0; }
.nj-close { width: 30px; height: 30px; border-radius: 6px; border: 1px solid transparent; background: transparent; color: var(--ink-mute); cursor: pointer; display: inline-flex; align-items: center; justify-content: center; font-size: 1.1rem; flex-shrink: 0; transition: background 0.18s, color 0.18s, border-color 0.18s; }
.nj-close:hover { background: var(--cream-2); color: var(--ink); border-color: var(--hairline-2); }
.nj-body { padding: 8px 28px 16px; overflow-y: auto; flex: 1 1 auto; }
.nj-form { display: flex; flex-direction: column; gap: 12px; }
.nj-row { display: flex; flex-direction: column; gap: 4px; }
.nj-row.is-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.nj-row.is-grid .nj-row-cell { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.nj-label { font-size: 0.74rem; color: var(--ink-mute); text-transform: uppercase; letter-spacing: 0.04em; font-weight: 500; }
.nj-label .nj-req { color: var(--orange-deep); margin-left: 2px; }
.nj-input, .nj-select, .nj-textarea { height: 36px; padding: 0 10px; border: 1px solid var(--hairline-2); border-radius: 6px; background: var(--paper); color: var(--ink); font-family: inherit; font-size: 0.88rem; }
.nj-textarea { height: auto; padding: 8px 10px; resize: vertical; min-height: 64px; line-height: 1.45; }
.nj-input:focus, .nj-select:focus, .nj-textarea:focus { outline: 2px solid var(--orange-deep); outline-offset: 1px; border-color: var(--orange-deep); }
.nj-input[disabled], .nj-select[disabled], .nj-textarea[disabled] { opacity: 0.5; cursor: not-allowed; }
.nj-help { font-size: 0.74rem; color: var(--ink-faint); line-height: 1.4; }
.nj-fielderr { font-size: 0.74rem; color: #a83a14; line-height: 1.4; }
.nj-row.has-error .nj-input, .nj-row.has-error .nj-select, .nj-row.has-error .nj-textarea, .nj-row-cell.has-error .nj-input, .nj-row-cell.has-error .nj-select { border-color: #a83a14; }
.nj-checkbox-row { display: flex; align-items: flex-start; gap: 8px; padding: 10px 12px; border: 1px solid var(--hairline-2); border-radius: 8px; background: var(--cream-2); margin-top: 4px; cursor: pointer; user-select: none; }
.nj-checkbox-row input { margin-top: 3px; flex-shrink: 0; cursor: pointer; }
.nj-checkbox-row-text { display: flex; flex-direction: column; gap: 2px; }
.nj-checkbox-label { font-size: 0.86rem; color: var(--ink); font-weight: 500; }
.nj-checkbox-sub { font-size: 0.76rem; color: var(--ink-mute); line-height: 1.4; }
.nj-foot { display: flex; align-items: center; justify-content: flex-end; gap: 8px; padding: 14px 28px 22px; border-top: 1px solid var(--hairline-2); flex-wrap: wrap; }
.nj-foot-status { flex: 1 1 auto; min-width: 0; font-size: 0.80rem; color: var(--ink-mute); }
.nj-foot-status.is-error { color: #a83a14; }
.nj-btn { display: inline-flex; align-items: center; justify-content: center; gap: 6px; padding: 8px 14px; font-family: inherit; font-size: 0.84rem; font-weight: 500; border-radius: 8px; border: 1px solid var(--hairline-2); background: var(--paper); color: var(--ink); cursor: pointer; transition: background 0.18s, border-color 0.18s, color 0.18s; }
.nj-btn:hover { border-color: var(--hairline-3); background: var(--cream-2); }
.nj-btn[disabled] { opacity: 0.5; cursor: not-allowed; }
.nj-btn.is-primary { background: var(--orange); border-color: var(--orange); color: #fff; }
.nj-btn.is-primary:hover { background: var(--orange-deep); border-color: var(--orange-deep); color: #fff; }

/* Empty-cell click target inside a day column. Rendered first in the
   day column so events stack on top via document order (events have no
   explicit z-index either). Inside working-hours is subtly hoverable;
   outside-hours cells are not interactive. */
.cal-empty-cell { position: absolute; left: 0; right: 0; cursor: pointer; background: transparent; transition: background 0.12s; }
.cal-empty-cell.is-disabled { cursor: default; pointer-events: none; }
.cal-empty-cell:hover { background: rgba(200, 81, 30, 0.06); }

@media (max-width: 540px) { .nj-row.is-grid { grid-template-columns: 1fr; } }
@media (prefers-reduced-motion: reduce) { .nj-backdrop, .nj-card { transition: none; } }

.cal-hours-band {
  position: absolute;
  left: 0; right: 0;
  background: var(--cream-2);
  opacity: 0.55;
  pointer-events: none;
  z-index: 0;
}

/* Header navigation row (prev / today / next + range label) */
.cal-nav-row {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  margin-right: 4px;
}
.cal-nav-btn {
  width: 30px; height: 30px;
  border-radius: 6px;
  border: 1px solid var(--hairline-2);
  background: var(--paper);
  cursor: pointer;
  display: inline-flex; align-items: center; justify-content: center;
  color: var(--ink);
  font-family: inherit;
  font-size: 0.92rem;
  padding: 0;
  transition: border-color 0.18s cubic-bezier(0.2, 0, 0, 1);
}
.cal-nav-btn:hover { border-color: var(--hairline-3); color: var(--ink); }
.cal-today-btn {
  padding: 0 12px; height: 30px;
  border-radius: 6px;
  border: 1px solid var(--hairline-2);
  background: var(--paper);
  cursor: pointer;
  font-family: inherit;
  font-size: 0.82rem;
  color: var(--ink);
  transition: border-color 0.18s cubic-bezier(0.2, 0, 0, 1);
}
.cal-today-btn:hover { border-color: var(--hairline-3); }
.cal-range-label {
  font-family: 'Geist', 'Inter Tight', 'Inter', sans-serif;
  font-size: 0.86rem;
  color: var(--ink-mute);
  font-weight: 500;
  margin: 0 8px;
  letter-spacing: -0.005em;
}

/* ──────────────────────────────────────────────────────────────────
   Calendar — Style D (week density heat-strip + focused-day agenda)
   ────────────────────────────────────────────────────────────────── */

/* Keep the calendar header in title-left / pill-right at mobile too —
   the page only has one tiny "+ New job" button up top now. The
   Calendar's old mobile rule stacked .rich-actions vertically because
   it had to fit prev/today/next + segmented view toggle + CTA; with
   tabs + nav moved into their own .cal-controls row below, the
   header can keep its desktop layout on mobile. */
@media (max-width: 720px) {
  .rich-head--calendar { grid-template-columns: 1fr auto !important; align-items: start; gap: 12px; }
  .rich-head--calendar .rich-actions { flex-direction: row !important; align-items: flex-start !important; }
}

/* The calendar header is empty now (heading lives in the topbar, New job moved
   down to the controls row) — collapse it so it leaves no gap. The New job
   pill sits hard-right of the tabs on the .cal-controls row (founder 2026-06-05). */
.rich-head--calendar { display: none !important; }
.cal-controls .cal-new-btn { margin-left: auto; align-self: center; }

/* Calendar page — Cal.com-inspired layout. Day-grouped agenda
   (no pill strip, no hour-by-hour timeline). Display heading uses
   Cal Sans (the Cal.com signature pairing of Cal Sans display +
   Inter body). Status reads through ink-soft tinted chips with a
   filled dot, not coloured backgrounds — keeps the page monotone
   and matches the Anthropic register. */

/* Compact "+ New job" pill — mirrors .inbound-new-btn exactly so the
   two pages read as the same product. */
.cal-new-btn {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 7px 14px; border-radius: 999px;
  /* Dark 3D gradient + inset top highlight, matching the active .cal-tab pill.
     7px vertical (vs the pills' 8px) lands the SAME rendered height once the +
     icon is accounted for, so it sits at exactly the pill size (founder
     2026-06-20). */
  background: linear-gradient(180deg, #3a2f23, #1f1611); color: #fff;
  border: 1px solid transparent;
  box-shadow: 0 1px 2px rgba(31, 22, 17, 0.18), inset 0 1px 0 rgba(255, 255, 255, 0.16);
  font-family: inherit; font-size: 0.8rem; font-weight: 640;
  text-decoration: none; white-space: nowrap; cursor: pointer;
  align-self: center;
  transition: transform 0.15s ease;
}
.cal-new-btn:active { transform: translateY(0.5px); }
.cal-new-btn svg { display: block; }

/* Controls strip (tabs + date nav). */
.cal-controls {
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
  margin: 4px 0 18px;
}

/* Tabs — carved track + raised white 3D-gradient sliding pill, identical to
   the Inbox tabs (founder 2026-06-05). Same JS positions the indicator. */
.cal-tabs {
  position: relative;
  display: inline-flex; gap: 7px; padding: 2px;
  background: transparent; border: 0;
  isolation: isolate;
}
.cal-tab {
  flex-shrink: 0;
  position: relative; z-index: 1;
  display: inline-flex; align-items: center; gap: 6px;
  padding: 8px 14px; border-radius: 999px;
  font-family: inherit;
  font-size: 0.8rem; font-weight: 560;
  color: var(--ink-2, #2a1f17);
  /* same recipe as the Inbox/Drafts .drafts-pill so the views match */
  background: linear-gradient(180deg, #FFFFFF 0%, #F8F8F8 100%);
  border: 1px solid rgba(31, 22, 17, 0.13); border-bottom-color: rgba(31, 22, 17, 0.19);
  cursor: pointer;
  box-shadow: 0 1px 2px rgba(31, 22, 17, 0.05), inset 0 1px 0 rgba(255, 255, 255, 0.9);
  transition: color 0.18s ease;
  -webkit-tap-highlight-color: transparent;
}
.cal-tab:active { transform: translateY(0.5px); }
.cal-tab.is-on { color: #fff; font-weight: 640; border-color: transparent; background: transparent; box-shadow: none; }

.cal-tabs__indicator {
  position: absolute;
  top: 2px; left: 0;
  height: calc(100% - 4px);
  width: 0;
  pointer-events: none; z-index: 0;
  border-radius: 999px;
  /* dark sliding pill, identical to the Inbox/Drafts .drafts-pillind */
  background: linear-gradient(180deg, #3a2f23, #1f1611);
  border: 0;
  box-shadow:
    0 5px 12px -5px rgba(31, 22, 17, 0.5),
    inset 0 1px 0 rgba(255, 255, 255, 0.16);
  will-change: transform, width;
  transform: translate3d(0, 0, 0);
  transition:
    transform 0.3s cubic-bezier(0.34, 1.26, 0.5, 1),
    width 0.3s cubic-bezier(0.34, 1.26, 0.5, 1);
}
.cal-tabs__indicator::before { display: none; }

/* Week range row — Cal Sans label + ghost nav arrows. Replaces the
   prior cream-pill prev/today/next group. The data-cal-range span is
   still populated by JS (the date string). */
.cal-nav-row {
  display: flex; align-items: center; justify-content: space-between;
  gap: 8px;
  padding: 4px 2px;
  margin: 6px 0 4px;
}
.cal-nav-row .cal-range-label {
  font-family: 'Cal Sans', 'Inter Tight', 'Inter', sans-serif;
  font-size: 1.05rem; font-weight: 400;
  letter-spacing: -0.012em;
  color: var(--ink);
  order: -1;
  flex: 1;
}
.cal-nav-row .cal-today-btn { display: none; }
.cal-nav-row .cal-nav-btn {
  width: 30px; height: 30px;
  display: inline-grid; place-items: center;
  background: transparent; border: 0; border-radius: 7px;
  color: var(--ink-mute); cursor: pointer;
  font-family: inherit; font-size: 0.95rem;
  transition: background 0.12s, color 0.12s;
}
.cal-nav-row .cal-nav-btn:hover {
  background: rgba(27, 22, 16, 0.05);
  color: var(--ink);
}

/* Day-grouped agenda — one block per day with a Cal-Sans day number,
   day-of-week label, optional Today tag, and inline event rows or an
   "Open day" dashed band when free. */
/* Zoom segmented control (1× / 2× / 3×). Sits beside the
   Today/Week/Month tabs and controls vertical hour density. */
.cal-zoom {
  position: relative; display: inline-flex; gap: 2px; padding: 3px;
  background: rgba(27, 22, 16, 0.05); border-radius: 9px;
}
.cal-zoom__btn {
  padding: 5px 10px; border: 0; background: transparent;
  font-family: 'JetBrains Mono', monospace;
  font-size: 0.66rem; font-weight: 600; color: var(--ink-mute);
  letter-spacing: 0.04em;
  border-radius: 6px; cursor: pointer;
  transition: color 0.2s ease, background 0.2s ease;
  -webkit-tap-highlight-color: transparent;
}
@media (hover: hover) { .cal-zoom__btn:hover { color: var(--ink); } }
.cal-zoom__btn.is-on {
  color: var(--ink); background: #FFFFFF;
  box-shadow: 0 1px 0 rgba(27, 22, 16, 0.04), 0 1px 3px rgba(27, 22, 16, 0.05);
}

/* Day-pill strip — horizontal navigator. Today is dark-filled, the
   focused day (whose hour grid is shown below) gets an orange ring.
   Days with jobs get a small pin dot under the date. */
.cal-date-strip {
  display: grid; grid-template-columns: repeat(7, 1fr); gap: 3px;
  margin: 10px 0 14px;
}
.cal-pill {
  position: relative;
  display: flex; flex-direction: column; align-items: center;
  padding: 9px 0 11px;
  border-radius: 8px;
  background: transparent;
  border: 1px solid transparent;
  font-family: inherit; cursor: pointer;
  transition: background 0.15s, border-color 0.15s, color 0.15s;
  -webkit-tap-highlight-color: transparent;
}
.cal-pill__name {
  font-family: 'JetBrains Mono', monospace;
  font-size: 0.55rem; letter-spacing: 0.13em; text-transform: uppercase;
  color: var(--ink-faint); font-weight: 500;
}
.cal-pill__num {
  font-size: 0.92rem; font-weight: 600; color: var(--ink);
  margin-top: 2px; letter-spacing: -0.02em; line-height: 1;
  font-variant-numeric: tabular-nums;
}
.cal-pill__pin {
  position: absolute; bottom: 5px; left: 50%; transform: translateX(-50%);
  width: 3px; height: 3px; border-radius: 50%;
  background: var(--ink-soft); opacity: 0.6;
}
@media (hover: hover) {
  .cal-pill:hover { background: rgba(27, 22, 16, 0.04); }
}
/* Focused day — orange ring (only visible when not today). */
.cal-pill.is-on {
  border-color: var(--orange, #D9541E);
  background: transparent;
}
/* Today — solid dark fill. Wins over .is-on (dark + orange ring is noisy). */
.cal-pill.is-today {
  background: var(--ink); border-color: var(--ink);
}
.cal-pill.is-today .cal-pill__name { color: rgba(250, 250, 250, 0.55); }
.cal-pill.is-today .cal-pill__num { color: var(--cream); }
.cal-pill.is-today .cal-pill__pin { background: var(--cream); opacity: 0.75; }

/* Hour grid — Jobber's daily driver. Vertical hour axis on the left,
   slot column on the right. Slot height is driven by CSS var so the
   1×/2×/3× zoom control just rewrites one number. */
.cal-grid-wrap {
  --cal-slot-h: 70px;            /* taller default for more breathing room */
  background: var(--paper);
  border: 1px solid var(--card-bd, rgba(31,22,17,0.08));
  border-radius: 16px; overflow: hidden;
  box-shadow: 0 1px 2px rgba(31,22,17,0.04), inset 0 1px 0 rgba(255,255,255,0.7);
}
.cal-grid-wrap[data-zoom="1"] { --cal-slot-h: 46px; }
.cal-grid-wrap[data-zoom="2"] { --cal-slot-h: 70px; }
.cal-grid-wrap[data-zoom="3"] { --cal-slot-h: 100px; }
.cal-grid-head {
  display: flex; align-items: center; justify-content: space-between;
  padding: 12px 16px;
  border-bottom: 1px solid var(--hairline);
}
.cal-grid-head__day {
  font-size: 0.96rem; font-weight: 600;
  letter-spacing: -0.005em;
}
.cal-grid-head__day b { font-weight: 700; }
.cal-grid-head__cap {
  font-family: 'JetBrains Mono', monospace;
  font-size: 0.62rem; font-weight: 500;
  letter-spacing: 0.14em; text-transform: uppercase;
  color: var(--ink-faint);
}
/* Renamed from .cal-grid to avoid colliding with the old week-grid
   .cal-grid selector + its mobile media-query override above. */
.cal-hgrid {
  display: grid; grid-template-columns: 50px 1fr;
  background: transparent;
}
.cal-gh {
  padding: 12px 0 12px 14px;
  font-family: 'JetBrains Mono', monospace;
  font-size: 0.6rem; font-weight: 500;
  color: var(--ink-faint);
  letter-spacing: 0.1em; text-transform: uppercase;
  border-bottom: 1px solid var(--hairline);
  min-height: var(--cal-slot-h);
  display: flex; align-items: flex-start;
}
.cal-gh:last-of-type { border-bottom: 0; }
.cal-gs {
  position: relative;
  border-bottom: 1px solid var(--hairline);
  border-left: 1px solid var(--hairline);
  min-height: var(--cal-slot-h);
}
.cal-gs:last-of-type { border-bottom: 0; }

/* Event block — solid ink-on-cream fill, brand-orange left bar for
   confirmed, paper left bar for new. Absolute-positioned inside the
   slot at its hour, height scaled by duration relative to slot. */
.cal-blk {
  position: absolute; left: 8px; right: 8px;
  background: var(--ink); color: var(--cream);
  border-radius: 8px;
  border-left: 3px solid var(--orange, #D9541E);
  padding: 9px 11px;
  overflow: hidden;
  box-shadow: 0 1px 2px rgba(27, 22, 16, 0.1);
  cursor: pointer;
}
/* Colour-by-type 3D gradients (founder 2026-06-05). These come after the base
   .cal-blk so they win the same-specificity background. */
.cal-blk--booking { background: linear-gradient(180deg, #3dbe75, #1f9d57); border-left-color: #15833f; box-shadow: 0 2px 6px -1px rgba(31,157,87,0.32), inset 0 1px 0 rgba(255,255,255,0.2); }
.cal-blk--gcal { background: linear-gradient(180deg, #5b9bf5, #4285F4); border-left-color: #2f68d8; box-shadow: 0 2px 6px -1px rgba(66,133,244,0.32), inset 0 1px 0 rgba(255,255,255,0.2); }
.cal-blk--sm8 { background: linear-gradient(180deg, #3fb6d8, #1b7cb0); border-left-color: #15688f; box-shadow: 0 2px 6px -1px rgba(27,124,176,0.32), inset 0 1px 0 rgba(255,255,255,0.2); }
.cal-blk--block { background: repeating-linear-gradient(45deg, var(--cream-2) 0, var(--cream-2) 7px, #e6e0d6 7px, #e6e0d6 14px); color: var(--ink-mute); border-left-color: var(--hairline-2); box-shadow: none; }
.cal-blk.is-new { border-left-color: var(--cream, #FAFAFA); }
.cal-blk.is-past { opacity: 0.55; }
.cal-blk__ttl {
  font-size: 0.84rem; font-weight: 600;
  letter-spacing: -0.005em; line-height: 1.2;
}
.cal-blk__meta {
  font-size: 0.72rem; opacity: 0.78;
  margin-top: 2px; line-height: 1.3;
}
.cal-blk__time {
  font-family: 'JetBrains Mono', monospace;
  font-size: 0.6rem; font-weight: 500;
  letter-spacing: 0.06em;
  opacity: 0.7; margin-top: 4px;
  text-transform: uppercase;
}
.cal-blk__new {
  position: absolute; top: 8px; right: 9px;
  font-family: 'JetBrains Mono', monospace;
  font-size: 0.55rem; font-weight: 700;
  letter-spacing: 0.14em; text-transform: uppercase;
  color: var(--cream); opacity: 0.85;
}

/* "Now" indicator inside a slot — horizontal orange hairline + dot. */
.cal-now-line {
  position: absolute; left: 0; right: 0; height: 2px;
  background: var(--orange, #D9541E); z-index: 4; pointer-events: none;
}
.cal-now-line:before {
  content: ""; position: absolute; left: -4px; top: -3px;
  width: 8px; height: 8px; border-radius: 50%;
  background: var(--orange, #D9541E);
  box-shadow: 0 0 0 3px rgba(217, 84, 30, 0.18);
}

/* Mobile (≤720px): the .rich-actions toolbar (prev/today/next + range +
   Today/Week/Month + New job) can't fit beside the title at this width.
   .rich-head is grid `1fr auto`, so the auto column pins itself wide and
   starves the 1fr title column to 0px — title and subtitle then wrap one
   character per line because they live in a 0-width box. Stack the head
   to a single column and stack each toolbar group as its own full-width
   row: nav, segmented view toggle, primary CTA. */
@media (max-width: 720px) {
  .rich-head { grid-template-columns: 1fr; gap: 12px; }
  .rich-actions { flex-direction: column; align-items: stretch; gap: 10px; }
  .cal-nav-row { display: flex; width: 100%; margin-right: 0; }
  .cal-range-label { flex: 1; text-align: right; margin: 0 0 0 8px; }
  .rich-actions .toggle-group { width: 100%; }
  .rich-actions .toggle-group button { flex: 1; }
  .rich-actions > .btn { width: 100%; justify-content: center; }
}

/* Inline grid loading shimmer */
.cal-loading-row {
  height: 100%;
  background: linear-gradient(
    90deg,
    var(--cream-2) 0%,
    var(--cream-3) 50%,
    var(--cream-2) 100%
  );
  background-size: 200% 100%;
  animation: cal-shimmer 1.4s ease-in-out infinite;
  opacity: 0.6;
}
@keyframes cal-shimmer {
  0%   { background-position: 200% 0; }
  100% { background-position: -200% 0; }
}

/* Inline status strip below grid */
.cal-status-row {
  margin-top: 12px;
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 0.82rem;
  color: var(--ink-mute);
}
.cal-status-row .cal-status-dot {
  width: 6px; height: 6px;
  border-radius: 50%;
  background: var(--ink-faint);
}
.cal-status-row.is-error { color: var(--orange-deep); }
.cal-status-row.is-error .cal-status-dot { background: var(--orange-deep); }

/* Sync status strip */
.cal-sync {
  background: var(--cream-2);
  border: 1px solid var(--hairline);
  border-radius: 12px;
  padding: 12px 18px;
  display: flex; align-items: center; justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
  font-size: 0.82rem;
  color: var(--ink-mute);
}
.cal-sync-left {
  display: inline-flex; align-items: center; gap: 10px;
}
.cal-sync-dot {
  width: 8px; height: 8px;
  border-radius: 50%;
  background: var(--green);
  animation: pulse 2.4s ease-in-out infinite;
}
.cal-sync-meta {
  font-family: 'JetBrains Mono', monospace;
  font-size: 0.6rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink-faint);
}
.cal-sync-meta strong { color: var(--green); font-weight: 700; }

/* ============================================================================
   Payments — booking-deposit summary + Stripe Connect deposit list
   ========================================================================== */
.pay-card {
  background: var(--paper);
  border: 1px solid var(--hairline);
  border-radius: var(--card-radius);
  overflow: hidden;
  transition: border-color 0.18s cubic-bezier(0.2, 0, 0, 1);
}
.pay-card:hover { border-color: var(--hairline-2); }
.pay-list-head {
  display: grid;
  grid-template-columns: 90px 1.4fr 1.6fr 90px 100px 90px 70px;
  gap: 12px;
  padding: 10px 18px;
  background: var(--cream);
  border-bottom: 1px solid var(--hairline);
  font-family: 'JetBrains Mono', monospace;
  font-size: 0.54rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--ink-faint);
  font-weight: 600;
}
.pay-list-head .pay-amt-h { text-align: right; }

.pay-row {
  display: grid;
  grid-template-columns: 90px 1.4fr 1.6fr 90px 100px 90px 70px;
  gap: 12px;
  padding: 14px 18px;
  border-bottom: 1px solid var(--hairline);
  align-items: center;
  font-size: 0.86rem;
}
.pay-row:last-child { border-bottom: 0; }
.pay-row:hover { background: rgba(31,22,17,0.015); }
.pay-inv {
  font-family: 'JetBrains Mono', monospace;
  font-size: 0.76rem;
  font-weight: 600;
  color: var(--ink);
  letter-spacing: 0.04em;
}
.pay-cust { min-width: 0; }
.pay-cust-name {
  font-weight: 600;
  color: var(--ink);
  font-size: 0.9rem;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.pay-cust-sub {
  font-family: 'JetBrains Mono', monospace;
  font-size: 0.58rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ink-faint);
  margin-top: 2px;
}
.pay-job {
  color: var(--ink-mute);
  font-size: 0.84rem;
  line-height: 1.4;
}
.pay-date {
  font-family: 'JetBrains Mono', monospace;
  font-size: 0.7rem;
  letter-spacing: 0.06em;
  color: var(--ink-faint);
  text-transform: uppercase;
}
.pay-amt {
  font-family: 'Geist', 'Inter Tight', 'Inter', sans-serif;
  font-size: 1.05rem;
  font-weight: 600;
  color: var(--ink);
  letter-spacing: -0.01em;
  text-align: right;
}
.pay-pill {
  font-family: 'JetBrains Mono', monospace;
  font-size: 0.56rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  font-weight: 700;
  padding: 4px 8px;
  border-radius: 5px;
  text-align: center;
  display: inline-block;
}
.pay-pill.is-paid    { color: var(--green);  background: var(--green-soft); }
.pay-pill.is-sent    { color: var(--blue);   background: var(--blue-soft); }
.pay-pill.is-overdue { color: var(--orange); background: var(--orange-wash); }
.pay-pill.is-draft   { color: var(--ink-faint); background: var(--cream-2); }

.pay-row-action {
  background: transparent;
  border: 1px solid var(--hairline-2);
  border-radius: 7px;
  padding: 5px 9px;
  font-family: inherit;
  font-size: 0.72rem;
  color: var(--ink);
  cursor: pointer;
  white-space: nowrap;
  text-align: center;
}
.pay-row-action:hover { background: var(--cream-2); border-color: var(--hairline-3); }

/* New-invoice CTA strip */
.pay-cta-strip {
  display: flex; align-items: center; justify-content: space-between;
  gap: 14px;
  padding: 18px 22px;
  background: var(--cream-2);
  border: 1px solid var(--hairline);
  border-radius: 12px;
  flex-wrap: wrap;
}
.pay-cta-text {
  font-size: 0.88rem;
  color: var(--ink-mute);
}
.pay-cta-text strong { color: var(--ink); font-weight: 600; }

/* Responsive: stack invoice rows on narrow viewports */
@media (max-width: 980px) {
  .pay-list-head { display: none; }
  .pay-row {
    grid-template-columns: 1fr auto;
    gap: 6px 12px;
    padding: 14px 16px;
  }
  .pay-row .pay-inv { grid-column: 1; grid-row: 1; }
  .pay-row .pay-pill { grid-column: 2; grid-row: 1; justify-self: end; }
  .pay-row .pay-cust { grid-column: 1 / -1; grid-row: 2; }
  .pay-row .pay-job  { grid-column: 1 / -1; grid-row: 3; }
  .pay-row .pay-date { grid-column: 1; grid-row: 4; }
  .pay-row .pay-amt  { grid-column: 2; grid-row: 4; }
  .pay-row .pay-row-action { grid-column: 1 / -1; grid-row: 5; justify-self: start; }
}
@media (max-width: 880px) {
  .cal-week-head,
  .cal-grid { grid-template-columns: 44px repeat(7, minmax(80px, 1fr)); }
  .cal-card { overflow-x: auto; }
}

/* ============================================================================
   Booking requests + Conversations — rich-page layouts
   Same warm-stone tokens; uses .rp-* prefix to avoid clashing with .cal-/.pay-
   styles above.
   ========================================================================== */

.rp-page { display: flex; flex-direction: column; gap: 18px; }

/* === Filter chips (Booking requests) ==================================== */
.rp-chips {
  display: flex; gap: 6px; flex-wrap: wrap;
  margin: 4px 0 4px;
}

/* === Booking-request rows =============================================== */
.rp-list {
  background: var(--paper);
  border: 1px solid var(--hairline);
  border-radius: var(--card-radius);
  overflow: hidden;
  transition: border-color 0.18s cubic-bezier(0.2, 0, 0, 1);
}
.rp-list:hover { border-color: var(--hairline-2); }
.rp-row {
  display: grid;
  grid-template-columns: 36px 1fr auto;
  gap: 12px;
  padding: 14px 18px;
  border-bottom: 1px solid var(--hairline);
  align-items: flex-start;
}
.rp-row:last-child { border-bottom: 0; }
.rp-row:hover { background: rgba(31,22,17,0.015); }
.rp-avatar {
  width: 36px; height: 36px;
  border-radius: 50%;
  background: var(--cream-2);
  color: var(--ink);
  font-family: 'Geist', 'Inter Tight', 'Inter', sans-serif;
  font-weight: 600;
  font-size: 0.84rem;
  display: flex; align-items: center; justify-content: center;
  flex: 0 0 auto;
  letter-spacing: 0.01em;
}
.rp-avatar.is-orange { background: var(--orange-wash); color: var(--orange); }
.rp-avatar.is-green  { background: var(--green-soft);  color: var(--green); }
.rp-avatar.is-blue   { background: var(--blue-soft);   color: var(--blue); }
.rp-avatar.is-grey   { background: var(--cream-3);     color: var(--ink-mute); }

.rp-row-text { min-width: 0; }
.rp-row-name {
  font-weight: 600;
  color: var(--ink);
  font-size: 0.92rem;
  display: flex; align-items: center; gap: 6px;
  flex-wrap: wrap;
  margin-bottom: 4px;
}
.rp-pill {
  font-family: 'JetBrains Mono', monospace;
  font-size: 0.52rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  background: var(--cream-2);
  color: var(--ink-mute);
  padding: 2px 6px;
  border-radius: 4px;
  font-weight: 700;
}
.rp-pill.is-awaiting { background: var(--orange-wash); color: var(--orange); }
.rp-pill.is-quoted   { background: var(--blue-soft);   color: var(--blue); }
.rp-pill.is-booked   { background: var(--green-soft);  color: var(--green); }
.rp-pill.is-archived { background: var(--cream-3);     color: var(--ink-faint); }
.rp-pill.is-source   { background: var(--cream-2);     color: var(--ink-mute); font-weight: 600; }
.rp-pill.is-out-of-area { background: var(--cream-3); color: var(--ink-mute); font-weight: 600; }

.rp-row-meta {
  font-family: 'JetBrains Mono', monospace;
  font-size: 0.58rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ink-faint);
}
.rp-row-quote {
  font-size: 0.84rem;
  color: var(--ink-mute);
  margin-top: 6px;
  line-height: 1.5;
}

.rp-row-actions {
  display: flex; gap: 6px; flex-wrap: wrap;
  align-items: center;
}
.rp-action {
  background: transparent;
  border: 1px solid var(--hairline-2);
  border-radius: 7px;
  padding: 6px 10px;
  font-family: inherit;
  font-size: 0.74rem;
  color: var(--ink);
  cursor: pointer;
  transition: background 0.12s, border-color 0.12s;
  white-space: nowrap;
}
.rp-action:hover { background: var(--cream-2); }
.rp-action.is-primary {
  background: var(--ink);
  color: #fff;
  border-color: var(--ink);
}
.rp-action.is-primary:hover { background: var(--ink-2); }

.rp-load-more {
  display: inline-flex; align-self: flex-start;
  align-items: center; gap: 8px;
  font-family: 'JetBrains Mono', monospace;
  font-size: 0.7rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ink-mute);
  background: transparent;
  border: 1px solid var(--hairline-2);
  border-radius: 8px;
  padding: 8px 14px;
  cursor: pointer;
}
.rp-load-more:hover { background: var(--cream-2); color: var(--ink); }

/* === Conversations: two-pane layout ===================================== */
.rp-conv {
  display: grid;
  grid-template-columns: 320px 1fr;
  background: var(--paper);
  border: 1px solid var(--hairline);
  border-radius: var(--card-radius);
  overflow: hidden;
  min-height: 580px;
  transition: border-color 0.18s cubic-bezier(0.2, 0, 0, 1);
}
.rp-conv:hover { border-color: var(--hairline-2); }
.rp-conv-aside {
  border-right: 1px solid var(--hairline);
  display: flex; flex-direction: column;
  background: var(--cream);
  min-width: 0;
}
.rp-conv-aside-head {
  padding: 14px 16px 12px;
  border-bottom: 1px solid var(--hairline);
}
.rp-conv-search {
  width: 100%;
  background: var(--paper);
  border: 1px solid var(--hairline-2);
  border-radius: 8px;
  padding: 7px 12px;
  font-family: inherit;
  font-size: 0.82rem;
  color: var(--ink);
}
.rp-conv-search::placeholder { color: var(--ink-faint); }

.rp-thread-list {
  flex: 1 1 auto;
  overflow-y: auto;
  max-height: 520px;
}
.rp-thread {
  display: grid;
  grid-template-columns: 32px 1fr auto;
  gap: 10px;
  padding: 12px 16px;
  border-bottom: 1px solid var(--hairline);
  cursor: pointer;
  align-items: flex-start;
  background: transparent;
  border-left: 0; border-right: 0; border-top: 0;
  width: 100%;
  text-align: left;
  font-family: inherit;
  transition: background 0.12s;
}
.rp-thread:hover { background: var(--cream-2); }
.rp-thread.is-active { background: var(--paper); }
.rp-thread .rp-avatar {
  width: 32px; height: 32px;
  font-size: 0.74rem;
}
.rp-thread-text { min-width: 0; }
.rp-thread-name {
  font-weight: 600;
  font-size: 0.86rem;
  color: var(--ink);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  margin-bottom: 2px;
}
.rp-thread-snippet {
  font-size: 0.78rem;
  color: var(--ink-mute);
  line-height: 1.4;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.rp-thread-side {
  display: flex; flex-direction: column; align-items: flex-end; gap: 4px;
  flex: 0 0 auto;
}
.rp-thread-time {
  font-family: 'JetBrains Mono', monospace;
  font-size: 0.54rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink-faint);
}
.rp-thread-dot {
  width: 6px; height: 6px;
  border-radius: 50%;
  background: var(--orange);
}

/* === Conversations: detail pane ========================================= */
.rp-conv-main {
  display: flex; flex-direction: column;
  min-width: 0;
}
.rp-conv-head {
  display: flex; align-items: center; gap: 12px;
  padding: 14px 20px;
  border-bottom: 1px solid var(--hairline);
}
.rp-conv-head .rp-avatar {
  width: 38px; height: 38px;
  font-size: 0.86rem;
}
.rp-conv-head-text { min-width: 0; flex: 1 1 auto; }
.rp-conv-head-name {
  font-weight: 600;
  font-size: 0.96rem;
  color: var(--ink);
}
.rp-conv-head-meta {
  font-family: 'JetBrains Mono', monospace;
  font-size: 0.58rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ink-faint);
  margin-top: 2px;
}
.rp-conv-head-actions {
  display: flex; gap: 6px; flex: 0 0 auto;
}
.rp-conv-back-btn {
  display: none;
  background: transparent;
  border: 1px solid var(--hairline-2);
  border-radius: 7px;
  padding: 6px 10px;
  font-family: 'JetBrains Mono', monospace;
  font-size: 0.62rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ink-mute);
  cursor: pointer;
}
.rp-conv-back-btn:hover { background: var(--cream-2); }

.rp-conv-stream {
  flex: 1 1 auto;
  overflow-y: auto;
  padding: 20px 22px;
  background: var(--cream);
  display: flex; flex-direction: column; gap: 10px;
}
.rp-day-divider {
  align-self: center;
  font-family: 'JetBrains Mono', monospace;
  font-size: 0.54rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--ink-faint);
  background: transparent;
  padding: 4px 12px;
  margin: 4px 0;
}

.rp-msg {
  max-width: 78%;
  padding: 10px 14px;
  border-radius: 14px;
  font-size: 0.86rem;
  line-height: 1.45;
  position: relative;
}
.rp-msg-from {
  font-family: 'JetBrains Mono', monospace;
  font-size: 0.5rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  font-weight: 700;
  display: block;
  margin-bottom: 4px;
  opacity: 0.6;
}
.rp-msg-time {
  display: block;
  font-family: 'JetBrains Mono', monospace;
  font-size: 0.5rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  margin-top: 5px;
  opacity: 0.7;
}
.rp-msg.is-customer {
  align-self: flex-start;
  background: var(--paper);
  color: var(--ink);
  border: 1px solid var(--hairline);
  border-bottom-left-radius: 5px;
}
.rp-msg.is-customer .rp-msg-time { color: var(--ink-faint); }
.rp-msg.is-ai {
  align-self: flex-end;
  background: var(--ink);
  color: #fff;
  border-bottom-right-radius: 5px;
}
.rp-msg.is-ai .rp-msg-time { color: rgba(255,255,255,0.65); }
.rp-msg.is-tradie {
  align-self: flex-end;
  background: var(--orange);
  color: #fff;
  border-bottom-right-radius: 5px;
}
.rp-msg.is-tradie .rp-msg-time { color: rgba(255,255,255,0.7); }

.rp-system-note {
  align-self: center;
  font-family: 'JetBrains Mono', monospace;
  font-size: 0.54rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink-faint);
  background: var(--cream-2);
  border: 1px dashed var(--hairline-2);
  border-radius: 999px;
  padding: 5px 12px;
  max-width: 80%;
  text-align: center;
}

.rp-conv-compose {
  border-top: 1px solid var(--hairline);
  padding: 12px 16px;
  display: flex; gap: 8px; align-items: flex-end;
  background: var(--paper);
}
.rp-conv-compose textarea {
  flex: 1 1 auto;
  resize: none;
  min-height: 38px;
  max-height: 120px;
  border: 1px solid var(--hairline-2);
  border-radius: 8px;
  padding: 9px 12px;
  font-family: inherit;
  font-size: 0.88rem;
  color: var(--ink);
  background: var(--cream);
}
.rp-conv-compose textarea:focus {
  outline: none;
  border-color: var(--ink-mute);
  background: var(--paper);
}
.rp-conv-send {
  background: var(--ink);
  color: #fff;
  border: 0;
  border-radius: 8px;
  padding: 10px 16px;
  font-family: inherit;
  font-size: 0.82rem;
  font-weight: 600;
  cursor: pointer;
  flex: 0 0 auto;
}
.rp-conv-send:hover { background: var(--ink-2); }

/* === Mobile: stack list above thread ==================================== */
@media (max-width: 880px) {
  .rp-conv {
    grid-template-columns: 1fr;
    min-height: 0;
  }
  .rp-conv-aside {
    border-right: 0;
    border-bottom: 1px solid var(--hairline);
  }
  .rp-thread-list { max-height: 420px; }
  /* Single-pane mobile mode: data-mobile-view swaps which pane is visible. */
  .rp-conv[data-mobile-view="list"] .rp-conv-main { display: none; }
  .rp-conv[data-mobile-view="thread"] .rp-conv-aside { display: none; }
  .rp-conv[data-mobile-view="thread"] .rp-conv-back-btn { display: inline-flex; }

  .rp-row { grid-template-columns: 32px 1fr; }
  .rp-row-actions { grid-column: 1 / -1; margin-top: 6px; justify-content: flex-end; }
  .rp-avatar { width: 32px; height: 32px; font-size: 0.78rem; }
}

/* === Conversations: filter chips, quick replies, meta sidebar =========== */
.rp-conv-filters {
  display: flex; flex-wrap: wrap; gap: 6px;
}
.rp-conv-filter {
  background: transparent;
  border: 1px solid var(--hairline-2);
  border-radius: 999px;
  padding: 4px 10px;
  font-family: 'JetBrains Mono', monospace;
  font-size: 0.58rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ink-mute);
  cursor: pointer;
  transition: background 0.12s, color 0.12s, border-color 0.12s;
}
.rp-conv-filter:hover { background: var(--cream-2); color: var(--ink); }
.rp-conv-filter.is-on {
  background: var(--ink);
  color: #fff;
  border-color: var(--ink);
}
.rp-conv-aside-head { display: flex; flex-direction: column; gap: 10px; }

/* Conversations: thread row hidden by search */
.rp-thread.is-hidden { display: none; }

/* Quick-reply chip row above the textarea */
.rp-conv-compose-wrap {
  display: flex; flex-direction: column;
  border-top: 1px solid var(--hairline);
  background: var(--paper);
}
.rp-quick-replies {
  display: flex; gap: 6px; flex-wrap: wrap;
  padding: 10px 16px 0;
}
.rp-quick-reply {
  background: var(--cream-2);
  border: 1px solid var(--hairline-2);
  border-radius: 999px;
  padding: 4px 10px;
  font-size: 0.74rem;
  color: var(--ink);
  cursor: pointer;
  font-family: inherit;
  transition: background 0.12s;
}
.rp-quick-reply:hover { background: var(--cream-3); }
.rp-conv-compose-wrap .rp-conv-compose { border-top: 0; padding-top: 8px; }
.rp-compose-hint {
  font-family: 'JetBrains Mono', monospace;
  font-size: 0.54rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ink-faint);
  padding: 0 16px 10px;
}
.rp-compose-attach {
  background: transparent;
  border: 1px solid var(--hairline-2);
  border-radius: 8px;
  width: 38px; height: 38px;
  display: flex; align-items: center; justify-content: center;
  cursor: pointer;
  color: var(--ink-mute);
  flex: 0 0 auto;
}
.rp-compose-attach:hover { background: var(--cream-2); color: var(--ink); }

/* Outbound delivery status */
.rp-msg-status {
  display: block;
  font-family: 'JetBrains Mono', monospace;
  font-size: 0.5rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  margin-top: 3px;
  opacity: 0.75;
}
.rp-msg-status.is-failed { color: #d97757; opacity: 1; font-weight: 700; }

/* Thread head: info + 3-dot icon buttons */
.rp-icon-btn {
  background: transparent;
  border: 1px solid var(--hairline-2);
  border-radius: 7px;
  width: 30px; height: 30px;
  display: inline-flex; align-items: center; justify-content: center;
  cursor: pointer;
  color: var(--ink-mute);
  position: relative;
}
.rp-icon-btn:hover { background: var(--cream-2); color: var(--ink); }
.rp-icon-btn svg { width: 14px; height: 14px; }

/* Thread actions popover */
.rp-actions-pop {
  position: absolute;
  top: calc(100% + 6px); right: 0;
  background: var(--paper);
  border: 1px solid var(--hairline-2);
  border-radius: var(--card-radius);
  box-shadow: 0 12px 32px rgba(0, 0, 0, 0.32);
  padding: 6px;
  min-width: 220px;
  z-index: 30;
  display: none;
  flex-direction: column;
}
.rp-actions-pop.is-open { display: flex; }
.rp-actions-pop button {
  background: transparent;
  border: 0;
  text-align: left;
  padding: 8px 10px;
  border-radius: 6px;
  font-family: inherit;
  font-size: 0.82rem;
  color: var(--ink);
  cursor: pointer;
}
.rp-actions-pop button:hover { background: var(--cream-2); }
.rp-actions-pop button.is-danger { color: #c0392b; }
.rp-actions-menu-wrap { position: relative; }

/* Conversations: meta sidebar */
.rp-conv {
  grid-template-columns: 320px 1fr 0;
  transition: grid-template-columns 0.18s ease;
}
.rp-conv.is-meta-open { grid-template-columns: 320px 1fr 280px; }
.rp-meta {
  border-left: 1px solid var(--hairline);
  background: var(--cream);
  overflow-y: auto;
  display: flex; flex-direction: column;
  min-width: 0;
  max-height: 720px;
}
.rp-conv:not(.is-meta-open) .rp-meta { display: none; }
.rp-meta-head {
  display: flex; align-items: center; justify-content: space-between;
  padding: 14px 16px;
  border-bottom: 1px solid var(--hairline);
}
.rp-meta-head-title {
  font-family: 'JetBrains Mono', monospace;
  font-size: 0.58rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink-faint);
  font-weight: 700;
}
.rp-meta-section {
  padding: 14px 16px;
  border-bottom: 1px solid var(--hairline);
  display: flex; flex-direction: column; gap: 8px;
}
.rp-meta-section:last-child { border-bottom: 0; }
.rp-meta-label {
  font-family: 'JetBrains Mono', monospace;
  font-size: 0.54rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink-faint);
  font-weight: 700;
}
.rp-meta-customer {
  display: flex; align-items: center; gap: 10px;
}
.rp-meta-customer-text { min-width: 0; }
.rp-meta-customer-name {
  font-weight: 600; font-size: 0.92rem; color: var(--ink);
}
.rp-meta-customer-meta {
  font-size: 0.76rem; color: var(--ink-mute); margin-top: 2px;
}
.rp-meta-booking {
  background: var(--paper);
  border: 1px solid var(--hairline);
  border-radius: var(--card-radius-data);
  padding: 8px 10px;
  font-size: 0.78rem;
  color: var(--ink);
}
.rp-meta-booking-status {
  font-family: 'JetBrains Mono', monospace;
  font-size: 0.54rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--green);
  font-weight: 700;
  margin-bottom: 2px;
  display: block;
}
.rp-meta-booking-status.is-quote { color: var(--blue); }
.rp-meta-summary {
  background: var(--paper);
  border: 1px solid var(--hairline);
  border-left: 2px solid var(--ink-mute);
  border-radius: var(--card-radius-data);
  padding: 10px 12px;
  font-size: 0.8rem;
  color: var(--ink);
  line-height: 1.5;
}
.rp-meta-summary strong {
  font-family: 'JetBrains Mono', monospace;
  font-size: 0.54rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-mute);
  display: block;
  margin-bottom: 4px;
  font-weight: 700;
}
.rp-meta-notes {
  width: 100%;
  background: var(--paper);
  border: 1px solid var(--hairline-2);
  border-radius: var(--card-radius-data);
  padding: 8px 10px;
  font-family: inherit;
  font-size: 0.82rem;
  color: var(--ink);
  resize: vertical;
  min-height: 64px;
}
.rp-meta-tags { display: flex; flex-wrap: wrap; gap: 6px; }
.rp-meta-tag {
  background: var(--paper);
  border: 1px solid var(--hairline-2);
  border-radius: 999px;
  padding: 3px 9px;
  font-size: 0.7rem;
  color: var(--ink);
}
.rp-meta-tag.is-vip { background: var(--orange-wash); color: var(--orange); border-color: transparent; font-weight: 600; }
.rp-meta-actions { display: flex; gap: 6px; }
.rp-meta-action {
  flex: 1 1 auto;
  background: transparent;
  border: 1px solid var(--hairline-2);
  border-radius: 7px;
  padding: 7px 10px;
  font-family: inherit;
  font-size: 0.76rem;
  color: var(--ink-mute);
  cursor: pointer;
}
.rp-meta-action:hover { background: var(--cream-2); color: var(--ink); }
.rp-meta-action.is-danger { color: #c0392b; }

@media (max-width: 880px) {
  .rp-conv, .rp-conv.is-meta-open {
    grid-template-columns: 1fr;
  }
  .rp-conv.is-meta-open .rp-meta {
    position: fixed; inset: 0;
    z-index: 60;
    max-height: none;
    border-left: 0;
    background: var(--paper);
  }
  .rp-conv.is-meta-open .rp-conv-aside,
  .rp-conv.is-meta-open .rp-conv-main { display: none; }
  .rp-conv-filters { overflow-x: auto; flex-wrap: nowrap; }
  .rp-conv-filter { white-space: nowrap; flex: 0 0 auto; }
}

/* ============================================================================
   Integrations + Settings + Notifications — page-specific layouts
   ========================================================================== */

/* Shared page header */
.pg-head { display: flex; flex-direction: column; gap: 6px; margin-bottom: 4px; }
.pg-eye {
  /* deprecated mono caps eyebrow — hidden in chrome-less restraint pass */
  display: none !important;
}
.pg-title {
  font-family: 'Geist', 'Inter Tight', 'Inter', sans-serif;
  font-size: 1.6rem; font-weight: 500; margin: 0;
  letter-spacing: -0.02em; line-height: 1.1; color: var(--ink);
}
.pg-sub {
  font-size: 0.92rem; color: var(--ink-mute);
  margin: 0; max-width: 64ch; line-height: 1.55;
}
.pg-group-head {
  font-family: 'Geist', 'Inter Tight', 'Inter', sans-serif;
  font-size: 0.95rem; letter-spacing: -0.005em; text-transform: none;
  color: var(--ink); font-weight: 600;
  margin: 24px 0 10px; padding-bottom: 8px;
  border-bottom: 1px solid var(--hairline);
}

/* Integrations grid */
.intg-grid {
  display: grid; grid-template-columns: repeat(3, 1fr); gap: 12px;
}
@media (max-width: 980px) { .intg-grid { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 640px) { .intg-grid { grid-template-columns: 1fr; } }

.intg-card {
  background: var(--paper);
  border: 1px solid var(--hairline);
  border-radius: var(--card-radius);
  padding: var(--card-pad);
  display: flex; flex-direction: column;
  min-height: 188px;
  transition: border-color 0.18s cubic-bezier(0.2, 0, 0, 1), background 0.18s cubic-bezier(0.2, 0, 0, 1);
}
.intg-card:hover {
  border-color: var(--hairline-2);
}
.intg-card.is-quiet {
  background: transparent;
  border: 1px dashed var(--hairline-2);
}
.intg-card-top { display: flex; align-items: center; gap: 10px; margin-bottom: 12px; }
.intg-tier {
  margin-left: auto;
  font-family: 'JetBrains Mono', monospace;
  font-size: 0.54rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  font-weight: 600;
  padding: 3px 8px;
  border-radius: 4px;
  white-space: nowrap;
  flex-shrink: 0;
}
.intg-tier--all      { color: var(--ink-mute); background: var(--cream-2); }
.intg-tier--recovery { color: var(--orange-deep, #B8420F); background: var(--orange-wash, rgba(217,84,30,0.10)); }
.intg-tier--builder  { color: var(--ink); background: var(--cream-3); }
.intg-logo {
  width: 36px; height: 36px;
  border-radius: 8px;
  background: var(--cream-2);
  display: inline-flex; align-items: center; justify-content: center;
  flex: 0 0 auto; overflow: hidden;
  padding: 6px;
}
.intg-logo svg, .intg-logo img { max-width: 100%; max-height: 100%; object-fit: contain; }
.intg-logo.is-twilio  { background: #F22F46; color: #fff; padding: 0; font-family: 'Newsreader', serif; font-weight: 700; font-size: 1.18rem; }
.intg-logo.is-openai  { background: #0F1820; color: #fff; padding: 7px; }
.intg-logo.is-gmail   { background: #fff; color: #EA4335; border: 1px solid var(--hairline); padding: 0; font-family: 'Newsreader', serif; font-weight: 700; font-size: 1.18rem; }
.intg-logo.is-xero    { background: #13B5EA; color: #fff; padding: 6px; font-family: 'Newsreader', serif; font-weight: 700; font-size: 1rem; }
.intg-logo.is-myob    { background: #6E2585; color: #fff; padding: 6px; font-family: 'Newsreader', serif; font-weight: 700; font-size: 0.96rem; }
.intg-logo.is-ms      { background: #0078D4; color: #fff; padding: 6px; font-family: 'Newsreader', serif; font-weight: 700; font-size: 1.05rem; }
.intg-card-title {
  font-family: 'Geist', 'Inter Tight', 'Inter', sans-serif;
  font-size: 1.06rem; font-weight: 600;
  color: var(--ink); letter-spacing: -0.01em;
  flex: 1 1 auto; min-width: 0;
}
.intg-status {
  display: inline-flex; align-items: center; gap: 6px;
  font-family: 'JetBrains Mono', monospace;
  font-size: 0.56rem; letter-spacing: 0.14em; text-transform: uppercase;
  font-weight: 600;
  padding: 3px 8px; border-radius: 5px;
  margin-bottom: 8px; align-self: flex-start;
}
.intg-status::before {
  content: ''; width: 6px; height: 6px;
  border-radius: 50%; flex: 0 0 auto;
}
.intg-status.is-on     { background: var(--green-soft); color: var(--green); }
.intg-status.is-on::before { background: var(--green); }
.intg-status.is-system { background: var(--cream-2); color: var(--ink-mute); }
.intg-status.is-system::before { background: var(--ink-faint); }
.intg-status.is-avail  { background: var(--cream-2); color: var(--ink-mute); }
.intg-status.is-avail::before { background: var(--ink-mute); }
.intg-status.is-soon   {
  background: transparent; color: var(--ink-faint);
  border: 1px dashed var(--hairline-2);
  padding: 2px 7px;
}
.intg-status.is-soon::before { display: none; }

.intg-desc {
  font-size: 0.84rem; color: var(--ink-mute);
  line-height: 1.5; margin: 0 0 14px;
  flex: 1 1 auto;
}
.intg-action {
  display: inline-flex; align-items: center; justify-content: center;
  padding: 8px 12px;
  font-family: inherit; font-size: 0.78rem; font-weight: 500;
  border-radius: 8px;
  border: 1px solid var(--hairline-2);
  background: transparent; color: var(--ink);
  cursor: pointer; text-decoration: none;
  align-self: flex-start;
  transition: background 0.12s, border-color 0.12s;
}
.intg-action:hover { background: var(--cream-2); border-color: var(--hairline-3); }
.intg-action.is-disabled,
.intg-action[disabled] {
  color: var(--ink-faint); cursor: not-allowed;
  border-style: dashed;
}
.intg-action.is-disabled:hover,
.intg-action[disabled]:hover { background: transparent; border-color: var(--hairline-2); }
.intg-action.is-system {
  color: var(--ink-mute);
  border: 1px dashed var(--hairline-2);
  cursor: default;
  font-family: 'JetBrains Mono', monospace;
  font-size: 0.58rem; letter-spacing: 0.14em; text-transform: uppercase;
}
.intg-action.is-system:hover { background: transparent; border-color: var(--hairline-2); }

/* When the Settings page is mounted, the parent .dash / .pg / .rich-page
   wrapper's 940px max-width would otherwise cage the rail + content.
   Widen it just for settings routes via :has() so other pages keep their
   reading-width caps. */
main.dash:has(.set-shell),
.pg:has(.set-shell),
.rich-page:has(.set-shell) {
  /* Claude-style flush-left settings: drop the 1040px cap + the
     inherited centering so .set-shell hugs the first sidebar instead
     of floating in the middle of the page. The 32px horizontal padding
     on .dash is also zeroed so .set-shell controls its own gutter. */
  max-width: none;
  margin: 0;
  padding-left: 0;
  padding-right: 0;
}

/* Settings form — Claude.ai-style centred layout. Rail (180px) + 40px gap +
   content (max 720px) ≈ 940px content + 40px page padding either side
   ≈ 1020px total. Tightened 2026-05-13 (pm) from 240+40+760 / max 1120px
   — the rail itself read too wide vs. Claude's settings, and the founder
   asked for the second sidebar specifically to feel narrower. */
/* ── Booking-form Commit 3 (2026-05-20): mode picker + per-day windows
   editor. Replaces the deleted .route-opt-block (was here previously).
   Conditional section visibility is driven by [data-conditional-mode] on
   the parent + a [data-hidden] attribute toggled by the wire-up code
   when the user clicks a different mode tile. ───────────────────── */
[data-conditional-mode][data-hidden] { display: none; }

/* Mode picker — 4 tiles in a 2x2 grid (collapses to 1 col on narrow). */
.set-mode-row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 10px;
  margin: 4px 0 4px;
}
@media (max-width: 640px) { .set-mode-row { grid-template-columns: 1fr; } }
.set-mode-card {
  background: var(--cream);
  border: 1px solid var(--hairline-2);
  border-radius: 10px;
  padding: 14px 16px;
  cursor: pointer;
  display: flex; flex-direction: column; gap: 6px;
  text-align: left;
  font-family: inherit;
  transition: border-color 0.12s, background 0.12s;
}
.set-mode-card:hover { background: var(--paper); border-color: var(--ink-faint); }
.set-mode-card.is-on  { background: var(--paper); border-color: var(--ink); }
.set-mode-card-name {
  font-size: 0.95rem; color: var(--ink); font-weight: 600;
}
.set-mode-card-desc {
  font-size: 0.82rem; color: var(--ink-mute); line-height: 1.45;
}
.set-mode-card-preview {
  font-family: 'JetBrains Mono', 'IBM Plex Mono', monospace;
  font-size: 0.7rem;
  color: var(--ink-faint);
  letter-spacing: 0.02em;
  margin-top: 4px;
  padding-top: 8px;
  border-top: 1px dashed var(--hairline);
}

/* Per-day windows editor — repeating rows of label + from/to inputs,
   grouped by weekday. Lifts the visual rhythm from .set-hours-row and
   the dashed-button pattern from .set-add-row. */
.set-windows-block {
  margin-bottom: 8px;
}
.set-windows-editor {
  display: flex; flex-direction: column;
  gap: 0;
  border: 1px solid var(--hairline);
  border-radius: 10px;
  overflow: hidden;
}
.set-windows-day {
  padding: 12px 14px;
}
.set-windows-day + .set-windows-day { border-top: 1px solid var(--hairline); }
.set-windows-day-name {
  font-family: 'JetBrains Mono', 'IBM Plex Mono', monospace;
  font-size: 0.6rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--ink-mute);
  font-weight: 600;
  margin-bottom: 8px;
}
.set-windows-day-list {
  display: flex; flex-direction: column;
  gap: 6px;
}
.set-window-row {
  display: grid;
  grid-template-columns: 1fr 100px 18px 100px 28px;
  gap: 8px;
  align-items: center;
}
.set-window-row .set-window-label {
  font-size: 0.86rem;
}
.set-windows-add {
  margin-top: 8px;
  width: 100%;
  background: transparent;
  border: 1px dashed var(--hairline-2);
  color: var(--ink-mute);
  font-family: inherit;
  font-size: 0.8rem;
  padding: 7px 12px;
  border-radius: 8px;
  cursor: pointer;
  text-align: center;
}
.set-windows-add:hover { background: var(--cream-2); color: var(--ink); }
.set-windows-add:disabled { opacity: 0.4; cursor: not-allowed; }

@media (max-width: 540px) {
  .set-window-row {
    grid-template-columns: 1fr 1fr 28px;
    grid-template-areas: "label label x" "from sep to";
    row-gap: 6px;
  }
  .set-window-row .set-window-label { grid-area: label; }
  .set-window-row .set-hours-sep    { grid-area: sep; }
}

.set-shell {
  display: grid;
  grid-template-columns: 180px minmax(0, 1fr);
  /* Row 1 = "Settings" header spanning both columns; row 2 = rail + content. */
  grid-template-rows: auto 1fr;
  gap: 18px 40px;
  align-items: start;
  /* Flush-left layout (Claude-style). 32px left gutter from the first
     sidebar's right edge; 48px right gutter so cards don't kiss the
     viewport edge. */
  max-width: none;
  margin: 0;
  padding: 28px 48px 96px 32px;
}
.set-shell-head { grid-column: 1 / -1; }
.set-shell-title {
  font-family: 'Geist', 'Inter Tight', 'Inter', sans-serif;
  font-size: 1.75rem;
  font-weight: 600;
  color: var(--ink);
  letter-spacing: -0.02em;
  margin: 0;
  line-height: 1.15;
}
@media (max-width: 1024px) {
  .set-shell {
    grid-template-columns: 180px minmax(0, 1fr);
    gap: 14px 32px;
    padding: 24px 32px 96px 24px;
  }
}
@media (max-width: 900px) {
  .set-shell {
    grid-template-columns: 1fr;
    gap: 10px 0;
    padding: 18px 18px 64px;
  }
  .set-shell-title { font-size: 1.4rem; }
}

.set-rail {
  position: sticky;
  top: 18px;
  display: flex;
  flex-direction: column;
  padding: 4px 0;
  max-height: calc(100vh - 36px);
  overflow-y: auto;
  scrollbar-width: thin;
}
@media (max-width: 900px) {
  /* === MOBILE SETTINGS RAIL === Restyled as a horizontal tab strip,
     matching the old "Settings mobile: clean tab strips + scrollbar" pattern.
     Desktop sidebar layout above 900px is untouched. */
  .set-rail {
    position: sticky;
    top: 56px;                                  /* sit just below the topbar */
    z-index: 5;
    flex-direction: row;
    border-bottom: 1px solid var(--hairline);
    overflow-x: auto;
    overflow-y: hidden;
    gap: 0;
    max-height: none;
    margin: 0 -18px 14px;                       /* bleed past .set-shell padding to viewport edges */
    padding: 6px 18px 14px;
    /* Use --topband (the same warm cream the mobile topbar above
       uses) so the rail blends seamlessly into the chrome strip
       above instead of reading as a whiter inset band. */
    background: var(--topband);
    -webkit-overflow-scrolling: touch;
    overscroll-behavior-x: contain;
    touch-action: pan-x;
    scrollbar-width: none;                      /* Firefox */
    /* Soft fade on the right edge as a scroll affordance */
    -webkit-mask-image: linear-gradient(to right, #000 0, #000 calc(100% - 28px), transparent);
            mask-image: linear-gradient(to right, #000 0, #000 calc(100% - 28px), transparent);
  }
  .set-rail::-webkit-scrollbar { display: none; }  /* Safari/Chrome */
}
.set-rail-link {
  display: block;
  /* Airier padding to match Claude's settings rail rhythm (was 7px 10px). */
  padding: 9px 12px;
  font-size: 0.92rem;
  color: var(--ink-mute);
  text-decoration: none;
  border-radius: 8px;
  border: none;
  margin-left: 0;
  white-space: nowrap;
  cursor: pointer;
  transition: background 0.18s cubic-bezier(0.2, 0, 0, 1), color 0.18s cubic-bezier(0.2, 0, 0, 1);
}
/* Hover + active fills (Claude-style soft warm fill). Rail surface is
   transparent (= --cream page bg), so hover needs a slight overlay to
   be visible; active uses --cream-2 (clearly darker than the page).
   Active no longer bumps font-weight; selection reads through colour
   + fill delta alone so items don't shift width on click. */
.set-rail-link:hover     { background: rgba(31, 22, 17, 0.04); color: var(--ink); }
.set-rail-link.is-active { background: var(--cream-2); color: var(--ink); }
@media (max-width: 900px) {
  /* === MOBILE TAB === Each rail link styled as a real bottom-border tab
     so the strip reads as a tabbed nav, not a stack of pills. */
  .set-rail-link {
    padding: 8px 14px;
    border-radius: 8px;
    border-bottom: none;
    font-size: 0.875rem;
    min-height: 36px;
    display: inline-flex;
    align-items: center;
    flex: 0 0 auto;
    font-weight: 500;
    color: var(--ink-mute);
  }
  .set-rail-link:hover {
    background: rgba(31, 22, 17, 0.04);
    color: var(--ink);
  }
  .set-rail-link.is-active {
    background: rgba(31, 22, 17, 0.06);
    color: var(--ink);
    border-bottom: none;
    font-weight: 600;
  }
}
/* .set-rail-gap removed 2026-05-14 — the rail is now a single flat
   list with no visual separation between groups (founder preference). */
.set-content { min-width: 0; display: flex; flex-direction: column; gap: 16px; }
/* Chrome-less settings: no card borders, no padding-box. Each section is a
   long list of horizontal hairline-divided rows. */
.set-card, .set-block {
  background: transparent;
  border: 0;
  border-radius: 0;
  padding: 0;
  scroll-margin-top: 18px;
}
.set-card:hover, .set-block:hover { border-color: transparent; }
.set-section { padding: 0; border-bottom: 0; }
.set-section:last-child { border-bottom: 0; }
/* Visual separation between subsections inside a merged card. The first
   subsection has no top divider; every following subsection gets a hairline
   + extra spacing so the user can clearly see "this is a related-but-distinct
   group" within the same merged rail item. */
.set-card .set-section + .set-section,
.set-block .set-section + .set-section {
  margin-top: 32px;
  padding-top: 32px;
  border-top: 1px solid var(--hairline);
}
.set-section-title {
  font-family: 'Geist', 'Inter Tight', 'Inter', sans-serif;
  font-size: 0.95rem; font-weight: 600;
  color: var(--ink); margin: 0;
  padding: 32px 0 8px;
  letter-spacing: -0.005em;
  text-transform: none;
}
/* Cross-reference pill at the top of a Settings rules panel. Tells the
   tradie which form(s) the rules in this panel govern, with a deep-link
   each way. Sits above the first set-section-title so it reads as the
   panel's contextual breadcrumb. */
.set-affects-pill {
  display: inline-block;
  font-size: 0.78rem;
  color: var(--ink-mute, #6b7280);
  background: rgba(0,0,0,0.03);
  border: 1px solid rgba(0,0,0,0.06);
  border-radius: 999px;
  padding: 4px 12px;
  margin: 0 0 4px;
}
.set-affects-pill a {
  color: var(--ink, #1c1917);
  text-decoration: none;
  border-bottom: 1px solid rgba(0,0,0,0.18);
}
.set-affects-pill a:hover { border-bottom-color: rgba(0,0,0,0.5); }
/* Hairline-divided horizontal flex rows. Label + sub-description on the left,
   control on the right. */
.set-row {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 32px;
  padding: 18px 0;
  border-bottom: 1px solid var(--hairline);
  margin: 0;
}
.set-row:last-child { border-bottom: none; }
.set-row-label {
  flex: 1;
  min-width: 0;
  max-width: 360px;
}
.set-row-name {
  font-size: 0.92rem;
  font-weight: 500;
  color: var(--ink);
  margin-bottom: 4px;
}
.set-row-sub {
  font-size: 0.82rem;
  color: var(--ink-mute);
  line-height: 1.5;
}
.set-row-control {
  flex-shrink: 0;
  min-width: 280px;
  max-width: 360px;
  text-align: right;
}
.set-row-control .set-input,
.set-row-control .set-select,
.set-row-control .set-textarea {
  text-align: left;
}
@media (max-width: 760px) {
  .set-row { flex-direction: column; gap: 8px; }
  .set-row-control { min-width: 0; max-width: 100%; width: 100%; text-align: left; }
}
/* Legacy .set-row.is-2col still used inside templates for two-input groupings —
   it wraps two .set-row children. Strip the outer's row chrome; let inner rows hairline. */
.set-row.is-2col {
  display: block;
  padding: 0;
  border-bottom: 0;
  gap: 0;
}
.set-row.is-2col > .set-row { padding: 18px 0; border-bottom: 1px solid var(--hairline); }
.set-row.is-2col > .set-row:last-child { border-bottom: none; }
.set-field { display: flex; flex-direction: column; gap: 5px; min-width: 0; }
.set-label {
  font-family: 'Geist', 'Inter Tight', 'Inter', sans-serif;
  font-size: 13px; letter-spacing: normal; text-transform: none;
  color: var(--ink-mute); font-weight: 500;
}
.set-input, .set-select {
  background: var(--cream-2);
  border: 0;
  border-radius: 8px;
  padding: 8px 12px;
  font-family: inherit; font-size: 0.9rem;
  color: var(--ink); width: 100%;
  transition: background 0.12s, box-shadow 0.12s;
}
.set-input:focus, .set-select:focus {
  outline: 0; background: var(--cream-3);
}
.set-chips { display: flex; flex-wrap: wrap; gap: 6px; padding: 4px 0; }
.set-chip {
  display: inline-flex; align-items: center; gap: 6px;
  background: var(--cream-2);
  border: 1px solid var(--hairline-2);
  color: var(--ink);
  font-family: inherit; font-size: 0.8rem;
  padding: 4px 10px; border-radius: 999px;
}
.set-chip-x {
  font-size: 0.95rem; color: var(--ink-faint);
  cursor: pointer; line-height: 1; user-select: none;
}
.set-chip-x:hover { color: var(--ink-mute); }
.set-chip-add {
  background: transparent;
  border: 1px dashed var(--hairline-2);
  color: var(--ink-mute);
  font-family: inherit; font-size: 0.8rem;
  padding: 4px 11px; border-radius: 999px;
  cursor: pointer;
}
.set-chip-add:hover { background: var(--cream-2); color: var(--ink); }
.set-pill {
  display: inline-flex; align-items: center; gap: 6px;
  font-family: 'JetBrains Mono', monospace;
  font-size: 0.56rem; letter-spacing: 0.16em; text-transform: uppercase;
  font-weight: 600;
  color: var(--green); background: var(--green-soft);
  padding: 3px 8px; border-radius: 5px;
  margin-top: 4px; align-self: flex-start;
}
.set-pill::before {
  content: ''; width: 5px; height: 5px;
  border-radius: 50%; background: var(--green);
}
.set-pill.is-warn {
  color: var(--accent-orange, #D57529);
  background: rgba(213, 117, 41, 0.12);
}
.set-pill.is-warn::before { background: var(--accent-orange, #D57529); }
.set-pill.is-mute {
  color: var(--ink-mute);
  background: rgba(0, 0, 0, 0.05);
}
.set-pill.is-mute::before { background: var(--ink-mute); }
.set-pill.is-inline {
  margin-top: 0; margin-left: 8px; vertical-align: middle;
  align-self: center;
}
/* ── Plan & billing redesign ────────────────────────────────────────
   Sectioned layout, no dividers — whitespace only. Floating line-art
   icon (no card). Bordered ghost CTAs except the single red filled
   Cancel button. Matches Anthropic-billing aesthetic on warm-stone
   tokens.                                                            */
/* Two-column header: current plan (left) + status (right, free-tier only).
   Hydrator adds .is-single-col when plan !== free so the left card spans
   the full width on paid tiers. */
.set-billing-header {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: 14px;
  padding: 4px 0 24px;
  border-bottom: 1px solid var(--hairline);
}
.set-billing-header.is-single-col {
  grid-template-columns: minmax(0, 1fr);
}
.set-billing-header-card {
  padding: 18px 20px;
  background: var(--paper, #FBFBFB);
  border: 1px solid var(--hairline, rgba(31,22,17,0.08));
  border-radius: 12px;
  display: flex; flex-direction: column; gap: 12px;
}
.set-billing-header-card--plan {
  flex-direction: row;
  align-items: center; justify-content: space-between;
  gap: 16px;
}
.set-billing-header-card-body {
  display: flex; flex-direction: column; gap: 3px;
  min-width: 0; flex: 1;
}
.set-billing-header-plan {
  font-family: 'Geist', 'Inter Tight', 'Inter', sans-serif;
  font-size: 1.4rem; font-weight: 600; color: var(--ink);
  letter-spacing: -0.012em; line-height: 1.18; margin: 0;
}
.set-billing-header-tagline {
  font-size: 0.96rem; color: var(--ink); margin: 4px 0 0;
  line-height: 1.45;
}
.set-billing-header-sub {
  font-size: 0.88rem; color: var(--ink-mute); margin: 0;
}
.set-billing-header-sub.is-warn { color: var(--accent-orange, #D57529); }
/* Status card sub-states (free tier only): default = credits + bar,
   warn = out-of-credits + upgrade CTA. */
.set-billing-status-title {
  font-family: 'Geist', 'Inter Tight', 'Inter', sans-serif;
  font-size: 0.95rem; font-weight: 600; color: var(--ink);
  margin: 0 0 4px; letter-spacing: -0.005em;
}
.set-billing-status-title.is-warn { color: var(--orange-deep, #B8420F); }
.set-billing-status-warn { display: flex; flex-direction: column; gap: 10px; }
.set-billing-status-warn-sub {
  margin: 0; font-size: 0.9rem; line-height: 1.5; color: var(--ink-mute);
  max-width: 44ch;
}

.set-billing-section {
  padding: 28px 0;
  border-bottom: 1px solid var(--hairline);
}
.set-billing-section:last-of-type { border-bottom: 0; }
.set-billing-section-title {
  font-family: 'Geist', 'Inter Tight', 'Inter', sans-serif;
  font-size: 0.98rem; font-weight: 600; color: var(--ink);
  margin: 0 0 18px; letter-spacing: -0.005em;
}
.set-billing-row {
  display: flex; align-items: center; justify-content: space-between;
  gap: 16px; flex-wrap: wrap;
}
/* Free-tier credit display. Numbers are large + readable; bar is a thin
   warm-stone progress strip. No emojis, no greens — pure tradie tradesman
   stone palette per memory feedback rules. */
.set-billing-credits { display: flex; flex-direction: column; gap: 10px; }
.set-billing-credits-numbers {
  display: flex; align-items: baseline; gap: 8px;
  font-family: 'Geist', 'Inter Tight', sans-serif;
}
.set-billing-credits-remaining {
  font-size: 1.85rem; font-weight: 600; color: var(--ink);
  letter-spacing: -0.024em; line-height: 1;
}
.set-billing-credits-total { font-size: 0.95rem; color: var(--ink-mute); }
.set-billing-credits-bar {
  position: relative; height: 6px; border-radius: 999px;
  background: var(--cream-2, #F0F0F0);
  overflow: hidden;
}
.set-billing-credits-bar-fill {
  position: absolute; left: 0; top: 0; bottom: 0;
  background: var(--orange, #D9541E);
  width: 100%;
  border-radius: inherit;
  transition: width 0.32s cubic-bezier(0.2, 0.9, 0.3, 1.0);
}
.set-billing-credits-help {
  margin: 0; font-size: 0.86rem; line-height: 1.5;
  color: var(--ink-mute);
  max-width: 56ch;
}
/* Two-card upgrade row. Pro card has the warm-orange accent so it visually
   draws the eye, matching the pricing page Most-Popular treatment. */
.set-billing-upgrade-row {
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 14px;
}
@media (max-width: 720px) {
  .set-billing-upgrade-row { grid-template-columns: 1fr; }
}
.set-billing-upgrade-card {
  display: flex; flex-direction: column; gap: 8px;
  padding: 18px 20px;
  background: var(--paper, #FBFBFB);
  border: 1px solid var(--hairline, rgba(31,22,17,0.08));
  border-radius: 12px;
  text-decoration: none; color: inherit;
  transition: transform 0.2s ease, border-color 0.2s ease, box-shadow 0.2s ease;
}
.set-billing-upgrade-card:hover {
  transform: translateY(-2px);
  border-color: var(--hairline-2, rgba(31,22,17,0.14));
  box-shadow: 0 1px 2px rgba(31,22,17,0.05), 0 18px 36px -16px rgba(31,22,17,0.12);
}
.set-billing-upgrade-card--pro {
  border-color: rgba(217, 84, 30, 0.32);
  background: linear-gradient(180deg, rgba(217,84,30,0.04), transparent 60%), var(--paper, #FBFBFB);
}
.set-billing-upgrade-card-head {
  display: flex; align-items: baseline; justify-content: space-between; gap: 12px;
}
.set-billing-upgrade-card-name {
  font-family: 'Geist', 'Inter Tight', sans-serif;
  font-size: 1.05rem; font-weight: 600; color: var(--ink);
}
.set-billing-upgrade-card-price {
  font-family: 'Geist', 'Inter Tight', sans-serif;
  font-size: 0.92rem; font-weight: 500; color: var(--ink-mute);
}
.set-billing-upgrade-card-sub {
  margin: 0; font-size: 0.9rem; line-height: 1.5; color: var(--ink-mute);
}
.set-billing-upgrade-card-cta {
  margin-top: 6px;
  font-family: 'Geist', 'Inter Tight', sans-serif;
  font-size: 0.88rem; font-weight: 500;
  color: var(--orange-deep, #B8420F);
}
.set-billing-upgrade-card--pro .set-billing-upgrade-card-cta { color: var(--orange, #D9541E); }

.set-billing-pay {
  display: flex; align-items: center; gap: 12px; min-width: 0;
}
.set-billing-pay-icon {
  width: 32px; height: 22px; border-radius: 4px;
  background: var(--cream, #FAFAFA);
  border: 1px solid var(--hairline-2, rgba(31,22,17,0.14));
  display: inline-flex; align-items: center; justify-content: center;
  color: var(--ink-mute); flex-shrink: 0;
  overflow: hidden;
}
.set-billing-pay-icon--visa     { background: #1A1F71; border-color: #1A1F71; color: #fff; }
.set-billing-pay-icon--amex     { background: #006FCF; border-color: #006FCF; color: #fff; }
.set-billing-pay-icon--mc       { background: #fff; border-color: var(--hairline-2, rgba(31,22,17,0.14)); }
.set-billing-pay-icon--link     { background: #00D924; border-color: #00D924; color: #1F1611; }
.set-billing-pay-icon-text {
  font-family: 'Geist', 'Inter Tight', 'Inter', sans-serif;
  font-weight: 800; font-size: 0.56rem; letter-spacing: 0.06em;
  line-height: 1;
}
.set-billing-pay-icon-mc-dots {
  display: inline-flex; align-items: center;
}
.set-billing-pay-icon-mc-dots span {
  width: 11px; height: 11px; border-radius: 50%; display: inline-block;
}
.set-billing-pay-icon-mc-dots span:first-child {
  background: #EB001B;
}
.set-billing-pay-icon-mc-dots span:last-child {
  background: #F79E1B; margin-left: -4px; opacity: 0.92;
}
.set-billing-pay-text {
  font-size: 0.94rem; color: var(--ink);
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum" 1, "lnum" 1;
}

/* Ghost (bordered) button — canonical pattern from
   landing-frontier.html .btn-ghost: --hairline-2 border, ink hover. */
.set-btn-ghost {
  display: inline-flex; align-items: center; justify-content: center;
  font-family: 'Geist', 'Inter Tight', 'Inter', sans-serif;
  font-size: 0.88rem; font-weight: 500; color: var(--ink);
  background: #fff;
  border: 1px solid var(--hairline-2, rgba(31,22,17,0.14));
  border-radius: 6px; padding: 8px 16px;
  cursor: pointer; transition: border-color .12s ease, background .12s ease;
  white-space: nowrap;
  box-shadow: 0 1px 0 rgba(255,255,255,0.4) inset;
}
.set-btn-ghost:hover  { border-color: var(--ink); background: rgba(255,255,255,0.6); }
.set-btn-ghost:disabled { opacity: 0.55; cursor: not-allowed; }

/* Warm primary — orange-filled CTA. Used for upgrade flows
   (out-of-credits, add-payment-method). Sits alongside the bordered
   ghost button + filled danger as the third button shape. */
.set-btn-primary-warm {
  display: inline-flex; align-items: center; justify-content: center;
  font-family: 'Geist', 'Inter Tight', 'Inter', sans-serif;
  font-size: 0.9rem; font-weight: 500; color: #fff;
  background: var(--orange, #D9541E);
  border: 1px solid var(--orange, #D9541E);
  border-radius: 6px; padding: 9px 18px;
  cursor: pointer; transition: background .12s ease, border-color .12s ease;
  white-space: nowrap;
  text-decoration: none;
  align-self: flex-start;
}
.set-btn-primary-warm:hover {
  background: var(--orange-deep, #B8420F);
  border-color: var(--orange-deep, #B8420F);
}
.set-btn-primary-warm:disabled { opacity: 0.55; cursor: not-allowed; }

/* No-card payment sub-state — explicit "Add a payment method" affordance
   when /api/billing/card returns no last4. Replaces the previous "—"
   placeholder that read as broken. */
.set-billing-payment-none {
  display: flex; flex-direction: column; gap: 12px;
  align-items: flex-start;
}
.set-billing-payment-none-text {
  margin: 0; font-size: 0.92rem; line-height: 1.5;
  color: var(--ink-mute); max-width: 60ch;
}

/* Filled danger — the only red filled button on the page. Cancel
   subscription. Warm red rather than primary-bright. */
.set-btn-danger-filled {
  display: inline-flex; align-items: center; justify-content: center;
  font-family: 'Geist', 'Inter Tight', 'Inter', sans-serif;
  font-size: 0.88rem; font-weight: 500; color: #fff;
  background: #B8421F;
  border: 1px solid #B8421F;
  border-radius: 6px; padding: 8px 18px;
  cursor: pointer; transition: background .12s ease;
  white-space: nowrap;
}
.set-btn-danger-filled:hover { background: #9A361A; border-color: #9A361A; }
.set-btn-danger-filled:disabled { opacity: 0.55; cursor: not-allowed; }

/* Invoices table — hairline-separated rows, generous spacing. */
.set-billing-invoices { display: flex; flex-direction: column; }
.set-invoice-grid {
  display: grid;
  grid-template-columns: minmax(110px, 1.2fr) minmax(90px, 1fr) minmax(70px, 0.8fr) auto;
  align-items: center; gap: 14px;
  padding: 11px 0;
  border-bottom: 1px solid var(--hairline);
  font-size: 0.92rem;
}
.set-invoice-grid:last-child { border-bottom: 0; }
.set-invoice-grid--head {
  padding: 2px 0 11px;
  font-family: 'Geist', 'Inter Tight', 'Inter', sans-serif;
  font-size: 0.78rem; font-weight: 500;
  color: var(--ink-mute); letter-spacing: 0;
  border-bottom: 1px solid var(--hairline);
}
.set-invoice-date {
  color: var(--ink);
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum" 1, "lnum" 1;
}
.set-invoice-amount {
  color: var(--ink); font-weight: 500;
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum" 1, "lnum" 1;
}
.set-invoice-status { color: var(--ink); }
.set-invoice-link {
  font-size: 0.88rem; color: var(--ink);
  text-decoration: underline; text-decoration-thickness: 1px;
  text-underline-offset: 3px;
  transition: opacity .12s ease;
  justify-self: end;
}
.set-invoice-link:hover { opacity: 0.7; }
.set-invoice-empty {
  padding: 14px 0; color: var(--ink-mute);
  font-size: 0.9rem;
}

@media (max-width: 720px) {
  .set-billing-header {
    grid-template-columns: minmax(0, 1fr);
    row-gap: 12px;
  }
  .set-billing-header-card--plan {
    flex-direction: column;
    align-items: flex-start;
  }
  .set-billing-header-card--plan .set-btn-ghost { align-self: flex-start; }
}
@media (max-width: 640px) {
  .set-invoice-grid { grid-template-columns: 1fr auto; gap: 6px 14px; }
  .set-invoice-grid--head { display: none; }
  .set-invoice-amount { grid-column: 2; text-align: right; }
}

/* ── Stacked form field block ──────────────────────────────────────
   Label above, input below, full-width up to 480px max. Hairline
   between blocks. Replaces .set-row "label-left + input-right-fixed-
   width" pattern on tabs that benefit from a cleaner vertical
   rhythm (Business identity, etc.).                               */
.set-stack {
  padding: 20px 0;
  border-bottom: 1px solid var(--hairline);
}
.set-stack:last-child { border-bottom: 0; }
.set-stack-label {
  display: block;
  font-family: 'Geist', 'Inter Tight', 'Inter', sans-serif;
  font-size: 0.86rem; font-weight: 500;
  color: var(--ink-mute);
  margin: 0 0 10px;
}
.set-stack > .set-input,
.set-stack > .set-select {
  width: 100%; max-width: 480px;
}
.set-stack-help {
  display: block;
  font-size: 0.82rem; color: var(--ink-mute);
  margin-top: 8px; max-width: 480px;
}
.set-stack-2col {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 20px;
  padding: 20px 0;
  border-bottom: 1px solid var(--hairline);
}
.set-stack-2col:last-child { border-bottom: 0; }
.set-stack-cell { display: flex; flex-direction: column; }
.set-stack-cell .set-stack-label { margin-bottom: 10px; }
.set-stack-cell .set-input,
.set-stack-cell .set-select { width: 100%; }
@media (max-width: 640px) {
  .set-stack-2col { grid-template-columns: 1fr; gap: 16px; }
}
.set-logo-row {
  display: flex; align-items: center; gap: 14px; flex-wrap: wrap;
}
.set-logo-preview {
  width: 44px; height: 44px; border-radius: 8px;
  background: var(--ink, #1F1611);
  display: flex; align-items: center; justify-content: center;
  color: var(--paper, #fff); font-weight: 600; font-size: 1rem;
  overflow: hidden; flex-shrink: 0;
}
.set-logo-preview img { width: 100%; height: 100%; object-fit: cover; display: block; }
.set-logo-help { font-size: 0.82rem; color: var(--ink-mute); }
.set-link {
  background: transparent; border: 0;
  color: var(--ink-mute); font-family: inherit; font-size: 0.84rem;
  cursor: pointer; padding: 0;
  text-decoration: underline;
  text-decoration-color: var(--hairline-2);
  text-underline-offset: 3px;
}
.set-link:hover { color: var(--ink); text-decoration-color: var(--ink-mute); }
.set-account-row {
  display: flex; align-items: center; justify-content: space-between;
  gap: 14px; flex-wrap: wrap;
}
.set-account-row + .set-account-row {
  margin-top: 12px; padding-top: 12px;
  border-top: 1px solid var(--hairline);
}
.set-account-label {
  font-family: 'Geist', 'Inter Tight', 'Inter', sans-serif;
  font-size: 13px; letter-spacing: normal; text-transform: none;
  color: var(--ink-mute); font-weight: 500;
  margin-bottom: 3px;
}
.set-account-val { font-size: 0.9rem; color: var(--ink); }
/* Sticky save bar at the bottom of every settings tab. Inline-style
   was stripped from the renderer; chrome lives here so it can be
   tuned without touching JS. Mobile media block in dashboard-v2.css
   stacks the bar vertically and adds horizontal margin so it sits
   inside the page padding. */
.set-actions {
  position: sticky;
  bottom: 12px;
  background: rgba(255, 255, 255, 0.96);
  -webkit-backdrop-filter: blur(6px);
          backdrop-filter: blur(6px);
  border: 1px solid var(--hairline-2);
  border-radius: 12px;
  padding: 10px 14px;
  box-shadow: 0 4px 12px rgba(31, 22, 17, 0.06);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin: 4px 0 0;
}
[data-theme="dark"] .set-actions {
  background: rgba(20, 16, 14, 0.96);
}
.btn-primary.is-disabled, .btn-ghost.is-disabled { opacity: 0.55; cursor: not-allowed; }
.btn-primary.is-disabled:hover { background: var(--ink); border-color: var(--ink); }
.btn-ghost.is-disabled:hover   { background: transparent; border-color: var(--hairline-2); }
.set-textarea {
  background: var(--cream-2);
  border: 0;
  border-radius: 8px;
  padding: 10px 12px;
  font-family: inherit; font-size: 0.9rem;
  color: var(--ink); width: 100%;
  resize: vertical;
  min-height: 84px;
  line-height: 1.5;
  transition: background 0.12s;
}
.set-textarea:focus { outline: 0; background: var(--cream-3); }
.set-help { font-size: 0.78rem; color: var(--ink-mute); margin-top: 2px; line-height: 1.5; }
.set-help.is-warn { color: var(--orange-deep); }
.set-switch {
  position: relative;
  display: inline-block;
  width: 38px; height: 22px;
  flex-shrink: 0;
}
.set-switch input { opacity: 0; width: 0; height: 0; }
.set-switch-slider {
  position: absolute; cursor: pointer; inset: 0;
  background: var(--cream-3);
  border-radius: 999px;
  transition: background 0.18s;
}
.set-switch-slider::before {
  content: ''; position: absolute;
  height: 16px; width: 16px;
  left: 3px; top: 3px;
  background: #fff; border-radius: 50%;
  transition: transform 0.18s;
  box-shadow: 0 1px 2px rgba(31, 22, 17, 0.2);
}
.set-switch input:checked + .set-switch-slider { background: var(--blue); }
.set-switch input:checked + .set-switch-slider::before { transform: translateX(16px); }
/* Usage progress bars + appearance toggle (Profile/Preferences/Usage sections) */
.usage-row { display: flex; flex-direction: column; gap: 6px; }
.usage-bar {
  height: 4px;
  background: var(--cream-3, rgba(31, 22, 17, 0.08));
  border-radius: 999px;
  overflow: hidden;
}
.usage-bar-fill {
  height: 100%;
  background: var(--ink, #1F1611);
  border-radius: 999px;
  transition: width 0.4s cubic-bezier(0.2, 0, 0, 1);
}
.usage-meta {
  font-family: 'JetBrains Mono', monospace;
  font-size: 0.72rem;
  color: var(--ink-mute, #6B5A4C);
  letter-spacing: 0.04em;
  font-variant-numeric: tabular-nums;
}
.appearance-toggle {
  display: inline-flex;
  background: var(--cream-2);
  border-radius: 8px;
  padding: 3px;
  gap: 2px;
}
.appearance-toggle button {
  background: transparent;
  border: 0;
  width: 32px; height: 28px;
  border-radius: 6px;
  display: inline-flex; align-items: center; justify-content: center;
  color: var(--ink-mute);
  cursor: pointer;
  transition: background 0.18s cubic-bezier(0.2, 0, 0, 1), color 0.18s cubic-bezier(0.2, 0, 0, 1);
}
.appearance-toggle button:hover { color: var(--ink); }
.appearance-toggle button.is-on {
  background: var(--paper, #fff);
  color: var(--ink);
  box-shadow: 0 1px 2px rgba(31, 22, 17, 0.08);
}
.appearance-toggle button svg { width: 14px; height: 14px; }
/* Lead capture: segmented CTA chooser (mirrors .appearance-toggle structure). */
.cta-toggle {
  display: inline-flex;
  background: var(--cream-2);
  border-radius: 8px;
  padding: 3px;
  gap: 2px;
}
.cta-toggle button {
  background: transparent; border: 0;
  padding: 6px 12px;
  font-family: inherit; font-size: 0.85rem;
  color: var(--ink-mute);
  border-radius: 6px;
  cursor: pointer;
  transition: all 0.18s cubic-bezier(0.2, 0, 0, 1);
}
.cta-toggle button:hover { color: var(--ink); }
.cta-toggle button.is-on {
  background: var(--paper, #fff);
  color: var(--ink);
  font-weight: 500;
  box-shadow: 0 1px 2px rgba(31, 22, 17, 0.06);
}
/* Tier-only reveal: hidden by default, shown when body[data-tier] matches
   the block's data-plan attribute. Set by dashboard-v2.js after the
   data-plan reveal pass.

   We match data-plan with attribute-contains (~"=") OR substring (*=) so a
   block tagged data-plan="recovery,recovery-only" shows for both tiers and
   data-plan="builder" shows only on Builder. This keeps the lead-capture
   page Builder-tier-clean (email-only) and Recovery-tier-rich (SMS screener
   block visible) without either tier seeing the other tier's controls. */
.set-tier-only { display: none; }
body[data-tier="builder"]       .set-tier-only[data-plan*="builder"],
body[data-tier="recovery"]      .set-tier-only[data-plan*="recovery"],
body[data-tier="recovery-only"] .set-tier-only[data-plan*="recovery-only"] { display: block; }
.set-tier-pill {
  display: inline-flex; align-items: center; gap: 6px;
  font-family: 'JetBrains Mono', monospace;
  font-size: 0.6rem; letter-spacing: 0.16em; text-transform: uppercase;
  font-weight: 600;
  color: var(--orange);
  background: var(--orange-wash, rgba(217, 84, 30, 0.08));
  padding: 3px 8px;
  border-radius: 999px;
  margin-bottom: 10px;
}
.set-tier-divider {
  margin: 28px 0 18px;
  padding-top: 24px;
  border-top: 1px dashed var(--hairline-2);
}
.set-quiet-hours {
  display: inline-flex; align-items: center; gap: 8px;
}
.set-quiet-hours input[type="time"] {
  font-family: inherit;
}
.set-quiet-hours .qh-sep {
  color: var(--ink-mute);
  font-size: 0.85rem;
}
.set-avatar-circle {
  width: 44px; height: 44px;
  border-radius: 50%;
  background: var(--ink, #1F1611);
  color: var(--paper, #fff);
  display: inline-flex; align-items: center; justify-content: center;
  font-family: 'Geist', 'Inter Tight', 'Inter', sans-serif;
  font-weight: 600;
  font-size: 1.1rem;
  flex-shrink: 0;
}
.set-toggle-row {
  display: flex; align-items: flex-start;
  justify-content: space-between;
  gap: 16px; padding: 10px 0;
}
.set-toggle-row + .set-toggle-row { border-top: 1px solid var(--hairline); }
.set-toggle-text { flex: 1; min-width: 0; }
.set-toggle-name { font-size: 0.92rem; color: var(--ink); font-weight: 500; margin-bottom: 2px; }
.set-toggle-desc { font-size: 0.8rem; color: var(--ink-mute); line-height: 1.45; }
.set-hours-row {
  display: grid;
  grid-template-columns: 90px 1fr 14px 1fr 28px;
  gap: 10px; align-items: center;
  padding: 6px 0;
}
.set-hours-row + .set-hours-row { border-top: 1px solid var(--hairline); }
.set-hours-day { font-size: 0.88rem; color: var(--ink); font-weight: 500; }
.set-hours-sep { font-size: 0.78rem; color: var(--ink-faint); text-align: center; }
.set-hours-x {
  font-size: 0.86rem; color: var(--ink-faint);
  background: transparent; border: 0; cursor: pointer;
  padding: 2px 4px;
}
.set-hours-x:hover { color: var(--ink-mute); }
.set-hours-closed-row .set-hours-closed {
  color: var(--ink-faint); font-size: 0.84rem; font-style: italic;
  grid-column: 2 / 5;
}
.set-tier-row {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr 28px;
  gap: 10px; align-items: center;
  padding: 6px 0;
}
.set-tier-row + .set-tier-row { border-top: 1px solid var(--hairline); }
.set-tier-row-head {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr 28px;
  gap: 10px; padding: 6px 0;
  font-family: 'JetBrains Mono', monospace;
  font-size: 0.54rem; letter-spacing: 0.18em; text-transform: uppercase;
  color: var(--ink-faint); font-weight: 600;
  border-bottom: 1px solid var(--hairline);
}
.set-add-row {
  background: transparent;
  border: 1px dashed var(--hairline-2);
  color: var(--ink-mute);
  font-family: inherit; font-size: 0.84rem;
  padding: 8px 12px; border-radius: 8px;
  cursor: pointer;
  margin-top: 8px;
  width: 100%;
  text-align: left;
}
.set-add-row:hover { background: var(--cream-2); color: var(--ink); }
.set-tone-row { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; }
@media (max-width: 640px) { .set-tone-row { grid-template-columns: 1fr; } }
.set-tone-card {
  background: var(--cream);
  border: 1px solid var(--hairline-2);
  border-radius: 10px;
  padding: 10px 12px;
  cursor: pointer;
  display: flex; flex-direction: column; gap: 4px;
  transition: border-color 0.12s, background 0.12s;
}
.set-tone-card:hover { background: var(--paper); border-color: var(--ink-faint); }
.set-tone-card.is-on { background: var(--paper); border-color: var(--ink); }
.set-tone-name { font-size: 0.92rem; color: var(--ink); font-weight: 600; }
.set-tone-eg { font-size: 0.78rem; color: var(--ink-mute); line-height: 1.4; font-style: italic; }
.set-color-row { display: flex; align-items: center; gap: 12px; }
.set-color-sw {
  width: 36px; height: 36px;
  border-radius: 8px;
  border: 1px solid var(--hairline-2);
  flex-shrink: 0;
}
.set-danger {
  background: rgba(217, 84, 30, 0.04);
  border: 1px solid rgba(217, 84, 30, 0.18);
  border-radius: 10px;
  padding: 14px 16px;
  display: flex; align-items: center; justify-content: space-between;
  gap: 16px; flex-wrap: wrap;
}
.set-danger + .set-danger { margin-top: 10px; }
.set-danger-text strong { color: var(--orange-deep); font-weight: 600; }
.set-danger-text { font-size: 0.86rem; color: var(--ink); line-height: 1.45; max-width: 460px; }
.set-btn-danger {
  background: transparent;
  border: 1px solid var(--orange);
  color: var(--orange);
  font-family: inherit; font-size: 0.86rem; font-weight: 500;
  padding: 8px 14px; border-radius: 8px;
  cursor: pointer; flex-shrink: 0;
  transition: background 0.12s, color 0.12s;
}
.set-btn-danger:hover { background: var(--orange); color: #fff; }
.set-mini-intg {
  display: flex; flex-direction: column; gap: 4px;
}
.set-mini-intg-row {
  display: flex; justify-content: flex-start; align-items: center;
  gap: 12px;
  padding: 14px 0;
  font-size: 0.92rem;
}
.set-mini-intg-row + .set-mini-intg-row { border-top: 1px solid var(--hairline); }
.set-mini-intg-logo {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 28px;
  flex-shrink: 0;
}
.set-mini-intg-logo svg,
.set-mini-intg-logo img {
  display: block;
  max-width: 100%;
  max-height: 100%;
  object-fit: contain;
}
.set-mini-intg-text {
  flex: 1; min-width: 0;
  display: flex; flex-direction: column; gap: 2px;
}
.set-mini-intg-name { color: var(--ink); font-weight: 500; }
.set-mini-intg-sub {
  font-size: 0.78rem;
  color: var(--ink-faint);
  line-height: 1.3;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-weight: 400;
}
.set-mini-intg-sub:empty { display: none; }
/* Legacy mono caps status — kept for backwards compat but hidden;
   the CTA pill now conveys connection state directly. */
.set-mini-intg-status { display: none; }
.set-mini-intg-cta {
  display: inline-flex; align-items: center;
  flex-shrink: 0;
}
.set-mini-intg-connect,
.set-mini-intg-disconnect {
  font-family: inherit; font-size: 0.86rem; font-weight: 600;
  padding: 7px 14px; border-radius: 999px;
  text-decoration: none; cursor: pointer;
  letter-spacing: -0.005em;
  border: 1px solid var(--hairline);
  background: transparent;
  transition: background 0.12s, border-color 0.12s, color 0.12s;
  white-space: nowrap;
}
.set-mini-intg-connect {
  color: var(--cream, #FAFAFA);
  background: var(--ink, #1F1611);
  border-color: var(--ink, #1F1611);
}
.set-mini-intg-connect:hover {
  background: var(--ink-2, #2A1F17);
  color: var(--cream, #FAFAFA);
}
.set-mini-intg-disconnect {
  color: var(--ink-soft);
  background: transparent;
}
.set-mini-intg-disconnect:hover {
  color: var(--ink);
  background: rgba(27, 22, 16, 0.05);
}
.set-mini-intg-disconnect:disabled {
  opacity: 0.5; cursor: default;
}
.set-mini-intg-muted {
  font-size: 0.78rem;
  color: var(--ink-faint);
  font-weight: 500;
  letter-spacing: -0.005em;
}

/* Notifications */
.ntf-card {
  background: var(--paper);
  border: 1px solid var(--hairline);
  border-radius: var(--card-radius);
  padding: 12px var(--card-pad) 18px;
  transition: border-color 0.18s cubic-bezier(0.2, 0, 0, 1);
}
.ntf-card:hover { border-color: var(--hairline-2); }
.ntf-section {
  padding: 16px 0 10px;
  border-bottom: 1px solid var(--hairline);
}
.ntf-section:last-child { border-bottom: 0; }
.ntf-section-title {
  font-family: 'Geist', 'Inter Tight', 'Inter', sans-serif;
  font-size: 1.02rem; font-weight: 600;
  color: var(--ink); margin: 0 0 4px;
}
.ntf-head {
  display: grid;
  grid-template-columns: 1fr 64px 64px 64px;
  gap: 10px; padding: 10px 0;
  font-family: 'JetBrains Mono', monospace;
  font-size: 0.54rem; letter-spacing: 0.18em; text-transform: uppercase;
  color: var(--ink-faint); font-weight: 600;
  border-bottom: 1px solid var(--hairline);
}
.ntf-head span:not(:first-child) { text-align: center; }
.ntf-row {
  display: grid;
  grid-template-columns: 1fr 64px 64px 64px;
  gap: 10px; padding: 12px 0;
  align-items: center;
  border-bottom: 1px solid var(--hairline);
}
.ntf-row:last-child { border-bottom: 0; }
.ntf-row-name { font-size: 0.9rem; color: var(--ink); font-weight: 500; }
.ntf-row-cell { display: flex; align-items: center; justify-content: center; }
@media (max-width: 640px) {
  .ntf-head { display: none; }
  .ntf-row { grid-template-columns: 1fr; gap: 6px; padding: 14px 0; }
  .ntf-row-cell { justify-content: space-between; padding: 4px 0; }
  .ntf-row-cell::before {
    content: attr(data-channel);
    font-family: 'JetBrains Mono', monospace;
    font-size: 0.58rem; letter-spacing: 0.16em; text-transform: uppercase;
    color: var(--ink-faint); font-weight: 600;
  }
}
.ntf-toggle {
  width: 38px; height: 20px;
  background: var(--cream-2);
  border: 1px solid var(--hairline-2);
  border-radius: 999px;
  position: relative; cursor: pointer;
  transition: background 0.18s, border-color 0.18s;
  padding: 0;
}
.ntf-toggle::after {
  content: '';
  position: absolute; top: 1px; left: 1px;
  width: 16px; height: 16px;
  background: #fff;
  border-radius: 50%;
  box-shadow: 0 1px 2px rgba(31, 22, 17, 0.18);
  transition: transform 0.18s;
}
.ntf-toggle.is-on { background: var(--ink); border-color: var(--ink); }
.ntf-toggle.is-on::after { transform: translateX(18px); }
.ntf-toggle.is-na { opacity: 0.32; cursor: not-allowed; }

.ntf-quiet {
  background: var(--cream);
  border: 1px solid var(--hairline);
  border-radius: 12px;
  padding: 14px 18px;
  margin-top: 16px;
  display: flex; align-items: center; gap: 16px;
  flex-wrap: wrap;
}
.ntf-quiet-text { flex: 1 1 240px; }
.ntf-quiet-title {
  font-family: 'Geist', 'Inter Tight', 'Inter', sans-serif;
  font-size: 0.98rem; font-weight: 600;
  color: var(--ink);
}
.ntf-quiet-meta {
  font-family: 'JetBrains Mono', monospace;
  font-size: 0.58rem; letter-spacing: 0.14em; text-transform: uppercase;
  color: var(--ink-faint); margin-top: 3px;
}
.ntf-quiet-range {
  display: inline-flex; align-items: center; gap: 6px;
  font-family: 'JetBrains Mono', monospace;
  font-size: 0.74rem;
  background: var(--paper);
  border: 1px solid var(--hairline-2);
  border-radius: 8px;
  padding: 7px 12px;
  color: var(--ink); letter-spacing: 0.06em;
}

/* ============================================================================
   Job types page — list of per-job-type configuration cards
   ========================================================================== */
.jt-list { display: flex; flex-direction: column; gap: 12px; margin-top: 14px; }
.jt-card {
  background: var(--paper);
  border: 1px solid var(--hairline);
  border-radius: var(--card-radius);
  padding: var(--card-pad);
  display: grid;
  grid-template-columns: 44px minmax(0, 1fr) auto;
  grid-template-rows: auto auto auto auto;
  gap: 4px 14px;
  align-items: start;
  transition: border-color 0.18s cubic-bezier(0.2, 0, 0, 1), background 0.18s cubic-bezier(0.2, 0, 0, 1);
}
.jt-card:hover {
  border-color: var(--hairline-2);
}
.jt-card.is-fallback {
  background: transparent;
  border: 1px dashed var(--hairline-2);
}
.jt-icon {
  grid-row: 1 / 3;
  width: 44px; height: 44px;
  border-radius: 10px;
  background: var(--cream-2);
  display: inline-flex; align-items: center; justify-content: center;
  color: var(--ink-mute);
  flex: 0 0 auto;
}
.jt-icon svg { width: 22px; height: 22px; }
.jt-card.is-fallback .jt-icon { background: var(--cream-2); color: var(--ink-mute); }
.jt-head {
  grid-column: 2;
  grid-row: 1;
  min-width: 0;
  display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap;
}
.jt-name {
  font-family: 'Geist', 'Inter Tight', 'Inter', sans-serif;
  font-size: 1.06rem; font-weight: 600;
  color: var(--ink); letter-spacing: -0.01em;
  margin: 0;
}
.jt-pill {
  display: inline-flex; align-items: center; gap: 5px;
  font-family: 'JetBrains Mono', monospace;
  font-size: 0.56rem; letter-spacing: 0.14em; text-transform: uppercase;
  font-weight: 600;
  padding: 2px 7px;
  border-radius: 5px;
}
.jt-pill.is-auto    { background: var(--green-soft); color: var(--green); }
.jt-pill.is-manual  { background: var(--cream-2); color: var(--ink-mute); }
.jt-pill.is-after   { background: var(--cream-2); color: var(--ink-mute); }
.jt-pill.is-emerg   { background: var(--cream-2); color: var(--ink-mute); }

.jt-stats {
  grid-column: 2;
  grid-row: 2;
  display: flex; gap: 14px; flex-wrap: wrap;
  font-family: 'JetBrains Mono', monospace;
  font-size: 0.62rem; letter-spacing: 0.12em; text-transform: uppercase;
  color: var(--ink-faint); font-weight: 500;
  margin-top: 3px;
}
.jt-stats strong {
  color: var(--ink);
  font-weight: 700;
  letter-spacing: 0.04em;
}
.jt-stats .dot {
  display: inline-block; width: 3px; height: 3px;
  border-radius: 50%; background: var(--hairline-3);
  align-self: center;
}

.jt-actions {
  grid-column: 3;
  grid-row: 1 / 3;
  display: flex; gap: 6px; align-items: center;
  align-self: start;
}
.jt-action {
  display: inline-flex; align-items: center; justify-content: center;
  padding: 7px 11px;
  font-family: inherit; font-size: 0.78rem; font-weight: 500;
  border-radius: 8px;
  border: 1px solid var(--hairline-2);
  background: transparent; color: var(--ink);
  cursor: pointer; text-decoration: none;
  transition: background 0.12s, border-color 0.12s, color 0.12s;
}
.jt-action:hover { background: var(--cream-2); border-color: var(--hairline-3); }
.jt-action.is-quiet { color: var(--ink-mute); }
.jt-action.is-danger:hover { color: var(--orange); border-color: var(--orange-deep); }

.jt-fields {
  grid-column: 2 / 4;
  grid-row: 3;
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 10px;
  margin-top: 14px;
  padding-top: 14px;
  border-top: 1px solid var(--hairline);
}
@media (max-width: 760px) {
  .jt-fields { grid-template-columns: repeat(2, 1fr); }
}
.jt-field {
  display: flex; flex-direction: column; gap: 4px;
  min-width: 0;
}
.jt-field-label {
  font-family: 'JetBrains Mono', monospace;
  font-size: 0.56rem; letter-spacing: 0.14em; text-transform: uppercase;
  color: var(--ink-mute); font-weight: 600;
}
.jt-field-value {
  font-family: 'Geist', 'Inter Tight', 'Inter', sans-serif;
  font-size: 0.94rem; font-weight: 500;
  color: var(--ink);
  display: flex; align-items: center; gap: 8px;
  min-height: 26px;
}
.jt-field-value.is-toggle { gap: 10px; }

.jt-keywords {
  grid-column: 2 / 4;
  grid-row: 4;
  display: flex; align-items: center; gap: 10px;
  flex-wrap: wrap;
  margin-top: 12px;
}
.jt-keywords-label {
  font-family: 'JetBrains Mono', monospace;
  font-size: 0.56rem; letter-spacing: 0.14em; text-transform: uppercase;
  color: var(--ink-mute); font-weight: 600;
  flex: 0 0 auto;
}
.jt-keyword {
  background: var(--cream-2);
  border: 1px solid var(--hairline);
  border-radius: 999px;
  padding: 4px 11px;
  font-size: 0.78rem;
  color: var(--ink);
  font-family: 'JetBrains Mono', monospace;
  letter-spacing: 0.02em;
}
.jt-keyword.is-add {
  background: transparent;
  border-style: dashed;
  color: var(--ink-faint);
  cursor: pointer;
}
.jt-keyword.is-add:hover { color: var(--orange); border-color: var(--orange); }

/* Per-job-type direct-booking toggle + bookable-price row */
.jt-booking-row {
  grid-column: 2 / 4;
  grid-row: 5;
  border-top: 1px solid var(--hairline);
  margin-top: 12px;
  padding-top: 8px;
}
.jt-price-row {
  display: grid;
  grid-template-columns: 140px 120px 1fr;
  gap: 12px;
  align-items: center;
  padding: 8px 0 4px;
}
.jt-price-row[data-hidden] { display: none; }
.jt-price-row label {
  font-size: 0.85rem; color: var(--ink-mute);
}
.jt-price-meta {
  font-size: 0.78rem; color: var(--ink-faint);
}
.jt-status-pill {
  display: inline-flex; align-items: center; gap: 6px;
  font-family: 'JetBrains Mono', monospace;
  font-size: 0.58rem; letter-spacing: 0.14em; text-transform: uppercase;
  font-weight: 600;
  padding: 3px 8px; border-radius: 4px;
  margin-left: 8px;
}
.jt-status-pill.is-bookable { background: var(--green-soft); color: var(--green); }
.jt-status-pill.is-quote { background: var(--cream-3); color: var(--ink-mute); }


/* ==========================================================================
   AI builder split-pane styles — chat pane (left) + preview pane (right).
   Used by renderAiBuilder. Companion .builder-* rules also live in
   public/dashboard-v2.css.
   ========================================================================== */
.builder-preview-body {
  background: linear-gradient(135deg, oklch(15% 0.018 60) 0%, oklch(22% 0.02 38) 100%) !important;
  color: oklch(96% 0.02 80);
}
/* When the preview-body contains the editable template iframe, strip
   padding + centered layout so the iframe takes the full pane (same
   treatment as the published live-site iframe). The template iframe
   itself paints its own cream background, so the preview-body's dark
   linear-gradient stays hidden behind it. */
.builder-preview-body:has(iframe[data-builder-template-iframe]) {
  padding: 0 !important;
  background: var(--cream) !important;
  align-items: stretch !important;
  justify-content: stretch !important;
  display: block !important;
}
.builder-template-iframe {
  width: 100%;
  height: 100%;
  min-height: 100%;
  border: 0;
  display: block;
  background: var(--cream);
}
/* 2026-05-24: in cards-view the preview iframe is a non-interactive
   thumbnail — taps go to the card body for the zoom-back gesture,
   and the iframe's own swipe-forwarder must NOT fire (it would
   detect horizontal swipes on V5 content and postMessage them up,
   even though navSingleMode discards them in cards-view, the touches
   still scroll the iframe content which the founder reported as
   "I can swipe on the website page from the card view"). */
body.is-builder-cards-view .builder-template-iframe {
  pointer-events: none !important;
}
/* Sections-pane in single-mode: section-card list. Each .builder-
   sections-pane__item is a two-line card (label + preview snippet).
   Padding clears the 52px topbar at top + iOS Safari URL bar at
   bottom. Cards have hover lift + amber accent on tap (founder iter
   surface 2026-05-23). */
/* 2026-05-24 v2: the active-pane gate is restored (dropping it
   broke chat-mode containment — sections-pane styling started
   rendering in the chat view because the wrap is in flow even when
   inactive). Add a parallel is-builder-sliding selector so the
   styles ALSO apply during a pane slide, when the wrap is force-
   shown but the attribute still points at the from-pane. */
body:not(.is-builder-cards-view)[data-builder-active-pane="sections"] .builder-sections-pane__body,
body.is-builder-sliding:not(.is-builder-cards-view) .builder-sections-pane__body {
  padding: max(64px, env(safe-area-inset-top) + 64px) 16px max(env(safe-area-inset-bottom) + 90px, 110px) !important;
  background: var(--cream) !important;
}
body:not(.is-builder-cards-view)[data-builder-active-pane="sections"] .builder-sections-pane__item,
body.is-builder-sliding:not(.is-builder-cards-view) .builder-sections-pane__item {
  display: flex !important;
  align-items: center;
  justify-content: space-between;
  gap: 14px;
  padding: 14px 16px !important;
  border: 1px solid var(--hairline) !important;
  border-radius: 12px !important;
  background: #fff !important;
  transition: border-color 0.15s, box-shadow 0.15s;
}
body:not(.is-builder-cards-view)[data-builder-active-pane="sections"] .builder-sections-pane__item:hover,
body.is-builder-sliding:not(.is-builder-cards-view) .builder-sections-pane__item:hover {
  border-color: var(--ink-faint) !important;
}
/* 2026-05-24 dropdown previews — each section row collapses by
   default to [label + axis + A/B/C picker + chevron]. Tap the row
   to expand a clean iframe preview of just that section beneath
   the row. Only one row expanded at a time (siblings auto-collapse).
   Edits still happen in the main Preview pane (the "Open in
   preview" link inside the dropdown jumps + enters edit mode).
   is-builder-sliding selector duplicated below so the items keep
   their bg/border/radius DURING the slide too — otherwise the
   destination cards animate in without their styling and snap into
   look-correct only at slide-end. */
body:not(.is-builder-cards-view)[data-builder-active-pane="sections"] .builder-sections-pane__item,
body.is-builder-sliding:not(.is-builder-cards-view) .builder-sections-pane__item {
  display: block !important;
  padding: 0 !important;
  overflow: hidden;
  background: #fff !important;
  transition: box-shadow 0.18s ease;
}
body:not(.is-builder-cards-view)[data-builder-active-pane="sections"] .builder-sections-pane__item.is-open,
body.is-builder-sliding:not(.is-builder-cards-view) .builder-sections-pane__item.is-open {
  box-shadow: 0 8px 24px -8px rgba(31, 22, 17, 0.12);
}
.builder-sections-pane__item-row {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 13px 14px;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  user-select: none;
  background: transparent;
  border: 0;
  width: 100%;
  font: inherit;
}
.builder-sections-pane__item-row:hover { background: rgba(31, 22, 17, 0.02); }
.builder-sections-pane__item-main {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
  flex: 1 1 auto;
  text-align: left;
}
.builder-sections-pane__item-chev {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 24px;
  height: 24px;
  color: var(--ink-mute, #6B5A4C);
  flex-shrink: 0;
  transition: transform 0.22s cubic-bezier(0.22, 1, 0.36, 1), color 0.15s;
}
.builder-sections-pane__item.is-open .builder-sections-pane__item-chev {
  transform: rotate(180deg);
  color: var(--accent, #FF5B00);
}

/* The dropdown preview frame — wraps an iframe of just this section
   (template-v5-variants.html?only=KEY). Iframe height is set via
   the postMessage height-back so it fits its section exactly, but
   capped at 360px for the list to stay scannable; taller sections
   get a fade-to-white at the bottom hinting "more in the preview". */
.builder-sections-pane__item-preview-drop {
  border-top: 1px solid var(--hairline, rgba(31,22,17,0.08));
  background: var(--paper-2, #F4F6FA);
  padding: 14px;
}
.builder-sections-pane__item-preview-drop[hidden] { display: none; }
.builder-sections-pane__item-preview-frame {
  position: relative;
  background: #fff;
  border-radius: 8px;
  border: 1px solid var(--rule, #DEE3EC);
  overflow: hidden;
  min-height: 120px;
  max-height: 360px;
}
.builder-sections-pane__item-preview-frame::after {
  /* Fade-to-white at the bottom — only visible when the iframe
     overflows the 360px cap. */
  content: '';
  position: absolute;
  left: 0; right: 0; bottom: 0;
  height: 56px;
  background: linear-gradient(180deg, rgba(255,255,255,0) 0%, rgba(255,255,255,0.92) 92%);
  pointer-events: none;
  border-bottom-left-radius: 8px;
  border-bottom-right-radius: 8px;
}
.builder-sections-pane__item-preview-frame iframe {
  display: block;
  width: 100%;
  min-height: 120px;
  border: 0;
  pointer-events: none;
  background: #fff;
}
.builder-sections-pane__item-edit {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  width: 100%;
  margin-top: 12px;
  padding: 11px 14px;
  background: transparent;
  color: var(--ink, #16110A);
  border: 1px solid var(--rule-2, #C7CFDC);
  border-radius: 7px;
  font: inherit;
  font-size: 0.88rem;
  font-weight: 600;
  cursor: pointer;
  transition: border-color 0.15s, background 0.15s, color 0.15s;
}
.builder-sections-pane__item-edit:hover {
  border-color: var(--accent, #FF5B00);
  background: var(--accent-soft, #FFF1E8);
  color: var(--accent-deep, #E04A00);
}

/* Variant picker — A/B/C buttons on the right side of each section row.
   Segmented-pill style; current pick is solid ink, others are quiet.
   Tap a button to update both the body data-attr (driving the preview
   iframe URL params) and the row's axis-description text below the
   section label. */
.builder-sections-pane__item-picker {
  display: flex;
  background: var(--paper-2, #F4F6FA);
  border-radius: 8px;
  padding: 3px;
  gap: 2px;
  flex-shrink: 0;
}
.builder-variant-btn {
  font: inherit;
  font-weight: 700;
  font-size: 0.78rem;
  letter-spacing: 0.05em;
  color: var(--ink-mute, #6B5A4C);
  background: transparent;
  border: 0;
  padding: 6px 11px;
  border-radius: 5px;
  cursor: pointer;
  min-width: 32px;
  transition: background 0.12s, color 0.12s;
}
.builder-variant-btn:hover {
  color: var(--ink);
  background: rgba(31, 22, 17, 0.04);
}
.builder-variant-btn.is-on {
  background: var(--ink, #16110A);
  color: #fff;
}
.builder-variant-btn.is-on:hover { background: var(--ink, #16110A); }

/* Form toggle (Quote / Booking) for hero + contact sections */
.builder-sections-pane__form-toggle {
  display: flex;
  gap: 8px;
  margin: 10px 16px 4px;
  padding: 0;
}
.builder-form-toggle-btn {
  font: inherit;
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.01em;
  color: var(--ink-mute, #6B5A4C);
  background: var(--paper, #fff);
  border: 1.5px solid var(--hairline, rgba(31,22,17,0.10));
  padding: 7px 14px;
  border-radius: 8px;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  transition: background 0.15s, color 0.15s, border-color 0.15s, box-shadow 0.15s;
  box-shadow: 0 1px 2px rgba(31,22,17,0.04);
}
.builder-form-toggle-btn svg {
  flex-shrink: 0;
  opacity: 0.55;
  transition: opacity 0.15s;
}
.builder-form-toggle-btn:hover {
  border-color: var(--ink-soft, #8A7866);
  color: var(--ink, #16110A);
  box-shadow: 0 1px 4px rgba(31,22,17,0.08);
}
.builder-form-toggle-btn:hover svg { opacity: 0.8; }

/* Publish sheet */
.builder-publish-sheet {
  position: fixed; inset: 0; z-index: 9999;
  display: flex; align-items: flex-end; justify-content: center;
}
.builder-publish-sheet[hidden] { display: none !important; }
.builder-publish-sheet__backdrop {
  position: absolute; inset: 0;
  background: rgba(0,0,0,0.25);
}
.builder-publish-sheet__card {
  position: relative; z-index: 1;
  width: 100%; max-width: 420px;
  background: #fff;
  border-radius: 16px 16px 0 0;
  box-shadow: 0 -4px 24px rgba(0,0,0,0.12);
  overflow: hidden;
  animation: bs-pub-up 0.25s ease-out;
}
@keyframes bs-pub-up {
  from { transform: translateY(100%); opacity: 0; }
  to { transform: translateY(0); opacity: 1; }
}
.builder-publish-sheet__header {
  display: flex; justify-content: space-between; align-items: center;
  padding: 20px 24px 0;
}
.builder-publish-sheet__title {
  font-size: 0.875rem; font-weight: 600; color: #171717; margin: 0;
  letter-spacing: -0.01em;
}
.builder-publish-sheet__close {
  background: none; border: 0; color: #bbb;
  cursor: pointer; padding: 2px; display: flex; border-radius: 6px;
}
.builder-publish-sheet__close:hover { color: #171717; background: #F5F5F5; }
.builder-publish-sheet__body { padding: 16px 24px 24px; }
/* Warning for existing live site */
.pub-warn {
  font-size: 0.8125rem; color: #666; line-height: 1.5;
  padding: 10px 12px; background: #FAFAFA; border-radius: 9px;
  margin-bottom: 14px;
}
.pub-warn strong { color: #171717; font-weight: 500; }
.pub-section { margin-bottom: 14px; }
.pub-label {
  font-size: 0.6875rem; font-weight: 500; color: #b5b0a8;
  margin-bottom: 5px; letter-spacing: 0.01em;
}
.pub-field {
  display: flex; align-items: center; height: 36px;
  border: 1px solid #e8e5e1; border-radius: 9px; overflow: hidden;
  margin-bottom: 4px;
}
.pub-field:focus-within { border-color: rgba(23,23,23,0.3); }
.pub-input {
  flex: 1; border: none; padding: 0 10px;
  font: inherit; font-size: 0.8125rem; color: #171717;
  outline: none; background: transparent; min-width: 0;
}
.pub-input::placeholder { color: #ccc; }
.pub-suffix {
  font-size: 0.6875rem; color: #b5b0a8;
  padding-right: 10px; white-space: nowrap; flex-shrink: 0;
}
.pub-hint { font-size: 0.6875rem; color: #ccc; }
/* Live URL strip */
.pub-live-url {
  display: flex; align-items: center; gap: 6px;
  padding: 9px 12px; background: #FAFAFA; border-radius: 9px;
  margin-bottom: 14px;
}
.pub-live-dot { width: 7px; height: 7px; border-radius: 50%; background: #16a34a; flex-shrink: 0; }
.pub-live-text { font-size: 0.8125rem; color: #171717; font-weight: 500; flex: 1; }
.pub-live-copy {
  font-size: 0.6875rem; color: #b5b0a8; font-weight: 500;
  background: none; border: none; cursor: pointer; font-family: inherit;
}
.pub-live-copy:hover { color: #171717; }
/* Action buttons */
.pub-actions { display: flex; flex-direction: column; gap: 6px; margin-bottom: 10px; }
.pub-btn-primary {
  width: 100%; height: 38px;
  border: 1px solid #171717; border-bottom-color: #0a0a0a; border-radius: 9px;
  background: linear-gradient(180deg, #2a2520, #171717);
  font: inherit; font-size: 0.8125rem; font-weight: 500; color: #fff;
  cursor: pointer;
  box-shadow: 0 1px 2px rgba(0,0,0,0.15), inset 0 1px 0 rgba(255,255,255,0.08);
}
.pub-btn-primary:hover { background: linear-gradient(180deg, #333, #1f1f1f); }
.pub-btn-primary:active { transform: translateY(0.5px); }
.pub-btn-primary:disabled { opacity: 0.6; cursor: wait; }
.pub-btn-secondary {
  width: 100%; height: 36px;
  border: 1px solid rgba(31,22,17,0.12); border-bottom-color: rgba(31,22,17,0.17); border-radius: 9px;
  background: linear-gradient(180deg, #fff, #F9F9F9);
  font: inherit; font-size: 0.8125rem; font-weight: 500; color: #171717;
  cursor: pointer;
  box-shadow: 0 1px 2px rgba(31,22,17,0.04), inset 0 1px 0 rgba(255,255,255,0.9);
}
.pub-btn-secondary:hover { border-color: rgba(31,22,17,0.2); }
.pub-btn-secondary:active { transform: translateY(0.5px); }
.pub-btn-danger {
  width: 100%; height: 36px; border-radius: 9px;
  background: #fff; color: #b91c1c; border: 1px solid #fecaca;
  font: inherit; font-size: 0.8125rem; font-weight: 500; cursor: pointer;
}
.pub-btn-danger:hover { background: #fef2f2; }
.pub-upsell {
  font-size: 0.75rem; color: #b5b0a8; text-align: center; margin-bottom: 0;
}
.pub-upsell a { color: #171717; font-weight: 500; text-decoration: none; }
.pub-upsell a:hover { text-decoration: underline; }
.pub-meta {
  font-size: 0.6875rem; color: #ccc; margin: 8px 0 0; text-align: center;
}
.builder-form-toggle-btn.is-on {
  background: var(--accent, #FF5B00);
  color: #fff;
  border-color: var(--accent, #FF5B00);
  box-shadow: 0 2px 6px rgba(255,91,0,0.2);
}
.builder-form-toggle-btn.is-on svg { stroke: #fff; }

.builder-sections-pane__item--variants .builder-sections-pane__item-main {
  min-width: 0;
}
.builder-sections-pane__item-preview[data-variant-axis] {
  /* The axis description swaps when the user picks a different variant
     so the row's preview text always reflects what they just picked.
     2026-06-03 (founder): non-italic to match the clean Templates tag style. */
  font-style: normal;
}
.builder-sections-pane__item-main {
  display: flex;
  flex-direction: column;
  gap: 3px;
  min-width: 0;
  flex: 1 1 auto;
}
.builder-sections-pane__item-label {
  font-weight: 600;
  font-size: 0.95rem;
  color: var(--ink);
}
.builder-sections-pane__item-preview {
  font-size: 0.78rem;
  color: var(--ink-mute);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
body:not(.is-builder-cards-view)[data-builder-active-pane="sections"] .builder-sections-pane__item svg,
body.is-builder-sliding:not(.is-builder-cards-view) .builder-sections-pane__item svg {
  color: var(--ink-mute);
  flex-shrink: 0;
}
/* AI builder live preview — loading + spinner shown while /api/auth/me
   resolves. Replaced by an iframe (or a CTA card) once we know the user. */
.builder-preview-loading {
  display: flex; flex-direction: column; align-items: center; gap: 14px;
  color: oklch(85% 0.02 60); font-size: 0.92rem;
}
.builder-preview-loading-spinner {
  width: 22px; height: 22px;
  border-radius: 50%;
  border: 2px solid oklch(96% 0.02 80 / 0.18);
  border-top-color: oklch(96% 0.02 80 / 0.9);
  animation: builderSpin 800ms linear infinite;
}
@keyframes builderSpin { to { transform: rotate(360deg); } }
/* Once an iframe lives in the body, it takes the whole pane and loses the
   centered-content padding so the live site fills the available space. */
.builder-preview-body:has(iframe[data-builder-iframe]) {
  padding: 0;
  align-items: stretch; justify-content: stretch;
}

/* ────────────────────────────────────────────────────────────────────
   Preview empty state — text-only, italic-serif headline + dark pill
   ────────────────────────────────────────────────────────────────────
   The previous heavy v6 dark mark + radial-orange tint + icon block
   were "trying too hard". Reduced to: italic-serif title, brief lede,
   dark pill CTA. Centred vertically on a clean cream gradient.

   Gated on :not(:has(iframe)) so it auto-resets when
   shellRenderPreviewIframe mounts the iframe.
   ──────────────────────────────────────────────────────────────────── */
.builder-preview-body:not(:has(iframe[data-builder-iframe])):not(:has(iframe[data-builder-template-iframe])) {
  background: linear-gradient(180deg, #FFFFFF 0%, #F6F6F6 100%) !important;
  color: var(--ink) !important;
  display: flex !important;
  align-items: center !important;
  justify-content: center !important;
  padding: 32px 36px 110px !important;  /* bottom padding clears the dock */
  overflow: auto;
}
.builder-preview-empty {
  text-align: center;
  max-width: 300px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 14px;
}
/* Empty-state content stays visible in cards-view (the preview card
   shows a real preview of the empty state). It morphs with the
   wrap via the parent's JS FLIP transform — only opacity is faded
   here, for a soft "settle" feel arriving at fullscreen.
   Easings matched to JS flipMorph: easeOutExpo in (sharp burst →
   slow settle), easeInQuart out (slow → fast snap). All durations
   end at the same beat as the wrap morph (~640ms open / ~380ms close)
   so the whole transition lands as one cohesive moment. */
/* 2026-05-23 founder feedback: "make it feel so fluid that the card
   transforms mid-animation smoothly to match the correct state."
   The previous staggered delays (220-320ms) made the chrome catch up
   to the wrap morph AFTER it had nearly settled — eye perceived two
   separate motions. Dropped all delays, matched durations to the
   wrap morph (720ms), all using the same easing. Everything moves
   in lockstep now → reads as one fluid motion. */
.builder-preview-empty {
  opacity: 1;
  transition: opacity 720ms cubic-bezier(0.22, 1, 0.36, 1);
}
body:not(.is-builder-cards-view):not([data-builder-active-pane="preview"]) .builder-preview-empty {
  opacity: 0;
  transition: opacity 460ms cubic-bezier(0.22, 1, 0.36, 1);
}
.builder-preview-empty__title {
  font-family: 'Instrument Serif', 'Newsreader', Georgia, serif;
  font-style: italic;
  font-weight: 400;
  font-size: 2.4rem;
  letter-spacing: -0.018em;
  line-height: 1.0;
  color: var(--ink);
  margin: 0;
  max-width: 280px;
}
.builder-preview-empty__lede {
  font-size: 0.94rem;
  color: var(--ink-mute);
  line-height: 1.55;
  margin: 0;
  max-width: 260px;
}
.builder-preview-empty__cta {
  margin-top: 6px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 10px 22px;
  background: linear-gradient(180deg, #2A211B 0%, #1F1611 100%);
  color: var(--cream);
  border: 0;
  border-radius: 999px;
  font-family: inherit;
  font-size: 0.9rem;
  font-weight: 500;
  cursor: pointer;
  box-shadow:
    0 0 0 0.5px rgba(0, 0, 0, 0.3),
    0 2px 3px rgba(0, 0, 0, 0.18),
    0 8px 18px -4px rgba(0, 0, 0, 0.22),
    inset 0 1.5px 0 rgba(255, 255, 255, 0.12);
  transition: transform 0.16s cubic-bezier(0.2, 0, 0, 1);
}
.builder-preview-empty__cta:hover { transform: translateY(-1px); }
.builder-preview-empty__cta:active { transform: translateY(0); }

/* ────────────────────────────────────────────────────────────────────
   Sections empty state — restructured 2026-05-24 to include a
   "preview of the populated state" via greyed-out ghost rows that
   mirror the actual sections list shape (label + A/B/C picker +
   chevron). Top: tighter title/lede/CTA; bottom: ghost rows with a
   fade to the pane edge. Reads as "this is what's coming" instead
   of just "blank pane".
   ──────────────────────────────────────────────────────────────────── */
.builder-sections-emptystate {
  display: flex;
  flex-direction: column;
  width: 100%;
  min-height: 0;
  flex: 1 1 auto;
  position: relative;
}
.builder-sections-emptystate__head {
  text-align: center;
  max-width: 320px;
  margin: 0 auto;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
  padding: 36px 24px 22px;
  flex: 0 0 auto;
}
.builder-sections-emptystate__title {
  font-family: 'Instrument Serif', 'Newsreader', Georgia, serif;
  font-style: italic;
  font-weight: 400;
  font-size: 1.9rem;
  letter-spacing: -0.018em;
  line-height: 1.05;
  color: var(--ink);
  margin: 0;
}
.builder-sections-emptystate__lede {
  font-size: 0.9rem;
  color: var(--ink-mute);
  line-height: 1.5;
  margin: 0;
  max-width: 280px;
}
.builder-sections-emptystate__cta {
  margin-top: 4px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 10px 22px;
  background: linear-gradient(180deg, #2A211B 0%, #1F1611 100%);
  color: var(--cream);
  border: 0;
  border-radius: 999px;
  font-family: inherit;
  font-size: 0.9rem;
  font-weight: 500;
  cursor: pointer;
  box-shadow:
    0 0 0 0.5px rgba(0, 0, 0, 0.3),
    0 2px 3px rgba(0, 0, 0, 0.18),
    0 8px 18px -4px rgba(0, 0, 0, 0.22),
    inset 0 1.5px 0 rgba(255, 255, 255, 0.12);
  transition: transform 0.16s cubic-bezier(0.2, 0, 0, 1);
}
.builder-sections-emptystate__cta:hover { transform: translateY(-1px); }
.builder-sections-emptystate__cta:active { transform: translateY(0); }

/* Ghost rows — preview of the populated list, greyed out + inert.
   Container has a fade-to-cream mask at the bottom so the list
   appears to fade out into the pane (suggesting "more rows than
   fit"). */
.builder-sections-emptystate__ghosts {
  padding: 0 16px 24px;
  display: flex;
  flex-direction: column;
  gap: 10px;
  flex: 1 1 auto;
  min-height: 0;
  -webkit-mask-image: linear-gradient(180deg, #000 0%, #000 65%, transparent 100%);
          mask-image: linear-gradient(180deg, #000 0%, #000 65%, transparent 100%);
  pointer-events: none;
  user-select: none;
}
.builder-sections-emptystate__ghost-row {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 14px 16px;
  background: rgba(255, 255, 255, 0.55);
  border: 1px solid rgba(31, 22, 17, 0.07);
  border-radius: 12px;
  flex: 0 0 auto;
}
.builder-sections-emptystate__ghost-label {
  flex: 1 1 auto;
  font-size: 0.96rem;
  font-weight: 600;
  color: rgba(31, 22, 17, 0.32);
  letter-spacing: -0.005em;
}
.builder-sections-emptystate__ghost-picker {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 4px;
  background: rgba(31, 22, 17, 0.04);
  border-radius: 10px;
  flex: 0 0 auto;
}
.builder-sections-emptystate__ghost-pick {
  width: 24px;
  height: 24px;
  border-radius: 7px;
  background: rgba(31, 22, 17, 0.08);
}
.builder-sections-emptystate__ghost-pick:first-child {
  background: rgba(31, 22, 17, 0.18);
}
.builder-sections-emptystate__ghost-chev {
  display: inline-flex;
  color: rgba(31, 22, 17, 0.18);
  flex: 0 0 auto;
}

/* ────────────────────────────────────────────────────────────────────
   2026-05-24 (rev 2): kill the mobile pull-up sheet AND stop the
   preview pane from bleeding through the chat pane in state="ready".
   The old design at dashboard-v2.css L7271 sets preview-pane to
   position:fixed top:0 bottom:0 z-index:1 whenever state="ready" —
   that was intentional under the sheet pattern (preview floated
   under the draggable chat sheet). With the sheet killed, the chat
   pane is position:static + z:auto so the position:fixed preview
   pane paints ON TOP of it, and the user sees V5 leak into the chat
   page after Build my site lands. Override BOTH:
     1. chat-pane stays a normal full-screen pane (sheet defang)
     2. preview-pane goes back to in-flow positioning UNLESS the
        active pane is actually preview (active-pane="preview" still
        wants the fullscreen iframe surface).
   Note: cards-view doesn't apply here — the cards-view rules at
   L7763 + L11760 are a separate ruleset and already override on
   their own. Only the single-mode state="ready" sheet is killed. */
@media (max-width: 720px) {
  body.is-builder-chat:not(.is-builder-cards-view) .builder-shell--centered[data-builder-state="ready"] .builder-chat-pane {
    position: static !important;
    bottom: auto !important;
    left: auto !important;
    right: auto !important;
    top: auto !important;
    height: auto !important;
    max-height: none !important;
    min-height: 0 !important;
    width: 100% !important;
    min-width: 0 !important;
    z-index: auto !important;
    background: transparent !important;
    border-top-left-radius: 0 !important;
    border-top-right-radius: 0 !important;
    box-shadow: none !important;
    overflow: hidden !important;
    flex: 1 1 0 !important;
    justify-content: flex-start !important;
    transition: none !important;
  }
  /* Belt-and-suspenders: hide the sheet handle even if the markup
     leaks back in via a stale cached renderer. */
  .builder-sheet-handle { display: none !important; }

  /* 2026-05-24 founder report: "preview brought to the chat page".
     The state="ready" rule at dashboard-v2.css L7271 sets preview-
     pane to position:fixed top:0 bottom:0 z-index:1 which under the
     old sheet design floated UNDER the chat sheet. With the sheet
     killed, preview-pane paints ON TOP of the chat pane (chat is
     z:auto static) — V5 bleeds through. Revert preview-pane to in-
     flow positioning unless active pane really is preview. */
  body.is-builder-chat:not(.is-builder-cards-view):not([data-builder-active-pane="preview"]) .builder-shell--centered[data-builder-state="ready"] .builder-preview-pane {
    position: static !important;
    top: auto !important;
    left: auto !important;
    right: auto !important;
    bottom: auto !important;
    z-index: auto !important;
  }

  /* 2026-05-24 (rev 2 — still bleeding). Even with preview-pane
     position:static, the parent .builder-card-wrap[data-pane-key=
     "preview"] is in flow below the chat-wrap. In state="empty" the
     shell is 100dvh + overflow:hidden so the preview-wrap is clipped
     below the viewport — but in state="ready" the shell sizing rule
     at L7395 stops firing (it gates on :not(state="ready")), so the
     shell falls back to auto height, the chat-wrap doesn't reach the
     viewport bottom, and the preview-wrap renders visible underneath.
     Fix: explicitly hide preview-wrap + sections-wrap whenever the
     user is on the chat pane (or no active-pane attr set). The
     is-builder-sliding rule already overrides display:none during
     pane transitions, so swipes between panes still show all three. */
  body.is-builder-chat:not(.is-builder-cards-view):not([data-builder-active-pane="preview"]):not([data-builder-active-pane="sections"]) .builder-card-wrap[data-pane-key="preview"],
  body.is-builder-chat:not(.is-builder-cards-view):not([data-builder-active-pane="preview"]):not([data-builder-active-pane="sections"]) .builder-card-wrap[data-pane-key="sections"] {
    display: none !important;
  }
}

/* ────────────────────────────────────────────────────────────────────
   State gating — `data-builder-state` on .builder-shell--centered
   flips between "empty" (initial) and "ready" (post chat-intro
   completion via shellTransitionToReady). When NOT ready: show the
   empty states, hide the populated content. When ready: reverse.
   Uses :not([data-builder-state="ready"]) so fresh shells (default
   data-builder-state="empty") AND any future transitional states
   both fall into the empty bucket.
   ──────────────────────────────────────────────────────────────────── */
.builder-shell--centered:not([data-builder-state="ready"]) .builder-template-iframe,
.builder-shell--centered:not([data-builder-state="ready"]) .builder-sections-pane__body {
  display: none !important;
}
.builder-shell--centered[data-builder-state="ready"] .builder-preview-empty,
.builder-shell--centered[data-builder-state="ready"] .builder-sections-emptystate {
  display: none !important;
}

/* Preview body centering — the existing :not(:has(iframe)) rule at
   ~line 4104 only fires when the iframe is absent from the DOM, but
   we keep the V5 iframe mounted always (display:none in empty state).
   This state-gated rule applies the same flex-centering when not
   ready so the empty title sits middle-of-pane instead of top-left. */
.builder-shell--centered:not([data-builder-state="ready"]) .builder-preview-body {
  display: flex !important;
  flex-direction: column !important;
  align-items: center !important;
  justify-content: center !important;
  padding: 32px 36px 110px !important;
  background: linear-gradient(180deg, #FFFFFF 0%, #F6F6F6 100%) !important;
  overflow: auto !important;
}

/* ────────────────────────────────────────────────────────────────────
   Preview floating dock (V1) — centred glass pill at the bottom of
   the preview pane. Always visible (empty state AND populated iframe),
   floats on top via position:absolute + high z-index.
   ──────────────────────────────────────────────────────────────────── */
.builder-preview-pane { position: relative; }
.builder-preview-dock {
  position: absolute;
  bottom: 16px;
  left: 50%;
  /* Visible default state — translate(-50%) centers, translateY(0) is
     at rest. The "hidden" state (in cards-view OR when preview isn't
     the active pane) slides down + fades via the transition below. */
  transform: translate(-50%, 0);
  z-index: 10;
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 6px;
  background: linear-gradient(180deg, rgba(255, 255, 255, 0.92) 0%, rgba(246, 246, 246, 0.92) 100%);
  -webkit-backdrop-filter: blur(16px) saturate(200%);
          backdrop-filter: blur(16px) saturate(200%);
  border: 1px solid rgba(31, 22, 17, 0.10);
  border-radius: 999px;
  box-shadow:
    0 0 0 0.5px rgba(0, 0, 0, 0.06),
    0 2px 4px rgba(20, 14, 8, 0.08),
    0 8px 24px -4px rgba(20, 14, 8, 0.18),
    0 20px 48px -12px rgba(20, 14, 8, 0.22),
    inset 0 1px 0 rgba(255, 255, 255, 0.9);
  opacity: 1;
  pointer-events: auto;
  /* Matched to OPEN_MS (720ms) and OPEN_EASE in dashboard-v2-page.html
     so the dock animates in lockstep with the wrap morph instead of
     catching up afterwards. */
  transition:
    opacity 720ms cubic-bezier(0.22, 1, 0.36, 1),
    transform 720ms cubic-bezier(0.22, 1, 0.36, 1);
}
.builder-preview-dock__btn {
  width: 40px;
  height: 40px;
  border-radius: 999px;
  background: transparent;
  border: 0;
  color: var(--ink);
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  transition: background 0.12s ease;
}
.builder-preview-dock__btn:hover { background: rgba(31, 22, 17, 0.06); }
.builder-preview-dock__btn:active { background: rgba(31, 22, 17, 0.10); }
/* When the edit-toggle is pressed, give it a filled dark circle so
   the tradie sees that edit mode is on. Founder feedback 2026-05-24:
   "when it [is] selected give it a black circle". */
.builder-preview-dock__btn.is-on {
  background: var(--ink, #1F1611);
  color: var(--cream, #FAFAF8);
}
.builder-preview-dock__btn.is-on:hover,
.builder-preview-dock__btn.is-on:active {
  background: var(--ink-2, #2A211B);
}
/* Hide-chrome toggle (founder 2026-06-15): a clean full-bleed preview surface.
   Hides the sidebar burger, the Live/Draft status pill and the cards-view pill.
   MUST be scoped to the preview surface: the toggle sets a PERSISTENT body class
   but the dock that owns it only shows on the preview pane, so an unscoped rule
   kept the burger hidden on the chat + sections panes too (founder 2026-07-02:
   "hides my sidebar button on both the chat and sections page"). Scope to the
   preview pane (and cards-view, unchanged) so chrome restores everywhere else. */
body.is-builder-chrome-hidden[data-builder-active-pane="preview"] .mob-topbar-burger,
body.is-builder-chrome-hidden[data-builder-active-pane="preview"] [data-preview-status],
body.is-builder-chrome-hidden[data-builder-active-pane="preview"] [data-builder-preview-pill],
body.is-builder-chrome-hidden.is-builder-cards-view .mob-topbar-burger,
body.is-builder-chrome-hidden.is-builder-cards-view [data-preview-status],
body.is-builder-chrome-hidden.is-builder-cards-view [data-builder-preview-pill] { display: none !important; }
/* But a PENDING choice/variations question needs the sidebar + cards-view buttons
   reachable - never let hide-chrome swallow them mid-question (founder 2026-06-29:
   the "show me variations" view lost both buttons). Scoped to an UNANSWERED card so
   it only overrides while the owner has a question in front of them, and NOT in
   cards-view (which hides the preview pill on purpose). :has()-dependent: on an
   engine without :has() the rule is ignored and chrome stays hidden (graceful). */
body.is-builder-chrome-hidden:not(.is-builder-cards-view):has(.builder-mcq-card:not(.is-answered):not(.is-dismissed)) .mob-topbar-burger,
body.is-builder-chrome-hidden:not(.is-builder-cards-view):has(.builder-mcq-card:not(.is-answered):not(.is-dismissed)) [data-builder-preview-pill] { display: inline-flex !important; }
/* Eye / eye-off icon swap on the dock toggle (default = chrome shown = eye). */
.builder-preview-dock__btn[data-chrome-toggle] .bs-eye-hide { display: none; }
.builder-preview-dock__btn[data-chrome-toggle].is-on .bs-eye-show { display: none; }
.builder-preview-dock__btn[data-chrome-toggle].is-on .bs-eye-hide { display: inline; }
.builder-preview-dock__divider {
  width: 1px;
  height: 22px;
  background: rgba(31, 22, 17, 0.10);
  margin: 0 3px;
}
.builder-preview-dock__publish {
  padding: 0 18px;
  height: 40px;
  min-width: 92px;
  background: linear-gradient(180deg, #2A211B 0%, #1F1611 100%);
  color: var(--cream);
  border: 0;
  border-radius: 999px;
  font-family: inherit;
  font-size: 0.86rem;
  font-weight: 500;
  cursor: pointer;
  box-shadow:
    0 0 0 0.5px rgba(0, 0, 0, 0.3),
    0 2px 3px rgba(0, 0, 0, 0.18),
    inset 0 1px 0 rgba(255, 255, 255, 0.12);
  transition: transform 0.16s cubic-bezier(0.2, 0, 0, 1);
}
.builder-preview-dock__publish:hover { transform: translateY(-1px); }
.builder-preview-dock__publish:active { transform: translateY(0); }

/* Slide-down + fade out when the dock shouldn't be visible (in
   cards-view OR when preview isn't the active fullscreen pane).
   pointer-events:none stops the invisible dock from intercepting
   taps. Faster decay than entry — out should snap, in should feel. */
body.is-builder-cards-view .builder-preview-dock,
body:not(.is-builder-cards-view):not([data-builder-active-pane="preview"]) .builder-preview-dock {
  opacity: 0;
  transform: translate(-50%, 28px);
  pointer-events: none;
  /* Matched to CLOSE_MS (460ms) and same easing — fluid exit. */
  transition:
    opacity 460ms cubic-bezier(0.22, 1, 0.36, 1),
    transform 460ms cubic-bezier(0.22, 1, 0.36, 1);
}

/* ────────────────────────────────────────────────────────────────────
   Preview status pill — top-right floating, Draft / Live
   ──────────────────────────────────────────────────────────────────── */
.builder-preview-status {
  /* 2026-05-24 (rev 2): pinned to the viewport at topbar height,
     positioned just to the LEFT of the cards-view button (which sits
     at right ~12-60px). Was position:absolute inside the preview
     pane; safe-area math + the pane's own padding put it right under
     the cards button on iOS. Fixed positioning + an explicit right
     offset that clears the 48px cards button gives a predictable
     gap. z-index above the topbar (.mob-topbar z:70 + .builder-
     preview-pill z:71) so it floats alongside, not behind. */
  position: fixed;
  top: calc(14px + env(safe-area-inset-top, 0px));
  right: calc(72px + env(safe-area-inset-right, 0px));
  z-index: 72;
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 5px 12px 5px 10px;
  background: rgba(255, 255, 255, 0.82);
  -webkit-backdrop-filter: blur(14px) saturate(180%);
          backdrop-filter: blur(14px) saturate(180%);
  border: 1px solid rgba(31, 22, 17, 0.08);
  border-radius: 999px;
  box-shadow: 0 2px 6px rgba(31, 22, 17, 0.08);
  font-family: 'JetBrains Mono', 'IBM Plex Mono', monospace;
  font-size: 0.62rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink);
  opacity: 1;
  transform: translateY(0);
  pointer-events: auto;
  /* Matched to OPEN_MS — no delay. */
  transition:
    opacity 720ms cubic-bezier(0.22, 1, 0.36, 1),
    transform 720ms cubic-bezier(0.22, 1, 0.36, 1);
}
.builder-preview-status__dot {
  width: 7px;
  height: 7px;
  border-radius: 999px;
  background: var(--ink-faint);
}
.builder-preview-status[data-state="live"] .builder-preview-status__dot {
  background: #4a7c4a;
  box-shadow: 0 0 6px rgba(74, 124, 74, 0.5);
}
body.is-builder-cards-view .builder-preview-status,
body:not(.is-builder-cards-view):not([data-builder-active-pane="preview"]) .builder-preview-status {
  opacity: 0;
  transform: translateY(-14px);
  pointer-events: none;
  transition:
    opacity 460ms cubic-bezier(0.22, 1, 0.36, 1),
    transform 460ms cubic-bezier(0.22, 1, 0.36, 1);
}

@media (prefers-reduced-motion: reduce) {
  .builder-preview-dock,
  .builder-preview-status,
  .builder-preview-empty {
    transition: none !important;
  }
}

/* ── Settings tab — Site Settings form (v2 premium) ────────────────────
   Hairline-separated sections, label-left / input-right rows, generous
   whitespace. No card chrome — sections are separated by space + a thin
   rule. AI reads these; tradie writes. */
.builder-settings-body {
  flex: 1;
  overflow-y: auto;
  background: var(--bs-paper, #FAFAFA);
}
.builder-settings-body[hidden] { display: none; }
.bsf-loading, .bsf-error {
  padding: 60px 40px;
  text-align: center;
  color: var(--bs-ink-mute, #6b5d50);
  font-size: 0.92rem;
}
.bsf-error { color: #b3261e; }
.bsf-wrap {
  max-width: 760px;
  margin: 0 auto;
  padding: 48px 40px 140px;
}
.bsf-head {
  margin: 0 0 40px;
  padding: 0 0 28px;
  border-bottom: 1px solid rgba(31, 22, 17, 0.08);
}
.bsf-title {
  font-family: 'Geist', 'Inter Tight', 'Inter', sans-serif;
  font-size: 1.7rem;
  font-weight: 600;
  color: var(--bs-ink, #1f1611);
  letter-spacing: -0.022em;
  margin: 0 0 6px;
  line-height: 1.2;
}
.bsf-sub {
  font-size: 0.92rem;
  color: var(--bs-ink-mute, #6b5d50);
  line-height: 1.55;
  max-width: 56ch;
  margin: 0;
}
.bsf-form {
  display: flex;
  flex-direction: column;
}

/* Section: borderless. Each section sits in space, separated by a hairline. */
.bsf-section {
  margin: 0;
  padding: 32px 0;
  border-bottom: 1px solid rgba(31, 22, 17, 0.07);
}
.bsf-section:first-of-type { padding-top: 0; }
.bsf-section:last-of-type { border-bottom: none; }
.bsf-section-summary {
  cursor: pointer;
  list-style: none;
  user-select: none;
  padding: 0 0 4px;
  position: relative;
}
.bsf-section-summary::-webkit-details-marker { display: none; }
.bsf-section-summary::after {
  content: '';
  position: absolute;
  right: 4px;
  top: 8px;
  width: 8px;
  height: 8px;
  border-right: 1.5px solid rgba(31, 22, 17, 0.45);
  border-bottom: 1.5px solid rgba(31, 22, 17, 0.45);
  transform: rotate(45deg);
  transition: transform 180ms ease;
}
.bsf-section[open] > .bsf-section-summary::after {
  transform: rotate(-135deg);
  top: 12px;
}
.bsf-section-summary:hover::after {
  border-color: var(--bs-ink, #1f1611);
}
.bsf-section-title {
  font-family: 'Geist', 'Inter Tight', 'Inter', sans-serif;
  font-size: 1.05rem;
  font-weight: 600;
  color: var(--bs-ink, #1f1611);
  letter-spacing: -0.01em;
  margin: 0 0 4px;
  line-height: 1.3;
}
.bsf-section-desc {
  font-size: 0.85rem;
  color: var(--bs-ink-mute, #6b5d50);
  line-height: 1.5;
  max-width: 56ch;
  margin: 0;
}
.bsf-section-body {
  padding: 24px 0 4px;
  display: flex;
  flex-direction: column;
}

/* Field row: label LEFT (200px), input RIGHT (max 420px). */
.bsf-field {
  display: grid;
  grid-template-columns: 180px 1fr;
  gap: 24px;
  align-items: start;
  padding: 14px 0;
  border-bottom: 1px solid rgba(31, 22, 17, 0.05);
}
.bsf-field:last-child { border-bottom: none; }
.bsf-label {
  font-size: 0.88rem;
  font-weight: 500;
  color: var(--bs-ink, #1f1611);
  letter-spacing: -0.005em;
  padding-top: 9px;
  line-height: 1.4;
}
.bsf-field-control { max-width: 460px; }
.bsf-input {
  font-family: inherit;
  font-size: 0.92rem;
  padding: 9px 12px;
  border: 1px solid rgba(31, 22, 17, 0.16);
  border-radius: 6px;
  background: white;
  color: var(--bs-ink, #1f1611);
  transition: border-color 120ms ease, box-shadow 120ms ease;
  width: 100%;
  min-width: 0;
  line-height: 1.4;
}
.bsf-input:hover { border-color: rgba(31, 22, 17, 0.28); }
.bsf-input:focus {
  outline: none;
  border-color: var(--bs-orange, #d9541e);
  box-shadow: 0 0 0 3px rgba(217, 84, 30, 0.10);
}
.bsf-textarea {
  resize: vertical;
  min-height: 88px;
  line-height: 1.55;
  font-family: inherit;
}
.bsf-hint {
  font-size: 0.78rem;
  color: var(--bs-ink-mute, #6b5d50);
  line-height: 1.45;
  margin-top: 8px;
  opacity: 0.85;
}
select.bsf-input {
  appearance: none;
  -webkit-appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12'%3E%3Cpath d='M3 4.5l3 3 3-3' stroke='%236b5d50' stroke-width='1.5' fill='none' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 10px center;
  background-size: 12px;
  padding-right: 32px;
}
.bsf-check-grid {
  display: flex;
  flex-wrap: wrap;
  gap: 8px 18px;
  padding-top: 6px;
}
.bsf-check {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: 0.88rem;
  cursor: pointer;
  padding: 4px 0;
  user-select: none;
  color: var(--bs-ink, #1f1611);
}
.bsf-check input { accent-color: var(--bs-orange, #d9541e); }

/* Curated swatch picker for accent colour. */
.bsf-swatch-row {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  align-items: center;
  padding: 4px 0;
}
.bsf-swatch {
  width: 32px;
  height: 32px;
  border-radius: 8px;
  border: 1px solid rgba(31, 22, 17, 0.12);
  cursor: pointer;
  position: relative;
  transition: transform 120ms ease, box-shadow 120ms ease;
  padding: 0;
  background-clip: padding-box;
}
.bsf-swatch:hover {
  transform: scale(1.08);
  box-shadow: 0 4px 12px rgba(31, 22, 17, 0.12);
}
.bsf-swatch.is-on {
  box-shadow: 0 0 0 2px white, 0 0 0 4px var(--bs-ink, #1f1611);
}
.bsf-swatch[data-custom="1"] {
  background: linear-gradient(135deg, #ff6b6b, #4ecdc4 25%, #ffe66d 50%, #95e1d3 75%, #c7a3e0);
}
.bsf-swatch-text {
  font-family: 'SF Mono', Menlo, monospace;
  font-size: 0.82rem;
  color: var(--bs-ink-mute, #6b5d50);
  margin-left: 8px;
  letter-spacing: 0.02em;
}
.bsf-color-native {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  opacity: 0;
  cursor: pointer;
}

/* Sticky save bar. Glass-look backdrop, full-width across the pane. */
.bsf-actions {
  position: sticky;
  bottom: 0;
  margin: 32px -40px 0;
  padding: 18px 40px;
  background: rgba(250, 250, 250, 0.92);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  border-top: 1px solid rgba(31, 22, 17, 0.08);
  display: flex;
  align-items: center;
  gap: 14px;
}
.bsf-save-btn {
  font-family: inherit;
  font-size: 0.9rem;
  font-weight: 500;
  padding: 9px 18px;
  border-radius: 8px;
  border: 1px solid var(--bs-ink, #1f1611);
  background: var(--bs-ink, #1f1611);
  color: white;
  cursor: pointer;
  transition: transform 80ms ease, opacity 120ms ease;
  letter-spacing: -0.005em;
}
.bsf-save-btn:hover { opacity: 0.93; }
.bsf-save-btn:active { transform: translateY(1px); }
.bsf-save-btn:disabled { opacity: 0.55; cursor: progress; }
.bsf-status {
  font-size: 0.85rem;
  color: var(--bs-ink-mute, #6b5d50);
  transition: opacity 200ms ease;
}
.bsf-status-ok { color: #2d6a3e; }
.bsf-status-err { color: #b3261e; }

@media (max-width: 720px) {
  .bsf-wrap { padding: 32px 20px 120px; }
  .bsf-field { grid-template-columns: 1fr; gap: 8px; }
  .bsf-label { padding-top: 0; }
  .bsf-actions { margin: 24px -20px 0; padding: 14px 20px; }
}
.builder-preview-content {
  max-width: 560px;
  text-align: center;
  padding: 30px;
}
.builder-preview-brand {
  font-family: 'Newsreader', Georgia, serif;
  font-style: italic;
  font-size: 0.95rem;
  color: oklch(80% 0.10 38);
  margin-bottom: 16px;
}
.builder-preview-headline {
  font-family: 'Geist', sans-serif;
  font-size: clamp(1.4rem, 2.4vw, 1.95rem);
  font-weight: 500;
  letter-spacing: -0.024em;
  line-height: 1.18;
  margin: 0 0 14px;
  color: #fff;
}
.builder-preview-sub {
  font-size: 0.92rem;
  color: oklch(85% 0.02 60);
  line-height: 1.55;
  margin: 0 0 28px;
}
.builder-preview-ctas {
  display: flex; flex-direction: column; align-items: center; gap: 14px;
}
.builder-preview-cta.is-primary {
  display: inline-block;
  background: oklch(64% 0.16 38);
  color: #fff;
  padding: 10px 22px;
  border-radius: 8px;
  font-size: 0.95rem; font-weight: 500;
  text-decoration: none;
  font-family: 'Geist', sans-serif;
}
.builder-preview-cta-or {
  font-size: 0.84rem;
  color: oklch(75% 0.02 60);
}
.builder-preview-cta-secondary {
  color: oklch(85% 0.10 38);
  text-decoration: underline;
}

/* ==========================================================================
   AI builder — 3-tab layout (Preview / Settings / AI Builder).
   Mobile-first, light-theme, white card. Replaces the older split-pane
   builder-shell layout. The .abx-* prefix keeps it scoped.
   ========================================================================== */
.abx { display: flex; flex-direction: column; gap: 14px; min-height: 0; }
.abx-tabs {
  display: flex; gap: 6px; padding: 4px; border-radius: 10px;
  background: var(--cream-2); border: 1px solid var(--hairline);
}
.abx-tab {
  flex: 1 1 0; min-width: 0;
  padding: 10px 12px; font-size: 0.92rem; font-weight: 500;
  color: var(--ink-mute); background: transparent; border: 0; border-radius: 8px;
  cursor: pointer; min-height: 44px; touch-action: manipulation;
  -webkit-tap-highlight-color: transparent;
  transition: background 0.15s, color 0.15s;
}
.abx-tab:hover { color: var(--ink); }
.abx-tab.is-on {
  background: var(--paper, #FFFFFF); color: var(--ink);
  box-shadow: 0 1px 2px rgba(31,22,17,0.06);
}
.abx-subtitle {
  font-size: 0.86rem; color: var(--ink-mute);
  font-family: 'Geist Mono', 'JetBrains Mono', ui-monospace, monospace;
}
.abx-panel { display: none; min-height: 0; }
.abx-panel.is-on { display: flex; flex-direction: column; gap: 12px; }

/* Preview panel: iframe of the live site (or empty state). */
.abx-preview-frame {
  position: relative;
  background: var(--paper, #FFFFFF);
  border: 1px solid var(--hairline); border-radius: 12px;
  min-height: 60vh; overflow: hidden;
  display: flex; align-items: center; justify-content: center;
}
.abx-iframe {
  width: 100%; height: 100%;
  min-height: 60vh; border: 0;
  background: var(--paper, #FFFFFF);
  display: block;
}
.abx-loading {
  display: flex; flex-direction: column; align-items: center; gap: 12px;
  color: var(--ink-mute); font-size: 0.9rem; padding: 32px;
}
.abx-spinner {
  width: 22px; height: 22px;
  border: 2px solid var(--hairline); border-top-color: var(--orange);
  border-radius: 50%; animation: abx-spin 0.7s linear infinite;
}
@keyframes abx-spin { to { transform: rotate(360deg); } }
.abx-empty {
  display: flex; flex-direction: column; align-items: center; gap: 12px;
  text-align: center; padding: 36px 24px; max-width: 420px;
}
.abx-empty-title { font-size: 1.15rem; font-weight: 500; color: var(--ink); }
.abx-empty-desc { font-size: 0.92rem; color: var(--ink-mute); margin: 0 0 8px; max-width: 36ch; line-height: 1.5; }
.abx-preview-actions {
  display: flex; gap: 8px; justify-content: flex-end;
}

/* Settings panel: stacked cards with site-only controls. */
.abx-card {
  background: var(--paper, #FFFFFF);
  border: 1px solid var(--hairline);
  border-radius: 12px;
  padding: 18px;
  display: flex; flex-direction: column; gap: 8px;
}
.abx-card-title { font-size: 0.95rem; font-weight: 600; color: var(--ink); margin: 0 0 4px; }
.abx-card-row { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
.abx-card-help { font-size: 0.84rem; color: var(--ink-mute); margin: 0; line-height: 1.5; }
.abx-card-help.is-error { color: var(--orange-deep, #B8420F); }
.abx-host {
  flex: 1 1 auto; min-width: 0;
  font-family: 'Geist Mono', 'JetBrains Mono', ui-monospace, monospace;
  font-size: 0.92rem; color: var(--ink);
  word-break: break-all;
}
.abx-input {
  flex: 1 1 auto; min-width: 0;
  padding: 10px 12px; border: 1px solid var(--hairline); border-radius: 8px;
  background: var(--paper, #FFFFFF); color: var(--ink);
  font: inherit; font-size: 16px;
}
.abx-input:focus { outline: 2px solid var(--orange); outline-offset: 2px; border-color: var(--ink); }
.abx-link {
  display: inline-block;
  font-size: 0.92rem; color: var(--orange-deep, #B8420F); text-decoration: none;
  padding: 6px 0;
}
.abx-link:hover { text-decoration: underline; }
.btn-sm { padding: 8px 14px; font-size: 0.86rem; min-height: 36px; }

/* AI Builder panel: white background, full available height. */
.abx-subtabs {
  display: flex; gap: 4px; padding: 3px;
  background: var(--cream-2); border: 1px solid var(--hairline); border-radius: 8px;
  margin-bottom: 8px; align-self: flex-start;
}
.abx-subtab {
  padding: 7px 14px; font-size: 0.85rem; font-weight: 500;
  color: var(--ink-mute); background: transparent; border: 0; border-radius: 6px;
  cursor: pointer; min-height: 36px; touch-action: manipulation;
}
.abx-subtab.is-on { background: var(--paper, #FFFFFF); color: var(--ink); box-shadow: 0 1px 2px rgba(31,22,17,0.06); }
.abx-subpanel { display: none; }
.abx-subpanel.is-on { display: block; }
.abx-builder-iframe {
  width: 100%;
  height: calc(100dvh - 200px);
  min-height: 600px;
  border: 1px solid var(--hairline); border-radius: 12px;
  background: #FFFFFF;
  display: block;
}
.abx-chat-card {
  background: var(--paper, #FFFFFF);
  border: 1px solid var(--hairline);
  border-radius: 12px;
  padding: 16px;
  display: flex; flex-direction: column; gap: 12px;
  min-height: calc(100dvh - 240px);
}
.abx-chat-thread {
  flex: 1 1 auto; min-height: 200px;
  overflow-y: auto;
  display: flex; flex-direction: column; gap: 10px;
  padding: 4px;
}
.abx-chat-msg {
  max-width: 85%;
  padding: 10px 14px;
  border-radius: 12px;
  font-size: 0.92rem; line-height: 1.5;
  word-break: break-word;
}
.abx-chat-msg.is-ai {
  align-self: flex-start;
  background: var(--cream-2);
  color: var(--ink);
}
.abx-chat-msg.is-user {
  align-self: flex-end;
  background: var(--ink);
  color: var(--cream, #FAFAFA);
}
.abx-chat-quick {
  display: flex; flex-wrap: wrap; gap: 6px;
}
.abx-chat-chip {
  padding: 7px 12px; font-size: 0.85rem;
  background: var(--paper, #FFFFFF); color: var(--ink);
  border: 1px solid var(--hairline); border-radius: 999px;
  cursor: pointer; min-height: 36px; touch-action: manipulation;
}
.abx-chat-chip:hover { background: var(--cream-2); }
.abx-chat-compose {
  display: flex; gap: 8px; align-items: flex-end;
}
.abx-chat-input {
  flex: 1 1 auto; min-width: 0;
  padding: 10px 12px; border: 1px solid var(--hairline); border-radius: 8px;
  background: var(--paper, #FFFFFF); color: var(--ink);
  font: inherit; font-size: 16px; resize: vertical;
  min-height: 44px; max-height: 200px;
}
.abx-chat-input:focus { outline: 2px solid var(--orange); outline-offset: 2px; border-color: var(--ink); }

@media (max-width: 899.98px) {
  .abx { gap: 10px; width: 100%; }
  .abx-tabs { padding: 3px; }
  .abx-tab { padding: 9px 10px; font-size: 0.88rem; }
  .abx-card { padding: 14px; }
  .abx-preview-frame, .abx-iframe { min-height: 55vh; }

  /* All four panel states (Preview frame, Settings cards, AI Builder Form
     iframe, AI Builder Chat card) live inside the normal dashboard page
     padding (16px each side). Iframe + preview frame keep the rounded card
     border so they read as siblings of the Settings cards. */
  .abx-builder-iframe {
    width: 100%;
    max-width: 100%;
    height: calc(100dvh - 200px);
    min-height: 520px;
    border-radius: 12px;
    border: 1px solid var(--hairline);
    margin: 0;
  }
  .abx-preview-frame {
    width: 100%;
    max-width: 100%;
    border-radius: 12px;
    border: 1px solid var(--hairline);
    margin: 0;
  }

  /* The /builder iframe has an intrinsic 300px width that, in a flex column
     chain (.abx-subpanel > .abx-panel > .abx > main.dash), shrinks every
     parent to fit-content. Force the dash + abx tree to fill the grid track
     so the iframe's width:100% resolves against the full page-padded area
     (343px at 375 viewport) instead of the iframe's 300px intrinsic. */
  main.dash:has(.abx) {
    width: 100%;
    max-width: 100%;
  }
  .abx-panel,
  .abx-subpanel { width: 100%; }
}

.jt-card.is-fallback .jt-fallback-body {
  grid-column: 2 / 4;
  grid-row: 2 / 4;
  font-size: 0.9rem; color: var(--ink-mute); line-height: 1.55;
  margin-top: 4px;
}
.jt-card.is-fallback .jt-fallback-body strong { color: var(--ink); font-weight: 600; }

/* === Calendar empty state ============================================== */
.cal-empty {
  display: flex;
  flex-direction: column;
  gap: 22px;
  margin-top: 28px;
  margin-bottom: 24px;
}
.cal-empty-card {
  background: var(--paper, #fff);
  border: 1px solid var(--hairline);
  border-radius: 12px;
  padding: 28px 32px;
}
.cal-empty-title {
  font-family: 'Geist', 'Inter Tight', 'Inter', sans-serif;
  font-weight: 500;
  font-size: 1.5rem;
  letter-spacing: -0.018em;
  color: var(--ink);
  margin: 0 0 8px;
}
.cal-empty-sub {
  font-size: 0.95rem;
  color: var(--ink-mute);
  line-height: 1.55;
  margin: 0;
  max-width: 64ch;
  text-wrap: pretty;
}
.cal-empty-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 12px;
}
.cal-empty-action {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  padding: 18px;
  background: var(--paper, #fff);
  border: 1px solid var(--hairline);
  border-radius: 12px;
  text-align: left;
  text-decoration: none;
  color: var(--ink);
  transition: border-color 0.18s cubic-bezier(0.2, 0, 0, 1), transform 0.18s cubic-bezier(0.2, 0, 0, 1);
}
.cal-empty-action:hover {
  border-color: var(--ink-mute);
  transform: translateY(-1px);
}
.cal-empty-action-icon {
  display: inline-flex;
  width: 32px;
  height: 32px;
  align-items: center;
  justify-content: center;
  border-radius: 8px;
  background: var(--cream-2);
  color: var(--ink);
  flex-shrink: 0;
}
.cal-empty-action-title {
  font-family: 'Geist', 'Inter Tight', 'Inter', sans-serif;
  font-weight: 500;
  font-size: 0.95rem;
  color: var(--ink);
  margin-bottom: 4px;
  line-height: 1.3;
  letter-spacing: -0.01em;
}
.cal-empty-action-sub {
  font-size: 0.82rem;
  color: var(--ink-mute);
  line-height: 1.45;
}
.cal-empty-preview { margin-top: 4px; }
.cal-empty-preview-eyebrow {
  font-family: 'JetBrains Mono', 'IBM Plex Mono', monospace;
  font-size: 0.7rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink-faint);
  margin: 0 0 12px;
  font-weight: 500;
}
.cal-empty-preview-list {
  display: flex;
  flex-direction: column;
  background: var(--paper, #fff);
  border: 1px solid var(--hairline);
  border-radius: 12px;
  overflow: hidden;
}
.cal-empty-preview-row {
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 14px 18px;
  border-bottom: 1px solid var(--hairline);
}
.cal-empty-preview-row:last-child { border-bottom: 0; }
.cal-empty-preview-pill {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 0.78rem;
  font-weight: 500;
  padding: 5px 10px;
  border-radius: 6px;
  flex-shrink: 0;
  min-width: 130px;
}
.cal-empty-preview-pill.is-booking { background: var(--green-soft, rgba(46,125,50,0.12)); color: var(--green, #2E7D32); }
.cal-empty-preview-pill.is-block { background: var(--cream-2); color: var(--ink); }
.cal-empty-preview-pill.is-gcal { background: rgba(213,117,41,0.1); color: var(--accent-orange, #D57529); }
.cal-empty-preview-pill.is-sm8 { background: rgba(42, 159, 214, 0.12); color: #1B7CB0; }
.cal-empty-preview-text {
  font-size: 0.88rem;
  color: var(--ink-mute);
  line-height: 1.5;
}

/* The empty week-grid is the primary calendar surface — full-strength.
   Empty-state cards sit below as supportive guidance, not as a takeover. */

@media (max-width: 720px) {
  .cal-empty-grid { grid-template-columns: 1fr; }
  .cal-empty-card { padding: 22px; }
  .cal-empty-preview-pill { min-width: auto; }
}

/* === Forms tabs — Booking form / Quote form switcher ===================
   Glass-sliding segmented control matching Leads (All/Bookings/Quotes)
   and Calendar (Today/Week/Month) — cream-2 track + one absolutely-
   positioned glass pill that slides between active positions via JS-
   controlled transform + width. Both GPU-cheap properties so the 60fps
   slide stays smooth. See [data-forms-indicator] in dashboard-v2-page-
   wire.js for the positioning logic. */
.forms-tabs {
  position: relative;
  display: inline-flex;
  background: rgba(31, 22, 17, 0.04);
  border: 1px solid rgba(31, 22, 17, 0.04);
  border-radius: 10px;
  padding: 3px;
  gap: 2px;
  margin: 4px 0 16px;
  isolation: isolate;
}
.forms-tab {
  position: relative;
  z-index: 1;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 7px 16px;
  border-radius: 8px;
  background: transparent;
  border: 0;
  font-family: inherit;
  font-size: 0.8125rem;
  font-weight: 500;
  color: #A39585;
  cursor: pointer;
  transition: color 0.22s ease;
  -webkit-tap-highlight-color: transparent;
}
@media (hover: hover) { .forms-tab:hover { color: var(--ink); } }
.forms-tab.is-on { color: var(--ink); }
.forms-tab__count {
  font-family: 'JetBrains Mono', 'IBM Plex Mono', monospace;
  font-size: 11px;
  color: var(--ink-faint);
  font-variant-numeric: tabular-nums;
}
.forms-tab.is-on .forms-tab__count { color: var(--ink-mute); }
.forms-tabs__indicator {
  position: absolute;
  top: 3px; left: 0;
  height: calc(100% - 6px);
  width: 0;
  pointer-events: none;
  z-index: 0;
  border-radius: 8px;
  background: linear-gradient(180deg, #FFFFFF 0%, #F8F8F8 100%);
  border: 1px solid rgba(31, 22, 17, 0.1);
  border-bottom-color: rgba(31, 22, 17, 0.15);
  box-shadow:
    0 1px 3px rgba(31, 22, 17, 0.07),
    0 2px 1px -1px rgba(31, 22, 17, 0.04),
    inset 0 1px 0 rgba(255, 255, 255, 0.9);
  will-change: transform, width;
  transform: translate3d(0, 0, 0);
  transition:
    transform 0.32s cubic-bezier(0.32, 0.72, 0, 1),
    width 0.32s cubic-bezier(0.32, 0.72, 0, 1);
}

/* === Form template — v6 hero card =====================================
   Holds the intro (Live pill + headline + sub + URL chip) and the
   form-rules sub-section. Editor + preview grid lives as a sibling
   below, untouched. One v6 light-gradient surface provides the depth;
   inside the card everything is hairline-divided (no nested boxes). */
.form-template {
  background: linear-gradient(180deg, #FFFFFF 0%, #F6F6F6 100%);
  border: 1px solid rgba(31, 22, 17, 0.10);
  border-radius: 18px;
  padding: 22px 22px 0;
  margin-bottom: 22px;
  box-shadow:
    0 0 0 0.5px rgba(0, 0, 0, 0.04),
    0 1px 2px rgba(20, 14, 8, 0.04),
    0 4px 10px -2px rgba(20, 14, 8, 0.10),
    0 12px 24px -6px rgba(20, 14, 8, 0.14),
    inset 0 1px 0 rgba(255, 255, 255, 0.9),
    inset 0 -1px 1px rgba(0, 0, 0, 0.03);
}
.form-template-head {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0;
}
.form-template-headline {
  font-size: 1.02rem;
  color: var(--ink);
  margin: 0 0 8px;
  line-height: 1.45;
}
.form-template-headline strong { font-weight: 600; }
.form-template-subline {
  font-size: 0.86rem;
  color: var(--ink-mute);
  margin: 0 0 16px;
  line-height: 1.5;
}
.form-template-subline a { color: var(--ink); border-bottom: 1px solid var(--hairline-2, var(--hairline)); text-decoration: none; }
.form-template-subline a:hover { border-bottom-color: var(--ink-mute); }

/* URL chip — small glass pill, the deliberate third v6 moment.
   The URL is the actual subject of the page so it gets surface depth
   even inside the already-v6 card. */
.form-template-url {
  display: flex;
  align-items: center;
  gap: 10px;
  font-family: 'JetBrains Mono', 'IBM Plex Mono', monospace;
  font-size: 0.82rem;
  color: var(--ink);
  background: rgba(255, 255, 255, 0.78);
  backdrop-filter: blur(8px) saturate(160%);
  -webkit-backdrop-filter: blur(8px) saturate(160%);
  border: 1px solid rgba(31, 22, 17, 0.08);
  padding: 8px 8px 8px 12px;
  border-radius: 10px;
  box-shadow: 0 1px 2px rgba(31, 22, 17, 0.04);
}
.form-template-url-icon { display: inline-flex; color: var(--ink-faint); flex-shrink: 0; }
.form-template-url-text {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.form-template-url-copy {
  flex-shrink: 0;
  width: 26px; height: 26px;
  border-radius: 6px;
  background: rgba(31, 22, 17, 0.04);
  border: 0;
  color: var(--ink-mute);
  display: inline-flex; align-items: center; justify-content: center;
  cursor: pointer;
  transition: background 0.12s, color 0.12s;
}
.form-template-url-copy:hover { background: rgba(31, 22, 17, 0.10); color: var(--ink); }
.form-template-url-copy.is-copied { color: var(--green); background: var(--green-soft); }

/* Live pill — pulse-dot prepended, sits as the first element in the
   card head (mono caps eyebrow style). Pulse animation is tiny — gives
   "actually live" feel without being noisy. */
.form-template-status {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  font-family: 'JetBrains Mono', 'IBM Plex Mono', monospace;
  font-size: 0.62rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--green);
  background: var(--green-soft);
  padding: 5px 10px 5px 9px;
  border-radius: 999px;
  margin-bottom: 14px;
}
.form-status-dot {
  position: relative;
  width: 7px; height: 7px;
  border-radius: 999px;
  background: var(--green);
  flex-shrink: 0;
}
.form-status-dot::after {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: 999px;
  animation: form-live-pulse 1.8s ease-out infinite;
}
@keyframes form-live-pulse {
  0%   { box-shadow: 0 0 0 0 rgba(63, 122, 71, 0.55); }
  70%  { box-shadow: 0 0 0 7px rgba(63, 122, 71, 0); }
  100% { box-shadow: 0 0 0 0 rgba(63, 122, 71, 0); }
}

/* === Form rules — hairline-divided sub-section inside the v6 card ====
   Sits below the URL chip, separated by a hairline. Title is a mono-caps
   eyebrow with an "Adjust in Settings →" deep-link on the right. Rules
   render as a 2-column grid of compact text + dot rows — no chip pills
   (the v6 card already provides surface; chips on chips reads as nested
   boxes). Each row deep-links to its specific Settings panel. */
.form-setup-rail {
  margin: 22px -22px 0;
  padding: 16px 22px 22px;
  background: transparent;
  border: 0;
  border-top: 1px solid var(--hairline);
  border-radius: 0;
}
.form-setup-rail-top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  margin-bottom: 4px;
}
.form-setup-rail-head {
  font-family: 'JetBrains Mono', 'IBM Plex Mono', monospace;
  font-size: 0.62rem;
  font-weight: 500;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--ink-soft);
}
.form-setup-rail-cta {
  font-size: 0.78rem;
  font-weight: 500;
  color: var(--ink);
  text-decoration: none;
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 3px 0;
  border-bottom: 1px solid var(--hairline-2);
  transition: border-color 0.12s ease;
}
.form-setup-rail-cta:hover { border-bottom-color: var(--ink-mute); }
.form-setup-rail-cta svg { flex-shrink: 0; }
.form-setup-rail-chips {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 2px 18px;
}
.setup-chip {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 0;
  font-size: 0.86rem;
  background: transparent;
  border: 0;
  color: var(--ink);
  text-decoration: none;
  transition: color 0.12s ease;
}
@media (hover: hover) { .setup-chip:hover .setup-chip-label { color: var(--ink); } }
.setup-chip-dot {
  width: 6px; height: 6px;
  border-radius: 999px;
  background: var(--ink-faint, #a8a29e);
  flex-shrink: 0;
}
.setup-chip[data-state="set"] .setup-chip-dot   { background: var(--green); }
.setup-chip[data-state="not-set"] .setup-chip-dot { background: var(--red); }
.setup-chip-label {
  flex: 1;
  font-weight: 500;
  color: var(--ink);
}
.setup-chip-state {
  color: var(--ink-mute);
  font-size: 0.78rem;
  font-family: 'JetBrains Mono', 'IBM Plex Mono', monospace;
}
.setup-chip[data-state="not-set"] .setup-chip-state { color: var(--red); font-weight: 500; }
@media (max-width: 420px) {
  .form-setup-rail-chips { grid-template-columns: 1fr; }
}

/* Two-column grid: editor on left, customer preview on right. Stacks on
   mobile so the editor takes priority.
   Lives as a sibling of .form-template (the v6 hero card above it) — got
   its own paper surface so the visual treatment of the editor + preview
   content stays exactly as it was when the grid sat inside .form-template. */
.form-template-grid {
  display: grid;
  grid-template-columns: 1.05fr 0.95fr;
  gap: 24px;
  align-items: start;
  background: var(--paper, #fff);
  border: 1px solid var(--hairline);
  border-radius: 14px;
  padding: 22px;
  margin-bottom: 24px;
}
@media (max-width: 880px) {
  .form-template-grid { grid-template-columns: 1fr; }
}

.form-template-editor { min-width: 0; }
.form-template-preview {
  min-width: 0;
  position: sticky;
  top: 24px;
}
.form-preview-eyebrow {
  font-family: 'JetBrains Mono', 'IBM Plex Mono', monospace;
  font-size: 0.66rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink-faint);
  margin-bottom: 10px;
}
.form-preview-frame {
  background: #EEEEF0;
  border: 1px solid var(--hairline);
  border-radius: 14px;
  padding: 22px;
}

/* Customer-side mockup card — looks like the form on the embedded site. */
.fp-card {
  background: var(--paper, #fff);
  border-radius: 12px;
  padding: 20px 20px 18px;
  box-shadow: 0 8px 24px -10px rgba(31, 22, 17, 0.18), 0 1px 2px rgba(31, 22, 17, 0.04);
}
.fp-bizname {
  font-family: 'JetBrains Mono', 'IBM Plex Mono', monospace;
  font-size: 0.66rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-faint);
  margin-bottom: 4px;
}
.fp-title {
  font-family: 'Newsreader', Georgia, serif;
  font-style: italic;
  font-weight: 500;
  font-size: 1.35rem;
  color: var(--ink);
  margin-bottom: 16px;
  letter-spacing: -0.015em;
}
.fp-row {
  display: block;
  margin-bottom: 12px;
}
.fp-label {
  display: block;
  font-size: 0.78rem;
  color: var(--ink-mute);
  margin-bottom: 5px;
  font-weight: 500;
}
.fp-input, .fp-select, .fp-textarea, .fp-photo {
  background: var(--cream);
  border: 1px solid var(--hairline);
  border-radius: 7px;
  padding: 8px 10px;
  font-size: 0.78rem;
  color: var(--ink);
  min-height: 30px;
}
.fp-input--placeholder { color: var(--ink-faint); }
.fp-textarea { min-height: 56px; }
.fp-select {
  display: flex;
  align-items: center;
  justify-content: space-between;
  color: var(--ink-faint);
}
.fp-caret { color: var(--ink-mute); font-size: 0.7rem; }
.fp-slots { display: flex; gap: 6px; flex-wrap: wrap; }
.fp-slot {
  background: var(--cream);
  border: 1px solid var(--hairline);
  border-radius: 5px;
  padding: 4px 10px;
  font-size: 0.7rem;
  color: var(--ink);
}
.fp-slot.is-on { background: var(--ink); color: var(--cream, #FAFAFA); border-color: var(--ink); }
.fp-photo {
  text-align: center;
  color: var(--ink-faint);
  border-style: dashed;
  font-size: 0.74rem;
}
.fp-cta {
  width: 100%;
  background: var(--ink);
  color: var(--cream, #FAFAFA);
  border: 0;
  border-radius: 8px;
  padding: 10px;
  font-family: inherit;
  font-size: 0.86rem;
  font-weight: 500;
  margin-top: 8px;
  cursor: not-allowed;
  opacity: 0.95;
}
.fp-foot {
  text-align: center;
  font-size: 0.66rem;
  color: var(--ink-faint);
  margin-top: 10px;
  font-family: 'JetBrains Mono', 'IBM Plex Mono', monospace;
  letter-spacing: 0.06em;
}
.form-template-section-title {
  font-family: 'Geist', 'Inter Tight', 'Inter', sans-serif;
  font-weight: 500;
  font-size: 0.95rem;
  color: var(--ink);
  margin: 0 0 4px;
}
.form-template-section-title--services {
  margin-top: 28px;
  padding-top: 18px;
  border-top: 1px solid var(--hairline);
}
.form-template-section-sub {
  font-size: 0.82rem;
  color: var(--ink-mute);
  margin: 0 0 12px;
  line-height: 1.45;
}

.form-fields-list {
  display: flex;
  flex-direction: column;
  border: 1px solid var(--hairline);
  border-radius: 10px;
  overflow: hidden;
}
.form-field {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px 14px;
  border-bottom: 1px solid var(--hairline);
  background: var(--paper, #fff);
  transition: background 0.14s;
}
.form-field:last-child { border-bottom: 0; }
.form-field:hover { background: var(--cream); }
.form-field[data-hidden] { opacity: 0.5; }
.form-field[data-hidden] .form-field-label { text-decoration: line-through; }
.form-field-label {
  flex: 1;
  min-width: 0;
  background: transparent;
  border: 1px solid transparent;
  padding: 5px 8px;
  border-radius: 6px;
  font-family: inherit;
  font-size: 0.92rem;
  color: var(--ink);
  outline: none;
  transition: background 0.14s, border-color 0.14s;
}
.form-field-label:hover { background: var(--cream-2); }
.form-field-label:focus {
  background: var(--paper, #fff);
  border-color: var(--ink-mute);
}
.form-field-type {
  font-family: 'JetBrains Mono', 'IBM Plex Mono', monospace;
  font-size: 0.68rem;
  letter-spacing: 0.04em;
  color: var(--ink-faint);
  background: var(--cream-2);
  padding: 3px 8px;
  border-radius: 5px;
  flex-shrink: 0;
}
.form-field-meta {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  font-family: 'JetBrains Mono', 'IBM Plex Mono', monospace;
  font-size: 0.66rem;
  letter-spacing: 0.06em;
  color: var(--ink-faint);
  text-transform: uppercase;
  flex-shrink: 0;
}
.form-field-toggle, .form-field-delete {
  background: transparent;
  border: 0;
  padding: 6px;
  border-radius: 6px;
  color: var(--ink-mute);
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  transition: background 0.14s, color 0.14s;
}
.form-field-toggle:hover { background: var(--cream-2); color: var(--ink); }
.form-field-delete:hover { background: rgba(199,74,28,0.1); color: var(--orange, #C74A1C); }

.form-field-add {
  margin-top: 12px;
  background: transparent;
  border: 1px dashed var(--hairline-2, var(--hairline));
  border-radius: 8px;
  padding: 10px 14px;
  font-family: inherit;
  font-size: 0.85rem;
  color: var(--ink-mute);
  cursor: pointer;
  width: 100%;
  text-align: center;
  transition: color 0.14s, border-color 0.14s, background 0.14s;
}
.form-field-add:hover {
  color: var(--ink);
  border-color: var(--ink-mute);
  background: var(--cream);
}

/* Service-picker row — clickable to expand the inline services panel. */
.form-field--picker { background: var(--cream); }
.form-field-services-btn {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  background: var(--paper, #fff);
  border: 1px solid var(--hairline);
  border-radius: 7px;
  padding: 5px 10px;
  font-family: inherit;
  font-size: 0.78rem;
  color: var(--ink);
  cursor: pointer;
  flex-shrink: 0;
  transition: border-color 0.14s, background 0.14s;
}
.form-field-services-btn:hover { border-color: var(--ink-mute); background: var(--cream-2); }
.form-field-services-count { font-weight: 500; }
.form-field-services-chev {
  display: inline-flex;
  color: var(--ink-mute);
  transition: transform 0.18s cubic-bezier(0.2, 0, 0, 1);
}
.form-field-services-btn[aria-expanded="true"] .form-field-services-chev {
  transform: rotate(180deg);
}

/* Services panel that expands under the picker row. Sits inside the
   field-list container, separated by hairlines from neighbour rows. */
.form-services-panel {
  background: var(--cream-2);
  border-bottom: 1px solid var(--hairline);
}
.form-services-panel-inner {
  padding: 18px 18px 18px;
}
.form-services-title {
  font-family: 'Geist', 'Inter Tight', 'Inter', sans-serif;
  font-weight: 500;
  font-size: 0.92rem;
  color: var(--ink);
  margin: 0 0 4px;
}
.form-services-sub {
  font-size: 0.8rem;
  color: var(--ink-mute);
  margin: 0 0 12px;
  line-height: 1.45;
}
.form-services-empty {
  font-size: 0.85rem;
  color: var(--ink-faint);
  margin: 0 0 14px;
  padding: 12px 0;
  text-align: center;
}
.form-services-list {
  display: flex;
  flex-direction: column;
  background: var(--paper, #fff);
  border: 1px solid var(--hairline);
  border-radius: 8px;
  overflow: hidden;
  margin-bottom: 14px;
}

/* jt-card list nested inside the inline services panel — slightly tighter
   spacing + drop the outer wrapper background since the panel already
   provides the cream tint. */
.jt-list--in-panel {
  display: flex;
  flex-direction: column;
  gap: 10px;
  margin-bottom: 14px;
}

/* Compact card variant for the inline panel. The full .jt-card grid was
   designed for the standalone Job types page (~880px); inside the picker
   panel it's ~440px wide, so the head + actions overlap and stats wrap
   awkwardly. Override to a clean vertical flow with the duplicates hidden. */
.jt-list--in-panel .jt-card {
  display: block !important;
  padding: 14px 16px !important;
  background: var(--paper, #fff) !important;
  border-radius: 10px;
}
.jt-list--in-panel .jt-icon { display: none !important; }

/* Head: name + small status pill on one row, actions on the right. */
.jt-list--in-panel .jt-head {
  display: flex !important;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px;
  margin: 0 0 8px;
}
.jt-list--in-panel .jt-name {
  font-size: 1rem !important;
  font-weight: 500;
  margin: 0;
  flex: 1 1 auto;
  min-width: 0;
}
/* Drop the AUTO-CONFIRM / BOOKABLE pills — same info shown by the toggles
   in .jt-fields below, no need to duplicate. */
.jt-list--in-panel .jt-pill { display: none !important; }
.jt-list--in-panel .jt-status-pill {
  font-size: 0.66rem;
  padding: 3px 8px;
  margin-left: 4px;
}

/* Stats row (Avg / Deposit) — sits inline under the name, compact. */
.jt-list--in-panel .jt-stats {
  display: flex !important;
  flex-wrap: nowrap;
  gap: 8px;
  font-size: 0.78rem;
  color: var(--ink-mute);
  margin: 0 0 10px;
}
.jt-list--in-panel .jt-stats strong {
  color: var(--ink);
  font-weight: 500;
}
.jt-list--in-panel .jt-stats .dot {
  display: inline-block;
  width: 3px;
  height: 3px;
  border-radius: 50%;
  background: var(--ink-faint);
  align-self: center;
}

/* Actions: small text buttons in the head row, right-aligned. */
.jt-list--in-panel .jt-actions {
  display: inline-flex !important;
  gap: 4px;
  margin: 0 0 0 auto;
  flex-shrink: 0;
}
.jt-list--in-panel .jt-action {
  font-size: 0.76rem !important;
  padding: 4px 10px !important;
  border-radius: 6px;
}

/* Fields grid (toggleable controls) — 2 columns when narrow. Hide the
   static Duration + Deposit fields since .jt-stats above already shows
   them; keep only the toggle fields. */
.jt-list--in-panel .jt-fields {
  grid-template-columns: repeat(2, 1fr) !important;
  gap: 8px !important;
  padding: 10px 0 !important;
  margin: 0 !important;
  border-top: 1px solid var(--hairline) !important;
  border-bottom: 1px solid var(--hairline) !important;
}
.jt-list--in-panel .jt-field {
  padding: 6px 0 !important;
}
/* Static Duration + Deposit fields are always the first two .jt-field
   children — they duplicate the .jt-stats row above. Hide so only the
   functional toggle fields (Auto-confirm + After-hours) remain. */
.jt-list--in-panel .jt-fields .jt-field:nth-child(1),
.jt-list--in-panel .jt-fields .jt-field:nth-child(2) { display: none !important; }

/* Keywords row + booking row stay but get tighter spacing. */
.jt-list--in-panel .jt-keywords {
  padding: 10px 0 6px !important;
  gap: 6px !important;
}
.jt-list--in-panel .jt-booking-row {
  padding: 8px 0 0 !important;
  border-top: 0 !important;
}
.jt-list--in-panel .jt-booking-row .set-toggle-name { font-size: 0.85rem; }
.jt-list--in-panel .jt-booking-row .set-toggle-desc { font-size: 0.75rem; }

/* Fallback card sits flush with the rest in the panel. */
.jt-list--in-panel .jt-card.is-fallback {
  background: var(--cream) !important;
  border: 1px dashed var(--hairline-2, var(--hairline));
}
.jt-list--in-panel .jt-card.is-fallback .jt-fallback-body {
  font-size: 0.82rem;
  margin-top: 8px;
}
.form-services-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 10px 12px;
  border-bottom: 1px solid var(--hairline);
}
.form-services-row:last-child { border-bottom: 0; }
.form-services-row-text { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.form-services-row-name {
  font-size: 0.88rem;
  font-weight: 500;
  color: var(--ink);
}
.form-services-row-meta {
  font-size: 0.74rem;
  color: var(--ink-faint);
  font-family: 'JetBrains Mono', 'IBM Plex Mono', monospace;
}
.form-services-row-remove {
  background: transparent;
  border: 0;
  padding: 6px;
  border-radius: 6px;
  color: var(--ink-mute);
  cursor: pointer;
  display: inline-flex;
  align-items: center;
}
.form-services-row-remove:hover {
  background: rgba(199,74,28,0.1);
  color: var(--orange, #C74A1C);
}

.form-services-add-head {
  font-family: 'JetBrains Mono', 'IBM Plex Mono', monospace;
  font-size: 0.66rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-faint);
  margin: 0 0 8px;
}
.form-services-starters {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 6px;
  margin-bottom: 10px;
}
.form-services-starter {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 8px 10px;
  background: var(--paper, #fff);
  border: 1px solid var(--hairline);
  border-radius: 7px;
  font-family: inherit;
  font-size: 0.82rem;
  color: var(--ink);
  cursor: pointer;
  text-align: left;
  transition: border-color 0.14s, background 0.14s;
}
.form-services-starter:hover { border-color: var(--ink-mute); background: var(--cream); }
.form-services-starter svg { color: var(--ink-mute); flex-shrink: 0; }
.form-services-custom-add { margin-top: 0; }

/* === Forms tab — Lovable v2 redesign (cream cards, C2 buttons) ========== */

/* Warm border/shadow shorthand */
:root {
  --fd-border: rgba(31,22,17,0.06);
  --fd-border-btn: rgba(31,22,17,0.13);
  --fd-border-btn-bot: rgba(31,22,17,0.19);
  --fd-shadow-card: 0 1px 2px rgba(31,22,17,0.04);
  --fd-card-bg: #F5F5F5;
  --fd-card-radius: 12px;
}

/* Page title + subtitle */
.fd-page-title {
  font-size: 1.25rem;
  font-weight: 700;
  color: var(--ink);
  margin: 0 0 4px;
}
.fd-page-sub {
  font-size: 0.875rem;
  color: #6B5A4C;
  margin: 0 0 16px;
  line-height: 1.5;
}

/* Generic bordered card (cream fill) */
.fd-card {
  background: var(--fd-card-bg);
  border: 1px solid var(--fd-border);
  border-radius: var(--fd-card-radius);
  box-shadow: var(--fd-shadow-card);
  overflow: hidden;
  margin-bottom: 8px;
}

/* C2 button — white gradient on cream, 3D feel */
.fd-btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  font-family: inherit; font-size: 0.8125rem; font-weight: 500;
  color: var(--ink);
  background: linear-gradient(180deg, #FFFFFF 0%, #F8F8F8 100%);
  border: 1px solid var(--fd-border-btn);
  border-bottom-color: var(--fd-border-btn-bot);
  border-radius: 8px;
  padding: 7px 14px;
  cursor: pointer;
  box-shadow: 0 1px 3px rgba(31,22,17,0.07), 0 2px 1px -1px rgba(31,22,17,0.04), inset 0 1px 0 rgba(255,255,255,0.9);
  transition: all 0.15s ease;
  -webkit-tap-highlight-color: transparent;
  text-decoration: none;
}
.fd-btn:hover { border-color: rgba(31,22,17,0.2); border-bottom-color: rgba(31,22,17,0.26); box-shadow: 0 2px 5px rgba(31,22,17,0.09), 0 2px 1px -1px rgba(31,22,17,0.04), inset 0 1px 0 rgba(255,255,255,0.9); }
.fd-btn:active { transform: translateY(0.5px); box-shadow: 0 0 2px rgba(31,22,17,0.05), inset 0 1px 0 rgba(255,255,255,0.7); }
.fd-btn svg { width: 13px; height: 13px; }

/* Ghost button — transparent on cream */
.fd-btn--ghost {
  background: transparent;
  border: 1px solid rgba(31,22,17,0.1);
  box-shadow: none;
  color: #6B5A4C;
}
.fd-btn--ghost:hover { border-color: rgba(31,22,17,0.18); color: var(--ink); background: rgba(31,22,17,0.02); box-shadow: none; }
.fd-btn--ghost:active { box-shadow: none; }

/* Section link */
.fd-section-link {
  font-size: 0.8125rem;
  font-weight: 500;
  color: #6B5A4C;
  text-decoration: none;
}
.fd-section-link:hover { color: var(--ink); }

/* Rules rows */
.fd-rule {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 11px 16px;
  font-size: 0.875rem;
  color: var(--ink);
  text-decoration: none;
  transition: background 0.12s;
}
.fd-rule + .fd-rule { border-top: 1px solid var(--fd-border); }
@media (hover: hover) { .fd-rule:hover { background: rgba(31,22,17,0.02); } }
.fd-rule__dot { display: none; }
.fd-rule__label { font-weight: 500; }
.fd-rule__value {
  font-size: 0.875rem;
  color: #A39585;
  display: flex;
  align-items: center;
  gap: 4px;
}
.fd-rule__value::after {
  content: '\203A';
  font-size: 1.1rem;
  color: #CCC;
  line-height: 1;
  margin-left: 2px;
}
.fd-rule[data-state="not-set"] .fd-rule__value { color: var(--red, #C74A1C); }

/* Inline rules — flat rows without a card wrapper */
.fd-rules-inline .fd-rule { padding: 13px 0; }
.fd-rules-inline .fd-rule:first-child { border-top: 1px solid var(--fd-border); }

/* Connection card — three-state status dot (green / amber / gray)
   driven by data-dot, set by hydrateFdConnection() in wire.js. The two
   surfaces (embedded landing-page widget + standalone /book or /quote
   link) are rendered as a stack of label/value rows so the tradie can
   see at a glance which path is live. */
.fd-connection {
  background: var(--fd-card-bg);
  border: 1px solid var(--fd-border);
  border-radius: var(--fd-card-radius);
  box-shadow: var(--fd-shadow-card);
  padding: 14px 16px;
  margin-bottom: 0;
}
.fd-connection__status {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 8px;
}
.fd-connection__dot {
  width: 8px; height: 8px; border-radius: 50%; flex-shrink: 0;
  background: #A39585;
}
.fd-connection[data-dot="green"] .fd-connection__dot { background: #22C55E; }
.fd-connection[data-dot="amber"] .fd-connection__dot { background: #D97706; }
.fd-connection[data-dot="gray"]  .fd-connection__dot { background: #A39585; }
.fd-connection__title { font-size: 1.1rem; font-weight: 600; color: var(--ink); }
.fd-connection__surfaces {
  display: flex; flex-direction: column; gap: 8px;
  padding-top: 10px; margin-top: 4px;
  border-top: 1px solid var(--fd-border);
}
.fd-connection__surface {
  display: flex; justify-content: space-between; align-items: center;
  gap: 12px; font-size: 0.82rem;
}
.fd-connection__surface--url { align-items: flex-start; flex-direction: column; gap: 4px; }
.fd-connection__surface-label { color: #6B5A4C; }
.fd-connection__surface-val { color: var(--ink); font-weight: 500; }
.fd-connection[data-state="connected"] .fd-connection__surface-val { color: #16a34a; }
.fd-connection[data-state="wrong-flow"] .fd-connection__surface-val,
.fd-connection[data-state="paused"]     .fd-connection__surface-val { color: #92400E; }
.fd-connection__url-row {
  display: flex; align-items: center; gap: 8px;
  width: 100%;
  font-size: 0.82rem;
}
.fd-connection__url {
  flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  color: var(--ink); text-decoration: none;
  font-family: 'JetBrains Mono', 'IBM Plex Mono', monospace;
  font-size: 0.78rem;
}
.fd-connection__url:hover { text-decoration: underline; }
.fd-connection__copy { padding: 5px 12px; font-size: 0.75rem; flex-shrink: 0; }
.fd-connection__count {
  margin-top: 10px; padding-top: 10px;
  border-top: 1px solid var(--fd-border);
  font-family: 'Geist Mono', 'JetBrains Mono', monospace;
  font-size: 0.7rem; letter-spacing: 0.08em;
  text-transform: uppercase; color: #A39585;
}
/* Action CTA — reuses .fd-btn for the 3d white-gradient look that
   matches every other primary action on the Forms page. Just add the
   margin-top to space it below the count line. */
.fd-connection__action { margin-top: 12px; }

/* Block section */
.fd-block { margin: 20px 0 10px; }
.fd-block__head {
  display: flex; align-items: baseline; justify-content: space-between; gap: 12px;
}
.fd-block__title { font-size: 1rem; font-weight: 600; color: var(--ink); }
.fd-block__count { font-size: 0.8125rem; color: #A39585; font-weight: 400; margin-left: 8px; }
.fd-block__sub { font-size: 0.8125rem; color: #6B5A4C; margin: 4px 0 0; line-height: 1.45; }

/* Field rows — cream card */
.fd-field-list {
  background: var(--fd-card-bg);
  border: 1px solid var(--fd-border);
  border-radius: var(--fd-card-radius);
  box-shadow: var(--fd-shadow-card);
  overflow: hidden;
}
.fd-field {
  display: flex; flex-direction: column; gap: 0; padding: 0 18px;
}
.fd-field + .fd-field { border-top: 1px solid var(--fd-border); }
.fd-field[data-hidden] { opacity: 0.45; }
.fd-field__row { display: flex; align-items: center; gap: 8px; padding: 10px 0 3px; }
.fd-field:not(:has(.fd-field__hint)) .fd-field__row { padding-bottom: 10px; }
.fd-field__hint { font-size: 0.6875rem; color: #A39585; line-height: 1.3; padding: 0 0 9px 4px; }
.fd-field__hint-link { color: #6B5A4C; font-weight: 500; text-decoration: none; }
.fd-field__hint-link:hover { color: var(--ink); }
.fd-field__dot { display: none; }
.fd-field__name {
  flex: 1; min-width: 0; font-size: 0.8125rem; font-weight: 500; color: var(--ink);
  background: transparent; border: 1px solid transparent; padding: 2px 4px;
  border-radius: 4px; font-family: inherit; outline: none;
  transition: background 0.14s, border-color 0.14s;
}
.fd-field__name:hover { background: rgba(31,22,17,0.03); }
.fd-field__name:focus { background: transparent; border-color: rgba(31,22,17,0.15); }
.fd-field__type {
  font-size: 0.6875rem; font-weight: 500; letter-spacing: 0.04em;
  text-transform: uppercase; color: #A39585; flex-shrink: 0;
  min-width: 56px; text-align: right; margin-right: 4px;
}
.fd-field__lock {
  color: #CCC; display: flex; align-items: center; justify-content: center;
  width: 28px; flex-shrink: 0;
}
.fd-field__lock svg { width: 14px; height: 14px; }

/* Toggle — indigo */
.fd-toggle {
  position: relative; width: 40px; height: 22px; border-radius: 11px;
  background: #D1D5DB; border: 0; cursor: pointer; flex-shrink: 0;
  transition: background 0.2s; padding: 0;
  box-shadow: inset 0 1px 2px rgba(0,0,0,0.08);
}
.fd-toggle::after {
  content: ''; position: absolute; top: 2px; left: 2px;
  width: 18px; height: 18px; border-radius: 50%;
  background: #FFFFFF; box-shadow: 0 1px 3px rgba(0,0,0,0.15);
  transition: transform 0.2s;
}
.fd-toggle.is-on { background: #4F46E5; box-shadow: none; }
.fd-toggle.is-on::after { transform: translateX(18px); }

/* Delete button */
.fd-field__delete {
  background: transparent; border: 0; padding: 4px; border-radius: 4px;
  color: #CCC; cursor: pointer; display: inline-flex; align-items: center;
  justify-content: center; transition: color 0.14s; flex-shrink: 0; margin-left: 2px;
}
.fd-field__delete:hover { color: var(--orange, #C74A1C); }
.fd-field__delete svg { width: 12px; height: 12px; }

/* Service cards — cream fill */
.fd-svc-list { display: flex; flex-direction: column; gap: 8px; }
.fd-svc {
  background: var(--fd-card-bg);
  border: 1px solid var(--fd-border);
  border-radius: var(--fd-card-radius);
  box-shadow: var(--fd-shadow-card);
  transition: border-color 0.14s;
  overflow: hidden;
}
.fd-svc:hover { border-color: rgba(31,22,17,0.12); }
.fd-svc__head {
  display: flex; align-items: center; gap: 12px; padding: 14px 18px;
  cursor: pointer; -webkit-tap-highlight-color: transparent;
}
.fd-svc__body { flex: 1; min-width: 0; }
.fd-svc__name { font-size: 0.9375rem; font-weight: 600; color: var(--ink); }
.fd-svc__meta { font-size: 0.8125rem; color: #6B5A4C; margin-top: 3px; }
.fd-svc__pill {
  font-size: 0.6875rem; font-weight: 600; letter-spacing: 0.04em;
  text-transform: uppercase; color: #22C55E;
  background: rgba(34,197,94,0.08); padding: 3px 8px;
  border-radius: 4px; flex-shrink: 0;
}
.fd-svc__pill.is-quote { background: rgba(31,22,17,0.04); color: #A39585; }
.fd-svc__chev { display: inline-flex; color: #CCC; flex-shrink: 0; transition: transform 0.2s; }
.fd-svc.is-open .fd-svc__chev { transform: rotate(180deg); }

/* Detail expand */
.fd-svc__detail-wrap {
  display: grid; grid-template-rows: 0fr;
  transition: grid-template-rows 0.28s cubic-bezier(0.2, 0, 0, 1);
}
.fd-svc.is-open .fd-svc__detail-wrap { grid-template-rows: 1fr; }
.fd-svc__detail { overflow: hidden; opacity: 0; transition: opacity 0.22s ease; }
.fd-svc.is-open .fd-svc__detail { opacity: 1; transition: opacity 0.22s ease 0.06s; }
.fd-svc__detail-inner { padding: 14px 18px 16px; border-top: 1px solid var(--fd-border); }
.fd-svc__stats { display: flex; gap: 14px; flex-wrap: wrap; font-size: 0.8125rem; color: #6B5A4C; padding: 8px 0; }
.fd-svc__stats strong { color: var(--ink); font-weight: 600; }
.fd-svc__stats .dot { display: inline-block; width: 3px; height: 3px; border-radius: 50%; background: #CCC; align-self: center; }
.fd-svc__toggles { display: grid; grid-template-columns: repeat(2, 1fr); gap: 8px; padding: 10px 0; border-top: 1px solid var(--fd-border); border-bottom: 1px solid var(--fd-border); }
.fd-svc__toggles .jt-field { padding: 6px 0; }
.fd-svc__detail-inner .jt-booking-row { padding: 8px 0 0; border-top: 0; }
.fd-svc__detail-inner .set-toggle-name { font-size: 0.85rem; }
.fd-svc__detail-inner .set-toggle-desc { font-size: 0.75rem; }
.fd-svc__actions { display: flex; gap: 6px; padding-top: 12px; border-top: 1px solid var(--fd-border); margin-top: 8px; }
.fd-svc__btn {
  font-family: inherit; font-size: 0.8125rem; font-weight: 500;
  color: #6B5A4C; background: transparent;
  border: 1px solid rgba(31,22,17,0.1); border-radius: 6px;
  padding: 6px 12px; cursor: pointer;
  transition: all 0.14s;
}
.fd-svc__btn:hover { border-color: rgba(31,22,17,0.18); color: var(--ink); }
.fd-svc__btn.is-danger:hover { color: var(--orange); border-color: var(--orange-deep); }

/* Add service */
.fd-add-row {
  display: flex; align-items: center; justify-content: center; gap: 8px;
  padding: 14px 18px;
  border: 1px dashed rgba(31,22,17,0.15); border-radius: var(--fd-card-radius);
  font-family: inherit; font-size: 0.875rem; font-weight: 500;
  color: #6B5A4C; cursor: pointer; background: transparent;
  width: 100%; box-sizing: border-box;
  transition: color 0.15s, border-color 0.15s;
}
.fd-add-row:hover { border-color: rgba(31,22,17,0.25); color: var(--ink); }
.fd-add-row svg { width: 14px; height: 14px; }

/* Quick-add chips — C2 pill style */
.fd-quick { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 12px; }
.fd-quick__chip {
  display: inline-flex; align-items: center;
  padding: 6px 16px;
  background: linear-gradient(180deg, #FFFFFF 0%, #F8F8F8 100%);
  border: 1px solid var(--fd-border-btn);
  border-bottom-color: var(--fd-border-btn-bot);
  border-radius: 100px;
  font-family: inherit; font-size: 0.8125rem; font-weight: 500;
  color: var(--ink); cursor: pointer;
  box-shadow: 0 1px 2px rgba(31,22,17,0.05), inset 0 1px 0 rgba(255,255,255,0.9);
  transition: all 0.15s;
}
.fd-quick__chip:hover { border-color: rgba(31,22,17,0.2); border-bottom-color: rgba(31,22,17,0.26); box-shadow: 0 2px 4px rgba(31,22,17,0.07), inset 0 1px 0 rgba(255,255,255,0.9); }

/* === Job types empty state — Builder-tier substantive markup ============ */
.jt-empty {
  display: flex;
  flex-direction: column;
  gap: 22px;
  padding: 8px 0 0;
}
.jt-empty-card {
  background: var(--paper, #fff);
  border: 1px solid var(--hairline);
  border-radius: 12px;
  padding: 28px 32px;
}
.jt-empty-title {
  font-family: 'Geist', 'Inter Tight', 'Inter', sans-serif;
  font-weight: 500;
  font-size: 1.5rem;
  letter-spacing: -0.018em;
  color: var(--ink);
  margin: 0 0 8px;
}
.jt-empty-sub {
  font-size: 0.95rem;
  color: var(--ink-mute);
  line-height: 1.55;
  margin: 0;
  max-width: 64ch;
  text-wrap: pretty;
}
.jt-starter-row {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 10px;
}
.jt-starter-chip {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 12px 14px;
  background: var(--paper, #fff);
  border: 1px solid var(--hairline);
  border-radius: 10px;
  font-family: inherit;
  font-size: 0.9rem;
  font-weight: 500;
  color: var(--ink);
  cursor: pointer;
  text-align: left;
  transition: border-color 0.18s cubic-bezier(0.2, 0, 0, 1), background 0.18s cubic-bezier(0.2, 0, 0, 1), transform 0.18s cubic-bezier(0.2, 0, 0, 1);
}
.jt-starter-chip:hover {
  border-color: var(--ink-mute);
  background: var(--cream-2);
  transform: translateY(-1px);
}
.jt-starter-chip svg { color: var(--ink-mute); flex-shrink: 0; }
.jt-starter-chip:disabled { cursor: not-allowed; }
.jt-empty-foot {
  display: flex;
  align-items: center;
  gap: 14px;
  padding-top: 4px;
  flex-wrap: wrap;
}
.jt-empty-foot .btn-primary {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}
.jt-empty-foot-meta {
  font-size: 0.85rem;
  color: var(--ink-mute);
  line-height: 1.4;
}
@media (max-width: 720px) {
  .jt-starter-row { grid-template-columns: 1fr; }
  .jt-empty-card { padding: 22px; }
}

@media (max-width: 640px) {
  .jt-card {
    grid-template-columns: 40px minmax(0, 1fr);
  }
  .jt-icon { grid-row: 1; width: 40px; height: 40px; }
  .jt-actions {
    grid-column: 1 / -1;
    grid-row: auto;
    margin-top: 8px;
    flex-wrap: wrap;
  }
  .jt-stats { grid-column: 1 / -1; }
  .jt-head { grid-column: 2; }
  .jt-fields, .jt-keywords { grid-column: 1 / -1; }
}

/* ============================================================================
   Phase 1 polish: focus rings, rp-chip pill, sticky save bar glass, tabular nums
   ========================================================================== */

/* rp-chip filter pills (Booking requests) — match .chip pattern */
.rp-chip {
  background: transparent;
  border: 1px solid var(--hairline-2);
  padding: 6px 12px;
  border-radius: 6px;
  font-family: inherit;
  font-size: 0.78rem;
  font-weight: 500;
  color: var(--ink-mute);
  cursor: pointer;
  transition: background 0.18s cubic-bezier(0.2, 0, 0, 1), color 0.18s cubic-bezier(0.2, 0, 0, 1), border-color 0.18s cubic-bezier(0.2, 0, 0, 1);
}
.rp-chip:hover { border-color: var(--hairline-3); color: var(--ink); }
.rp-chip.is-active {
  background: var(--ink);
  border-color: var(--ink);
  color: var(--cream);
}
.rp-chip-count {
  font-family: 'JetBrains Mono', monospace;
  font-size: 0.6rem;
  margin-left: 6px;
  color: var(--ink-faint);
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum" 1, "lnum" 1;
}
.rp-chip.is-active .rp-chip-count { color: rgba(255,255,255,0.6); }

/* Focus rings on settings inputs (theme-aware orange wash) */
.set-input:focus, .set-textarea:focus, .set-select:focus {
  box-shadow: 0 0 0 3px var(--orange-wash);
}
.set-input:focus-visible, .set-textarea:focus-visible, .set-select:focus-visible {
  outline: 0;
  border-color: var(--ink-mute);
  box-shadow: 0 0 0 3px var(--orange-wash);
}
.rp-conv-search:focus {
  outline: none;
  border-color: var(--ink-mute);
  box-shadow: 0 0 0 3px var(--orange-wash);
}
.rp-conv-compose textarea:focus {
  box-shadow: 0 0 0 3px var(--orange-wash);
}
.rp-meta-notes:focus {
  outline: none;
  border-color: var(--ink-mute);
  box-shadow: 0 0 0 3px var(--orange-wash);
}

/* Glass on sticky save bar. The base sticky/border/padding chrome is in
   dashboard-v2.css under "Settings sticky save bar" — this only paints the
   glass background so the rule sits next to the rest of the glass surfaces. */
.set-actions {
  background: var(--glass-bg) !important;
  backdrop-filter: saturate(140%) blur(14px) !important;
  -webkit-backdrop-filter: saturate(140%) blur(14px) !important;
}

/* Sticky settings rail — transparent on desktop so it reads as part
   of the page surface (Claude-style), not a separate white card.
   Hover + active fills on .set-rail-link still pop because they use
   warm cream tones darker than the page background. */
@media (min-width: 901px) {
  .set-rail {
    background: transparent;
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
  }
}

/* Tabular numerals — sub-page-specific number-bearing classes */
.intg-status, .jt-stats, .jt-stats strong, .jt-pill, .jt-keyword,
.set-account-val, .set-mini-intg-status, .ntf-quiet-meta, .ntf-quiet-range,
.rp-row-meta, .rp-thread-time, .rp-msg-time, .rp-msg-status,
.rp-conv-head-meta, .rp-meta-customer-meta, .rp-meta-booking-status,
.cal-time-cell, .cal-event-time, .cal-event-meta, .cal-sync-meta,
.pay-cust-sub, .pay-amt, .pay-pill, .pay-date, .pay-inv,
.set-pill, .chip-count, .rich-subtitle, .pg-sub,
.set-account-label, .jt-field-value, .jt-field-label {
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum" 1, "lnum" 1;
}

/* === Print styles ======================================================== */
@media print {
  body { background: #fff !important; }
  .side, .mobile-nav, .upsell, .attention-strip, .empty-card-back, .btn, .pg-actions, .rich-actions, [data-no-print] { display: none !important; }
  .shell { grid-template-columns: 1fr !important; }
  .dash, .pg, .rich-page { padding: 24px !important; max-width: 720px; margin: 0 auto; }
  .metric, .set-card, .pay-card, .activity-feed, .rec-hero, .site-card, .panel, .upsell {
    box-shadow: none !important;
    border: 1px solid #ddd !important;
    page-break-inside: avoid;
    background: #fff !important;
  }
  .pg-head, .rich-head, .dash-greeting { border-bottom: 1px solid #999; padding-bottom: 12px; margin-bottom: 16px; }
  .pg-head::after { content: 'BookingSprint · Printed ' attr(data-print-date); display: block; font-size: 0.7rem; color: #666; margin-top: 6px; font-family: 'JetBrains Mono', monospace; }
  a { color: #1F1611 !important; text-decoration: underline; }
  a[href]::after { content: ' (' attr(href) ')'; font-size: 0.7em; color: #666; }
  /* Tabular alignment for printed lists */
  .pay-row, .activity-feed { font-variant-numeric: tabular-nums; }
}

/* ---------- Live AI choreography (Conversations) ---------- */

/* 1. Typewriter cursor */
.rp-msg-typer { display: inline; }
.rp-msg.is-typing::after {
  content: '';
  display: inline-block;
  width: 2px;
  height: 1em;
  background: currentColor;
  margin-left: 2px;
  vertical-align: text-bottom;
  animation: bs-cursor-blink 0.9s step-end infinite;
}
@keyframes bs-cursor-blink {
  50% { opacity: 0; }
}
@media (prefers-reduced-motion: reduce) {
  .rp-msg.is-typing::after { display: none; }
}

/* 3. Thinking-state diamond-rosette */
@keyframes bs-diamond-pulse-1 { 0%, 100% { opacity: 0.3; } 12% { opacity: 1; } }
@keyframes bs-diamond-pulse-2 { 0%, 100% { opacity: 0.3; } 24% { opacity: 1; } }
@keyframes bs-diamond-pulse-3 { 0%, 100% { opacity: 0.3; } 36% { opacity: 1; } }
@keyframes bs-diamond-pulse-4 { 0%, 100% { opacity: 0.3; } 48% { opacity: 1; } }
@keyframes bs-diamond-pulse-5 { 0%, 100% { opacity: 0.3; } 60% { opacity: 1; } }
@keyframes bs-diamond-pulse-6 { 0%, 100% { opacity: 0.3; } 72% { opacity: 1; } }
@keyframes bs-diamond-pulse-7 { 0%, 100% { opacity: 0.3; } 84% { opacity: 1; } }
@keyframes bs-diamond-pulse-8 { 0%, 100% { opacity: 0.3; } 96% { opacity: 1; } }
.bs-thinking-mark {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 8px 12px;
  background: var(--orange-wash, rgba(217, 84, 30, 0.08));
  border: 1px solid var(--hairline);
  border-radius: 12px;
  font-family: 'JetBrains Mono', monospace;
  font-size: 0.62rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--orange);
  font-weight: 600;
}
.bs-thinking-mark svg { width: 16px; height: 16px; }
.bs-thinking-mark svg .d:nth-child(1) { animation: bs-diamond-pulse-1 1.6s ease-in-out infinite; transform-origin: center; }
.bs-thinking-mark svg .d:nth-child(2) { animation: bs-diamond-pulse-2 1.6s ease-in-out infinite; transform-origin: center; }
.bs-thinking-mark svg .d:nth-child(3) { animation: bs-diamond-pulse-3 1.6s ease-in-out infinite; transform-origin: center; }
.bs-thinking-mark svg .d:nth-child(4) { animation: bs-diamond-pulse-4 1.6s ease-in-out infinite; transform-origin: center; }
.bs-thinking-mark svg .d:nth-child(5) { animation: bs-diamond-pulse-5 1.6s ease-in-out infinite; transform-origin: center; }
.bs-thinking-mark svg .d:nth-child(6) { animation: bs-diamond-pulse-6 1.6s ease-in-out infinite; transform-origin: center; }
.bs-thinking-mark svg .d:nth-child(7) { animation: bs-diamond-pulse-7 1.6s ease-in-out infinite; transform-origin: center; }
.bs-thinking-mark svg .d:nth-child(8) { animation: bs-diamond-pulse-8 1.6s ease-in-out infinite; transform-origin: center; }
@media (prefers-reduced-motion: reduce) {
  .bs-thinking-mark svg .d { animation: none; opacity: 1; }
}
.rp-thinking-row {
  display: flex;
  justify-content: flex-start;
  margin: var(--space-3, 12px) 0;
  padding-left: var(--space-3, 12px);
}

/* 4. AI confidence bar */
.rp-msg-confidence {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 6px 10px;
  margin-top: 6px;
  font-family: 'JetBrains Mono', monospace;
  font-size: 0.56rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-faint);
  font-weight: 600;
  max-width: 320px;
  align-self: flex-end;
}
.rp-confidence-label { color: var(--ink-mute); }
.rp-confidence-bar {
  flex: 1;
  height: 4px;
  background: var(--cream-2);
  border-radius: 999px;
  overflow: hidden;
}
.rp-confidence-fill {
  display: block;
  height: 100%;
  background: linear-gradient(90deg, var(--orange-soft), var(--orange));
  border-radius: 999px;
  width: 0;
  transition: width 0.8s var(--ease-out, cubic-bezier(0.2, 0, 0, 1));
}
.rp-msg-confidence.is-low .rp-confidence-fill { background: linear-gradient(90deg, var(--ink-faint), var(--ink-mute)); }
.rp-confidence-value { color: var(--ink); }
@media (prefers-reduced-motion: reduce) {
  .rp-confidence-fill { transition: none; }
}

/* 5. Thread header AI active pill */
.rp-thread-status {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-family: 'JetBrains Mono', monospace;
  font-size: 0.56rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--green);
  background: var(--green-soft);
  padding: 3px 8px;
  border-radius: 999px;
  font-weight: 600;
  margin-left: 8px;
  vertical-align: middle;
}

/* 6. Live AI choreography (typewriter caret + status pill + suggestions) */
.is-typing { position: relative; }
.is-typing::after {
  content: '';
  display: inline-block;
  width: 2px; height: 1em;
  background: var(--orange);
  margin-left: 2px;
  vertical-align: text-bottom;
  animation: bs-caret 0.9s ease-in-out infinite;
}
@keyframes bs-caret {
  0%, 50% { opacity: 1; }
  51%, 100% { opacity: 0; }
}
@media (prefers-reduced-motion: reduce) {
  .is-typing::after { display: none; }
}

.ai-status {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 6px 10px;
  background: var(--orange-wash);
  border-radius: 999px;
  font-family: 'JetBrains Mono', monospace;
  font-size: 0.6rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--orange-deep);
  font-weight: 600;
  transition: background 0.4s var(--ease-out, cubic-bezier(0.2, 0, 0, 1)), color 0.4s var(--ease-out, cubic-bezier(0.2, 0, 0, 1));
}
.ai-status-mark rect {
  transform-origin: center;
  animation: bs-diamond-pulse-status 1.6s ease-in-out infinite;
}
.ai-status-mark .d1 { animation-delay: 0.00s; }
.ai-status-mark .d2 { animation-delay: 0.10s; }
.ai-status-mark .d3 { animation-delay: 0.20s; }
.ai-status-mark .d4 { animation-delay: 0.30s; }
.ai-status-mark .d5 { animation-delay: 0.40s; }
.ai-status-mark .d6 { animation-delay: 0.50s; }
.ai-status-mark .d7 { animation-delay: 0.60s; }
.ai-status-mark .d8 { animation-delay: 0.70s; }
@keyframes bs-diamond-pulse-status {
  0%, 100% { opacity: 0.3; transform: scale(1); }
  20%      { opacity: 1;   transform: scale(1.15); }
  60%      { opacity: 0.3; transform: scale(1); }
}
.ai-status.is-idle .ai-status-mark rect { animation-play-state: paused; opacity: 1; }
.ai-status.is-idle { background: var(--green-soft); color: var(--green); }
@media (prefers-reduced-motion: reduce) {
  .ai-status-mark rect { animation: none; opacity: 1; }
}

.ai-suggest-block {
  padding: 14px;
  background: var(--paper);
  border: 1px solid var(--hairline);
  border-radius: var(--card-radius);
}
.ai-suggest-title {
  font-family: 'JetBrains Mono', monospace;
  font-size: 0.56rem; letter-spacing: 0.18em; text-transform: uppercase;
  color: var(--ink-faint); font-weight: 600;
  margin-bottom: 10px;
}
.ai-suggest {
  display: block; width: 100%; text-align: left;
  background: transparent; border: 0;
  padding: 8px 0;
  cursor: pointer;
  border-top: 1px solid var(--hairline);
  transition: background 0.18s cubic-bezier(0.2, 0, 0, 1), padding 0.18s cubic-bezier(0.2, 0, 0, 1);
  font-family: inherit;
}
.ai-suggest:first-of-type { border-top: 0; }
.ai-suggest:hover { background: var(--cream-2); padding-left: 8px; padding-right: 8px; border-radius: 8px; }
.ai-suggest-text {
  font-size: 0.86rem; color: var(--ink); font-weight: 500;
  margin-bottom: 6px; line-height: 1.4;
}
.ai-suggest-bar {
  height: 3px; background: var(--cream-3); border-radius: 999px; overflow: hidden;
  margin-bottom: 4px;
}
.ai-suggest-bar-fill {
  height: 100%;
  background: linear-gradient(90deg, var(--orange-soft), var(--orange));
  border-radius: 999px;
  transition: width 0.6s cubic-bezier(0.2, 0, 0, 1);
}
.ai-suggest-meta {
  font-family: 'JetBrains Mono', monospace;
  font-size: 0.58rem; letter-spacing: 0.1em;
  color: var(--ink-faint); text-transform: uppercase;
}
.ai-suggest-meta span { color: var(--ink); font-weight: 600; }

@keyframes rp-compose-flash {
  0%   { box-shadow: 0 0 0 0 rgba(217, 84, 30, 0.32); }
  100% { box-shadow: 0 0 0 6px rgba(217, 84, 30, 0); }
}
.rp-compose-flash { animation: rp-compose-flash 0.6s cubic-bezier(0.2, 0, 0, 1); }

/* Sidebar footer account card overrides — two-line stack (business + email)
   plus an icon-only sign-out button. Falls back gracefully if the email
   field is empty (no extra row). */
.side-foot { align-items: center; }
.side-foot-name {
  display: flex; flex-direction: column; gap: 1px;
  flex: 1 1 auto; min-width: 0;
  white-space: normal; overflow: hidden;
}
.side-foot-name-business {
  font-size: 13px; line-height: 1.2;
  color: var(--ink); font-weight: 500;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.side-foot-name-email {
  font-size: 11px; line-height: 1.2;
  color: var(--ink-mute);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.side-foot-name-email:empty { display: none; }
.side-foot-signout {
  flex: 0 0 auto;
  width: 24px; height: 24px;
  display: inline-flex; align-items: center; justify-content: center;
  background: transparent; border: 0; padding: 0;
  border-radius: 6px; cursor: pointer;
  color: var(--ink-mute);
  transition: background 0.18s ease, color 0.18s ease;
}
.side-foot-signout:hover { background: var(--cream-2); color: var(--ink); }
.side-foot-signout:focus-visible { outline: 2px solid var(--ink); outline-offset: 2px; }

/* ============================================================================
   Mobile shell — top bar + side drawer (visible only at <720px).
   Hidden by default on desktop. Drawer slides in from the left over a
   semi-transparent backdrop. Esc + backdrop tap + nav-link tap all close it.
   ========================================================================== */
.mob-topbar { display: none; }
.mob-drawer-backdrop { display: none; }
.mob-drawer-close { display: none; }

@media (max-width: 899.98px) {
  .mob-topbar {
    display: flex;
    align-items: center;
    gap: 10px;
    height: 52px;
    padding: 0 12px;
    background: var(--topband);
    position: fixed;
    top: 0; left: 0; right: 0;
    z-index: 70;
    will-change: transform;
  }
  /* Burger inherits C2 styling from dashboard-v2.css — no override needed */
  .mob-topbar-glass { display: none; }
  body.is-builder-chat .mob-topbar-glass { display: block; }
  .mob-topbar-title {
    flex: 1 1 auto;
    min-width: 0;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    color: var(--ink);
  }
  .mob-topbar-mark {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 20px;
    height: 20px;
    line-height: 0;
    flex-shrink: 0;
  }
  .mob-topbar-mark svg { width: 100%; height: 100%; display: block; }
  .mob-topbar-mark .bs-logo-mark__d { fill: var(--ink); }
  .mob-topbar-name {
    font-family: 'Geist', 'Inter Tight', 'Inter', sans-serif;
    font-size: 0.95rem;
    font-weight: 600;
    color: var(--ink);
    letter-spacing: -0.01em;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  }
  .mob-topbar-spacer {
    flex: 0 0 auto;
    width: 48px; height: 48px;
    display: inline-block;
  }

  /* Card-slide drawer: sidebar parked at left:0 below the card; page
     surface slides right to reveal it. See dashboard-v2.css for the
     full commentary — kept in sync here for sub-route SPA shell. */
  body { --drawer-offset: 0px; }
  body.mob-drawer-open { --drawer-offset: min(360px, 84vw); }

  .side {
    position: fixed !important;
    top: 0; left: 0;
    height: 100vh;
    width: min(360px, 84vw);
    transform: none;
    z-index: 1;
    border-right: 1px solid var(--hairline-2);
    display: flex !important;
    background: var(--topband);
  }

  .mob-topbar,
  .shell > main.dash,
  .shell > .pg,
  .shell > .rich-page {
    transform: translateX(var(--drawer-offset));
    transition: transform 0.32s cubic-bezier(0.2, 0, 0, 1),
                border-radius 0.32s cubic-bezier(0.2, 0, 0, 1),
                box-shadow 0.32s cubic-bezier(0.2, 0, 0, 1);
  }
  .mob-topbar { z-index: 70; }
  .shell > main.dash,
  .shell > .pg,
  .shell > .rich-page {
    position: relative;
    z-index: 10;
    background: var(--topband);
    /* Cover the sidebar even when content is shorter than viewport. */
    min-height: calc(100dvh - 52px);
  }

  /* Breathing room below the floating topbar for every rich-mounted page
     (Inbox / Calendar / Missed calls / My site / Settings / …). These pages
     put their title in the topbar, so their first card/toolbar would otherwise
     sit flush against the burger button. One rule here keeps the gap uniform
     instead of per-page padding (founder 2026-06-06). */
  [data-rich-mount] { padding-top: 18px; }

  body.mob-drawer-open .mob-topbar {
    border-top-left-radius: 22px;
    overflow: hidden;
    padding-left: 22px;
    /* Left-edge hairline only — main.dash's full-height shadow underneath
       owns the soft left-edge lift (one continuous shadow, curves at the
       rounded top corner). A separate topbar lift shadow looked darker/
       concentrated + mismatched at the top (founder 2026-06-06). DUPLICATE of
       the dashboard-v2.css rule; builder loads this sheet last. */
    box-shadow: -1px 0 0 0 rgba(31, 22, 17, 0.08);
  }
  body.mob-drawer-open .shell > main.dash,
  body.mob-drawer-open .shell > .pg,
  body.mob-drawer-open .shell > .rich-page {
    border-top-left-radius: 22px;
    border-bottom-left-radius: 22px;
    box-shadow:
      -1px 0 0 0 rgba(31, 22, 17, 0.08),
      -6px 0 22px -8px rgba(31, 22, 17, 0.18);
  }
  .side { border-right: 0 !important; }

  .mob-drawer-backdrop {
    display: block;
    position: fixed;
    top: 0;
    bottom: 0;
    left: var(--drawer-offset);
    right: 0;
    background: transparent;
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.22s cubic-bezier(0.2, 0, 0, 1),
                left 0.32s cubic-bezier(0.2, 0, 0, 1);
    z-index: 80;
  }
  body.mob-drawer-open .mob-drawer-backdrop {
    opacity: 1;
    pointer-events: auto;
  }

  /* Close X inside the drawer (mobile only). */
  .mob-drawer-close {
    display: inline-flex;
    align-items: center; justify-content: center;
    position: absolute;
    top: 12px; right: 12px;
    width: 28px; height: 28px;
    background: transparent;
    border: 0;
    border-radius: 6px;
    color: var(--ink-mute);
    cursor: pointer;
    z-index: 1;
    -webkit-tap-highlight-color: rgba(0, 0, 0, 0.1);
    touch-action: manipulation;
    user-select: none;
    -webkit-user-select: none;
  }
  .mob-drawer-close:hover { background: var(--cream-3); color: var(--ink); }
  .mob-drawer-close:active { background: var(--cream-3); color: var(--ink); }
  .mob-drawer-backdrop { touch-action: manipulation; }

  /* Lock body scroll when drawer is open. */
  body.mob-drawer-open { overflow: hidden; }

  /* The desktop floating "open sidebar" button is irrelevant on mobile. */
  .side-opener { display: none !important; }

  /* Hide the existing bottom-tab nav at <720px — drawer replaces it. */
  .mobile-nav { display: none !important; }

  /* Mobile padding + spacing for the editorial column. */
  .dash, .pg, .rich-page { padding: 16px 16px 32px; gap: 16px; }
  .dash { gap: 16px; }
  .dash-greeting h1 { font-size: clamp(1.5rem, 6vw, 1.85rem); }

  /* Hide the per-plan footer (billing / support links) — same info available
     in the drawer. Decorative on mobile, eats vertical space. */
  .foot { display: none !important; }
}

/* ============================================================================
   Empty-state primitive — shared across My site, AI builder, Inbound,
   Job types, Lead capture (and Domain when it lands). Single centred panel
   with icon, headline, one-line description, single primary CTA. Match
   the .set-card chassis (border + radius). Warm-stone tokens only.
   ========================================================================== */
.empty-state {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
  padding: 48px 24px;
  text-align: center;
  background: var(--paper, #FFFFFF);
  border: 1px solid var(--hairline);
  border-radius: 12px;
  max-width: 560px;
  margin: 24px auto;
}
.empty-state__icon {
  width: 36px; height: 36px;
  color: var(--ink-mute);
  display: block;
}
.empty-state__title {
  font-family: 'Geist', 'Inter Tight', 'Inter', sans-serif;
  font-size: 1.2rem;
  font-weight: 500;
  color: var(--ink);
  margin: 0;
  max-width: 30ch;
  text-wrap: balance;
  letter-spacing: -0.005em;
}
.empty-state__desc {
  font-size: 0.92rem;
  color: var(--ink-mute);
  margin: 0;
  max-width: 50ch;
  line-height: 1.5;
}
.empty-state__cta {
  margin-top: 8px;
}
@media (max-width: 899.98px) {
  .empty-state { padding: 32px 20px; margin: 16px auto; }
}

/* =====================================================================
   Missed call recovery — v4 (founder reqs 2026-05-20)
   - Read-only SMS preview replaces editable textarea
   - 3 iPhone forwarding screenshots in Setup section
   - 3-way mode picker (Pro) + lock card (Starter)
   - "Both" link target removed (Booking OR Quote only)
   ===================================================================== */
.set-section-intro {
  font-size: 0.85rem;
  color: var(--ink-mute);
  line-height: 1.55;
  margin: 0 0 18px;
  max-width: 60ch;
}


/* ============================================================================
   2026-05-22 v5 — Mobile AI builder chat thread layout (canonical block)
   ============================================================================
   Final structure after several iterations. The whole page scrolls (window
   owns scroll, not chat-body). Topbar + composer are position:fixed at the
   viewport edges; everything in between flows naturally and scrolls past
   them. Chat content visibly passes behind the floating topbar buttons as
   the user scrolls.

   Why this block lives here (and not in dashboard-v2.css): cascade. The
   inline <style> at dashboard-v2-page.html:124+ was winning every fight
   we tried in dashboard-v2.css. The page-specific stylesheet (this file)
   is loaded BEFORE the inline <style> block in the document head — so by
   itself, the inline still wins. The rules below use !important on layout-
   critical properties AND a tight selector specificity (~0,4,1+) to beat
   both the inline rules and the long-standing flex defaults in dashboard-
   v2.css. The mobile media-query + body class + state-attribute scoping
   keeps it out of desktop / cards-view / ready-state layouts.

   Bottom-anchor (latest message just above the composer) is NOT done via
   CSS margin:auto tricks any more — that was fragile and depended on a
   chain of containers respecting child min-heights, which iOS Safari was
   collapsing. Instead, JS calculates the precise window.scrollTo target
   in _shellScrollToEnd (dashboard-v2-page-builder.js): "scroll the page
   so the last message's BOTTOM edge sits composer-height + 12px above
   the viewport bottom". Predictable, works on every browser, no flex
   math. */
@media (max-width: 720px) {

  /* ---- 1A. Containers must NOT clip or own scroll. The whole document
     scrolls (html/body). Every ancestor between body and chat-body gets
     overflow:visible + height:auto + display:block so a long thread
     grows the document naturally and a short thread doesn't trigger
     scroll. display:block kills the flex math that the bottom-anchor
     attempts kept losing to. */
  body.is-builder-chat:not(.is-builder-cards-view) .shell,
  body.is-builder-chat:not(.is-builder-cards-view) .shell > main.dash,
  body.is-builder-chat:not(.is-builder-cards-view) [data-rich-mount],
  body.is-builder-chat:not(.is-builder-cards-view) .builder-shell,
  body.is-builder-chat:not(.is-builder-cards-view) .builder-shell--centered:not([data-builder-state="ready"]),
  body.is-builder-chat:not(.is-builder-cards-view) .builder-card-wrap,
  body.is-builder-chat:not(.is-builder-cards-view) .builder-shell--centered:not([data-builder-state="ready"]) .builder-chat-pane,
  body.is-builder-chat:not(.is-builder-cards-view) .builder-shell--centered:not([data-builder-state="ready"]) .builder-chat-body {
    overflow: visible !important;
    height: auto !important;
    min-height: 0 !important;
    max-height: none !important;
  }

  /* ---- 1B. Body owns the scroll. Top padding clears the fixed topbar
     (so content doesn't start under it on cold start); bottom padding
     clears the fixed composer (so the last item can sit ABOVE the
     composer at end-of-thread). The composer-h CSS variable is set by
     the JS shellSyncChatPanePadBot helper after measuring the composer's
     actual rendered height. */
  body.is-builder-chat:not(.is-builder-cards-view) {
    min-height: 100dvh !important;
    padding-top: calc(52px + env(safe-area-inset-top, 0px)) !important;
    padding-bottom: calc(var(--bs-composer-h, 128px) + env(safe-area-inset-bottom, 0px) + 12px) !important;
    overflow-x: hidden !important;
    overscroll-behavior-y: contain !important;
  }

  /* ---- 1C. Topbar fixed at viewport top. Some computed-style runs
     reported position:sticky which TAKES FLOW SPACE — that pushed
     main.dash down by 52px (verified via Playwright: paneRectTop=104
     instead of 52). Forcing fixed here ensures topbar is out of flow
     and the body padding-top reserve is the ONLY top-clearance for
     content. */
  body.is-builder-chat:not(.is-builder-cards-view) .mob-topbar {
    position: fixed !important;
    top: 0 !important;
    left: 0 !important;
    right: 0 !important;
  }

  /* ---- 1C-bis. Frosted-glass blur band above the chat content. Sits
     BELOW the floating topbar buttons (which have z:71 + their own
     paper bg) but ABOVE chat content (default z:0). Backdrop-filter
     blurs whatever scrolls underneath; mask-image fades the blur
     intensity quadratically so the bottom of the band is invisible
     (content scrolls into a totally clear area) and the top is full
     frost (content disappears into the topbar). Gated on @supports
     so iOS Safari builds without backdrop-filter fall back to the
     existing transparent-topbar look (still works, just no blur).
     The band is on body::before because body::after may be used
     elsewhere — :before stays available for the builder page. */
  body.is-builder-chat:not(.is-builder-cards-view):not(.mob-drawer-open)::before {
    content: '';
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    /* Height = topbar visible height + ~64px ramp-out below it. */
    height: calc(52px + env(safe-area-inset-top, 0px) + 64px);
    z-index: 60;
    pointer-events: none;
    /* Tint = the topbar/chrome colour (--topband #FEFEFD) so the band fades
       INTO the chrome and is invisible over it. 2026-06-03: commit 0f212e2's
       de-cream pass changed this from warm cream rgba(253,251,246) to neutral
       rgba(253,253,253), which against the lightened #FEFEFD chrome read as a
       grey strip wherever the band leaked onto the sections view. Matching the
       chrome exactly makes the band invisible regardless of leak (belt-and-
       braces with the is-builder-sliding kill above). */
    background: linear-gradient(to bottom,
      rgba(254, 254, 253, 0.55) 0%,
      rgba(254, 254, 253, 0.28) 50%,
      rgba(254, 254, 253, 0) 100%);
  }
  /* The fade is meant for the chat pane (so chat messages scroll
     softly under the topbar). It bleeds into the preview + sections
     panes where the iframe / section-list start right at the top of
     the viewport — those don't want a fade. Founder feedback
     2026-05-24: "the page is fading at the top".
     2026-06-03 REGRESSION FIX: the kill only matched the EXACT attribute,
     but the sections pane is ALSO shown during is-builder-sliding (which
     forces all panes visible while active-pane already points at the slide
     TARGET — so sliding away from sections left this band painting over the
     still-visible sections pane). It was invisible until 0f212e2 retinted the
     band cream→neutral-grey; then it became the grey band the founder saw.
     The sections pane is visible ONLY when active-pane="sections" OR
     is-builder-sliding, so killing the band in both closes the leak while
     keeping the chat blur.
     2026-06-03 (founder): sections must match the PREVIEW pane — NO blur/fade.
     So the band is killed in sections AND preview (founder explicitly: "get rid
     of the blur on the sections page"). The grey that killing it exposed is now
     handled the preview way: the sections pane is position:fixed (like the
     preview pane), so as a positioned element it paints the iOS top safe-area
     strip cream — no blur, no separate cover layer. See the sections-pane
     fixed rule near the flatten block below. */
  body[data-builder-active-pane="preview"]::before,
  body[data-builder-active-pane="sections"]::before {
    display: none !important;
  }
  /* Kill the frosted top band entirely while the drawer is open. It's a
     position:fixed pseudo-element that does NOT slide with the card, so on
     iOS Safari it composites as a faint warmer/lighter band over the top of
     the sliding card + sidebar (a backdrop-filter/saturate effect Linux
     Chromium doesn't render, so it's invisible in our screenshots). With
     the drawer open there's no chat scrolling under the topbar, so the band
     serves no purpose here. (Founder 2026-06-06 — iOS-only seam.) */
  body.is-builder-chat.mob-drawer-open::before {
    display: none !important;
  }
  @supports ((-webkit-backdrop-filter: blur(0)) or (backdrop-filter: blur(0))) {
    body.is-builder-chat:not(.is-builder-cards-view):not(.mob-drawer-open)::before {
      /* pure blur, NO saturate — saturate() amplifies the cream's warm
         tone into a visible band on iOS (same lesson as the .mob-topbar-glass
         de-saturate in dashboard-v2.css). blur of a uniform colour returns
         that colour, so this stays invisible over flat chrome. */
      -webkit-backdrop-filter: blur(18px);
              backdrop-filter: blur(18px);
      -webkit-mask-image: linear-gradient(to top,
        rgba(0, 0, 0, 0) 0%,
        rgba(0, 0, 0, 0.05) 25%,
        rgba(0, 0, 0, 0.22) 50%,
        rgba(0, 0, 0, 0.58) 75%,
        rgba(0, 0, 0, 1) 100%);
              mask-image: linear-gradient(to top,
        rgba(0, 0, 0, 0) 0%,
        rgba(0, 0, 0, 0.05) 25%,
        rgba(0, 0, 0, 0.22) 50%,
        rgba(0, 0, 0, 0.58) 75%,
        rgba(0, 0, 0, 1) 100%);
    }
  }

  /* ---- 1D. Composer fixed at viewport bottom. position:fixed already
     applied by the existing inline page CSS (see dashboard-v2-page.html
     for the rule keyed on .builder-shell--centered:not([data-builder-
     state="ready"]) .builder-input-wrap). Don't redeclare here — but DO
     re-assert z-index so the composer always covers any chat content
     that the page-scroll briefly slides under it during rubber-band. */
  body.is-builder-chat:not(.is-builder-cards-view) .builder-shell--centered:not([data-builder-state="ready"]) .builder-input-wrap {
    z-index: 65 !important;
  }

  /* ---- 1D. Chat-body styling. No padding-top / bottom (the body's
     padding handles topbar / composer clearance). Drop the legacy
     auto-margin on first-child — page-scroll mode positions the latest
     message via JS, not via CSS bottom-anchor. */
  body.is-builder-chat:not(.is-builder-cards-view) .builder-shell--centered:not([data-builder-state="ready"]) .builder-chat-body {
    padding-top: 0 !important;
    padding-bottom: 0 !important;
    -webkit-mask-image: none !important;
            mask-image: none !important;
  }
  body.is-builder-chat:not(.is-builder-cards-view) .builder-shell--centered:not([data-builder-state="ready"]) .builder-chat-body > :first-child {
    margin-top: 0 !important;
  }

  /* ---- 1E. Cold-start (no messages yet, body lacks .has-chat-messages
     class — toggled by JS in _shellScrollToEnd). Keep the empty-hero
     centered between topbar and composer; no chat to bottom-anchor. */
  body.is-builder-chat:not(.is-builder-cards-view):not(.has-chat-messages) .builder-shell--centered:not([data-builder-state="ready"]) .builder-chat-pane {
    min-height: calc(100dvh - 52px - env(safe-area-inset-top, 0px) - var(--bs-composer-h, 128px) - env(safe-area-inset-bottom, 0px) - 12px) !important;
    display: flex !important;
    flex-direction: column !important;
    justify-content: center !important;
  }

  /* ============================================================
     2026-05-22 v9b — Card-slide drawer kept, containing-block bug fixed.
     ============================================================
     Founder: keep the card-slide animation (main.dash slides right
     revealing sidebar). The card-slide pattern was breaking the
     composer/cards-view because `transform: translateX(...)` on
     main.dash creates a containing block for position:fixed
     descendants — they re-anchored to main.dash instead of viewport.

     Fix: animate main.dash with `position: relative; left: var(
     --drawer-offset)` INSTEAD of transform. `left` doesn't create a
     containing block — fixed descendants stay anchored to viewport.
     Same visual (card slides right) without the containing-block
     side effect.

     Position:fixed elements that need to slide WITH the card
     (composer in chat mode, cards-view shell, frosted topbar overlay)
     get their own `transform: translateX(var(--drawer-offset))` rule
     gated on `.mob-drawer-open` so they animate in sync with main.dash.
     Each is GPU-smooth on its own; main.dash uses left which is a tad
     less smooth but acceptable.

     Verified via Playwright: chat mode composer stays at y=734
     (viewport bottom) whether drawer is open or closed — was y=612
     with the buggy transform approach. Cards-view pane stays at
     top=101 whether drawer is open or closed. */

  /* main.dash + sibling rich containers: use `left` instead of
     `transform` so they don't create a containing block for fixed
     descendants. The base rule's `transform: translateX(var(
     --drawer-offset))` is killed; left-animation produces the same
     visual slide. `will-change: left` + `backface-visibility: hidden`
     hint the browser to GPU-promote the layer so `left` is as smooth
     as `transform` (without creating a containing block — only
     `transform`/`filter`/`perspective` do that, will-change only
     opens an opportunity for the engine to optimise). */
  /* 2026-06-11 DOUBLE-SLIDE FIX: [data-rich-mount] REMOVED from this list
     (and from the transform-based list below). On the builder page the
     rich-mount is a CHILD of main.dash, so giving it its own
     --drawer-offset slide (left here, transform below) stacked on top of
     main.dash's slide — drawer-open pushed the chat pane to x≈655 on a
     390px viewport, i.e. the founder's "chat card goes blank when I open
     the sidebar". The mount inherits main.dash's slide; it must never
     carry its own. */
  body.is-builder-chat .shell > main.dash,
  body.is-builder-chat .shell > .pg,
  body.is-builder-chat .shell > .rich-page {
    transform: none !important;
    position: relative;
    left: var(--drawer-offset, 0px);
    transition: left 0.32s cubic-bezier(0.2, 0, 0, 1) !important;
    will-change: left;
    -webkit-backface-visibility: hidden;
            backface-visibility: hidden;
    animation: none !important;
    opacity: 1 !important;
  }
  /* The mount must stay completely INERT in builder mode: no slide of its
     own (the double-slide fix above) AND no entrance stagger. The mount
     carries [data-stagger], whose bs-fade-up animation fills FORWARDS
     ending on `transform: translateY(0)` — a filled IDENTITY transform
     that silently makes the mount a CONTAINING BLOCK for every fixed
     descendant (the cards-view shell, the preview/sections panes), which
     re-anchors and clips them (cards-view rendered blank). The old slide
     rules suppressed this as a side effect via animation:none — keep that
     suppression alive here, without re-adding any slide. */
  body.is-builder-chat [data-rich-mount] {
    transform: none !important;
    animation: none !important;
    opacity: 1 !important;
  }
  /* Also GPU-promote the elements that DO use transform so the engine
     doesn't have to recompose them every frame. */
  body.is-builder-chat .mob-topbar,
  body.is-builder-chat .builder-input-wrap,
  body.is-builder-cards-view .builder-shell {
    will-change: transform;
    -webkit-backface-visibility: hidden;
            backface-visibility: hidden;
  }
  /* Composer (chat mode): position:fixed at viewport bottom. With
     main.dash no-longer-transformed, the composer correctly anchors
     to the viewport regardless of drawer state. But VISUALLY we want
     the composer to slide RIGHT with the card-slide so it doesn't
     stay behind on the left side of the screen. Add its own
     transform that follows --drawer-offset. */
  body.is-builder-chat .builder-shell--centered:not([data-builder-state="ready"]) .builder-input-wrap {
    transition: transform 0.32s cubic-bezier(0.2, 0, 0, 1) !important;
  }
  /* 2026-06-11: scoped :not(.is-flex-flow-chat) — in flex-flow mode
     main.dash is TRANSFORMED (rule 1E'' below), which makes it the
     containing block for this fixed composer, so the composer already
     slides with the card. Adding its own translate on top double-shifted
     it off-screen. The self-translate is only needed on the legacy
     left-based path where no containing block exists. */
  body.is-builder-chat.mob-drawer-open:not(.is-flex-flow-chat) .builder-shell--centered:not([data-builder-state="ready"]) .builder-input-wrap {
    transform: translateX(var(--drawer-offset, 0px)) !important;
  }
  /* Cards-view shell (position:fixed inset:52,0,0,0): same pattern.
     Slide with the card so the sidebar reveals on the left. */
  body.is-builder-cards-view .builder-shell {
    transition: transform 0.32s cubic-bezier(0.2, 0, 0, 1) !important;
  }
  body.is-builder-cards-view.mob-drawer-open .builder-shell {
    transform: translateX(var(--drawer-offset, 0px)) !important;
  }
  /* Frosted-blur band (body::before, position:fixed at top): slides
     with the card too so the topbar's frosted region tracks the
     visible chat content. */
  body.is-builder-chat:not(.is-builder-cards-view):not(.mob-drawer-open)::before {
    transition: transform 0.32s cubic-bezier(0.2, 0, 0, 1);
  }
  body.is-builder-chat.mob-drawer-open::before {
    transform: translateX(var(--drawer-offset, 0px)) !important;
    transition: transform 0.32s cubic-bezier(0.2, 0, 0, 1);
  }

  /* ---- 1F. Has-chat-messages (set by JS once thread has any .builder-
     msg-row or form-card). Pane fills the visible chat area as a
     min-height and uses flex-end to BOTTOM-ANCHOR short threads (the
     chat-body, which is the only in-flow flex child here — empty-hero,
     instruction, suggestion-row, sections-body, publish-body are all
     display:none in this state, and input-wrap is position:fixed).
     - Short content (chat-body < min-height): chat-pane stays at
       min-height, slack is absorbed by justify-content:flex-end →
       chat-body anchored to bottom of chat-pane (just above composer).
     - Long content (chat-body > min-height): chat-pane.height = auto
       grows with chat-body; no slack to align; content fills naturally
       from top, document grows beyond viewport, page scrolls. JS
       _shellScrollToEnd auto-positions the last message above composer.
     Verified via Playwright on 390x844 viewport, post-commit 3b4e6b1
     pass — short thread message lands at y≈632-722 (12px above
     composer at y=734); long thread page-scrolls to last message
     bottom y=721.5 (12.5px above composer). */
  body.is-builder-chat.has-chat-messages:not(.is-builder-cards-view) .builder-shell--centered:not([data-builder-state="ready"]) .builder-chat-pane {
    min-height: calc(100dvh - 52px - env(safe-area-inset-top, 0px) - var(--bs-composer-h, 128px) - env(safe-area-inset-bottom, 0px) - 12px) !important;
    display: flex !important;
    flex-direction: column !important;
    justify-content: flex-end !important;
  }
  /* chat-body must NOT grow to fill chat-pane — the base rule has
     `flex: 1 1 auto` which made it size to chat-pane.height (670)
     instead of its content height, so justify-content:flex-end had
     nothing to push (chat-body already filled the pane). Setting
     flex:none sizes chat-body to its content; justify-content on the
     pane then bottom-anchors it. */
  body.is-builder-chat.has-chat-messages:not(.is-builder-cards-view) .builder-shell--centered:not([data-builder-state="ready"]) .builder-chat-body {
    flex: 0 0 auto !important;
  }

  /* ============================================================
     1G. Form-card redesign — bring back the card chrome on mobile.
     The Phase 4.3 (2026-05-17) rule at dashboard-v2.css:10368
     stripped the form's bg/border/shadow/radius/padding so it read
     as "Claude-style flowing content" — but the founder wants a
     compact card instead. Restore card chrome + tighten the spacing
     so the form feels like a small distinct surface, not a wall of
     fields.
     ============================================================ */
  body.is-builder-chat:not(.is-builder-cards-view) .builder-shell--centered:not([data-builder-state="ready"]) .builder-form-row,
  body.is-builder-chat:not(.is-builder-cards-view) .builder-shell--centered:not([data-builder-state="ready"]) .builder-msg-row {
    /* Side margin so the card doesn't go edge-to-edge — and so every
       message row (user bubble, thinking row, AI text reply, form-card)
       sits on the same x. Without this, the thinking row + user bubble
       sat at x=16 while the form-card sat at x=28, making the layout
       visibly shift when the AI's thinking finished and the form-card
       took over. Founder report 2026-05-28.
       Founder 2026-05-30: was 12px each side — combined with the
       chat-pane's own gutter that pushed bubbles ~28px in from each
       screen edge, which felt too inset for mobile. Drop to 0 so the
       only horizontal breathing room is the chat-pane gutter. */
    padding: 0 !important;
  }
  body.is-builder-chat .builder-shell--centered:not([data-builder-state="ready"]) .builder-form-card {
    background: var(--paper, #fff) !important;
    border: 1px solid var(--hairline) !important;
    border-radius: 16px !important;
    box-shadow:
      0 6px 22px -10px rgba(31, 22, 17, 0.10),
      0 1px 2px rgba(31, 22, 17, 0.04) !important;
    /* Compact: tighter padding + gap than the desktop card. */
    padding: 14px 14px 14px !important;
    gap: 9px !important;
    max-width: 100% !important;
  }
  /* Header: smaller + tighter than the desktop default. */
  body.is-builder-chat .builder-shell--centered:not([data-builder-state="ready"]) .builder-form-card .builder-form-header {
    font-size: 0.92rem !important;
    line-height: 1.35 !important;
    margin: 0 0 2px !important;
    font-weight: 600 !important;
  }
  /* Fields: tighten gap between fields + within field. */
  body.is-builder-chat .builder-shell--centered:not([data-builder-state="ready"]) .builder-form-card .builder-form-fields {
    gap: 10px !important;
  }
  body.is-builder-chat .builder-shell--centered:not([data-builder-state="ready"]) .builder-form-card .builder-form-field {
    gap: 3px !important;
  }
  /* Label: smaller + uppercased for a denser "spec sheet" feel. */
  body.is-builder-chat .builder-shell--centered:not([data-builder-state="ready"]) .builder-form-card .builder-form-label {
    font-size: 0.7rem !important;
    text-transform: uppercase !important;
    letter-spacing: 0.04em !important;
    color: var(--ink-mute) !important;
    font-weight: 600 !important;
  }
  /* Help text: kept (founder wants context) but smaller. */
  body.is-builder-chat .builder-shell--centered:not([data-builder-state="ready"]) .builder-form-card .builder-form-help {
    font-size: 0.72rem !important;
    margin-top: 1px !important;
    line-height: 1.35 !important;
  }
  /* Inputs: compact, 16px font kept (iOS-no-zoom requirement). */
  body.is-builder-chat .builder-shell--centered:not([data-builder-state="ready"]) .builder-form-card .builder-form-input,
  body.is-builder-chat .builder-shell--centered:not([data-builder-state="ready"]) .builder-form-card .builder-form-chip-input {
    font-size: 16px !important;
    padding: 6px 2px 7px !important;
  }
  /* Textarea: cap height tighter (was 80px on mobile, 60px reads
     leaner inside a smaller card). */
  body.is-builder-chat .builder-shell--centered:not([data-builder-state="ready"]) .builder-form-card .builder-form-textarea {
    height: 60px !important;
    min-height: 60px !important;
    max-height: 120px !important;
  }
  /* Segmented control: thinner buttons. */
  body.is-builder-chat .builder-shell--centered:not([data-builder-state="ready"]) .builder-form-card .builder-form-seg {
    padding: 8px 6px !important;
    font-size: 0.84rem !important;
  }
  /* Submit button: cleaner, slightly smaller. */
  body.is-builder-chat .builder-shell--centered:not([data-builder-state="ready"]) .builder-form-card .builder-form-submit {
    margin-top: 4px !important;
    padding: 12px 14px !important;
    font-size: 0.92rem !important;
    border-radius: 11px !important;
  }

  /* ============================================================
     2026-06-14 — sleek in-chat intake card (founder). Header bar +
     boxed inputs + trade dropdown + 2-col row + footer button.
     ============================================================ */
  body.is-builder-chat .builder-shell--centered:not([data-builder-state="ready"]) .builder-form-card {
    padding: 0 !important;
    gap: 0 !important;
    overflow: hidden !important;
    border-radius: 18px !important;
  }
  body.is-builder-chat .builder-shell--centered:not([data-builder-state="ready"]) .builder-form-card .builder-form-header {
    display: flex !important;
    align-items: center !important;
    justify-content: space-between !important;
    padding: 13px 16px !important;
    margin: 0 !important;
    border-bottom: 1px solid var(--hairline) !important;
    text-transform: none !important;
    letter-spacing: 0 !important;
  }
  .builder-form-htitle { font-size: 0.86rem; font-weight: 600; color: var(--ink); }
  .builder-form-hstep { font-size: 0.72rem; font-weight: 500; color: var(--ink-faint); }
  body.is-builder-chat .builder-shell--centered:not([data-builder-state="ready"]) .builder-form-card .builder-form-fields {
    padding: 16px 16px 6px !important;
    gap: 14px !important;
  }
  body.is-builder-chat .builder-shell--centered:not([data-builder-state="ready"]) .builder-form-card .builder-form-field {
    gap: 6px !important;
  }
  /* Boxed inputs (was underline) to match the approved mockup. */
  body.is-builder-chat .builder-shell--centered:not([data-builder-state="ready"]) .builder-form-card .builder-form-input,
  body.is-builder-chat .builder-shell--centered:not([data-builder-state="ready"]) .builder-form-card .builder-form-chip-input {
    height: 44px !important;
    border: 1.5px solid var(--hairline) !important;
    border-radius: 11px !important;
    padding: 0 12px !important;
    background: var(--paper, #fff) !important;
    font-size: 16px !important;
  }
  body.is-builder-chat .builder-shell--centered:not([data-builder-state="ready"]) .builder-form-card .builder-form-textarea {
    height: 64px !important;
    min-height: 64px !important;
    max-height: 140px !important;
    padding: 10px 12px !important;
  }
  body.is-builder-chat .builder-shell--centered:not([data-builder-state="ready"]) .builder-form-card .builder-form-input:focus,
  body.is-builder-chat .builder-shell--centered:not([data-builder-state="ready"]) .builder-form-card .builder-form-chip-input:focus {
    border-color: var(--orange, #D9601F) !important;
    box-shadow: 0 0 0 3px rgba(217, 96, 31, 0.13) !important;
    outline: none !important;
  }
  /* Trade + phone 2-col row. */
  .builder-form-row2 { display: grid !important; grid-template-columns: 1fr 1fr !important; gap: 11px !important; }
  .builder-form-col { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
  /* Trade dropdown chevron. */
  .builder-form-selwrap { position: relative; }
  .builder-form-selwrap::after {
    content: ""; position: absolute; right: 13px; top: 50%;
    width: 7px; height: 7px;
    border-right: 1.7px solid var(--ink-faint); border-bottom: 1.7px solid var(--ink-faint);
    transform: translateY(-65%) rotate(45deg); pointer-events: none;
  }
  body.is-builder-chat .builder-shell--centered:not([data-builder-state="ready"]) .builder-form-card .builder-form-select {
    -webkit-appearance: none !important; appearance: none !important;
    padding-right: 30px !important; cursor: pointer !important;
  }
  /* Footer button: inset from the card edges. The base rule sets
     width:100% + display:inline-flex; combined with these 16px side
     margins that overflowed the card by 32px (off the right edge). Use a
     block-level flex with width:auto so the margins constrain it to align
     with the input fields (founder 2026-06-15 crisp-spacing pass). */
  body.is-builder-chat .builder-shell--centered:not([data-builder-state="ready"]) .builder-form-card .builder-form-submit {
    display: flex !important;
    width: auto !important;
    margin: 8px 16px 16px !important;
    border-radius: 12px !important;
  }

  /* ============================================================
     2026-05-22 v12 — Flex-in-flow chat layout (Lovable-pattern).
     ============================================================
     Gated on body.is-flex-flow-chat. Replaces page-scroll + fixed
     composer with a viewport-tall flex column whose last child IS
     the composer (in flow, no position:fixed). Eliminates the
     transform-containing-block conflict — main.dash can now use
     `transform` for GPU-smooth drawer animation matching home page,
     without re-anchoring any descendant.

     Flip FLEX_FLOW = false in dashboard-v2-page-builder.js to revert
     to page-scroll behaviour instantly — the rules in this block
     simply don't fire when the body class isn't set.

     Specificity tie with the page-scroll rules above is broken by
     source order (this block is later in the file) so we win without
     needing crazy selector chains.
     ============================================================ */

  /* Body: viewport-fixed height, no scroll on body itself. */
  body.is-flex-flow-chat.is-builder-chat:not(.is-builder-cards-view) {
    height: 100dvh !important;
    min-height: 0 !important;
    overflow: hidden !important;
    padding-top: 0 !important;
    padding-bottom: 0 !important;
  }

  /* .shell, main.dash, rich-mount, builder-shell, card-wrap, chat-pane —
     all become flex columns that share viewport height. Chat-body is
     the only scroller. */
  body.is-flex-flow-chat.is-builder-chat:not(.is-builder-cards-view) .shell,
  body.is-flex-flow-chat.is-builder-chat:not(.is-builder-cards-view) .shell > main.dash,
  body.is-flex-flow-chat.is-builder-chat:not(.is-builder-cards-view) [data-rich-mount],
  body.is-flex-flow-chat.is-builder-chat:not(.is-builder-cards-view) .builder-shell,
  body.is-flex-flow-chat.is-builder-chat:not(.is-builder-cards-view) .builder-shell--centered:not([data-builder-state="ready"]),
  body.is-flex-flow-chat.is-builder-chat:not(.is-builder-cards-view) .builder-card-wrap[data-pane-key="chat"] {
    display: flex !important;
    flex-direction: column !important;
    height: 100dvh !important;
    min-height: 0 !important;
    max-height: 100dvh !important;
    overflow: hidden !important;
  }
  /* chat-pane fills its parent flex slot. 16px horizontal gutter
     lives INSIDE the chat wrap (not on main.dash) so the chat-wrap
     itself stays a constant 100vw across the pane slide — otherwise
     the gutter snaps in/out at slide-end when main.dash padding
     would change. Founder report 2026-05-24. */
  body.is-flex-flow-chat.is-builder-chat:not(.is-builder-cards-view) .builder-shell--centered .builder-chat-pane {
    /* 2026-05-24: dropped the :not([data-builder-state="ready"]) gate.
       Under the old sheet design the ready state turned the chat pane
       into a bottom sheet with bespoke sizing. Sheet is dead (see kill
       commit), so chat-pane should keep its gutter + flex layout
       in BOTH states. Was clobbering the handoff card's left/right
       breathing room and making the card look like floating text.
       Founder 2026-05-30: was 16px each side — combined with the
       msg-row + chat-body padding it pushed bubbles ~46px inset which
       felt too far from screen edges. Tightened to 12px (tried 8px
       and 10px first; 12px is the sweet spot the founder picked). */
    flex: 1 1 0 !important;
    min-height: 0 !important;
    max-height: none !important;
    display: flex !important;
    flex-direction: column !important;
    padding: 0 12px !important;
    overflow: hidden !important;
  }
  /* chat-body owns the scroll. Top padding clears the fixed topbar
     (52px) so content visually starts below it but scrolls under it.
     Bottom padding gives breathing room above the in-flow composer.
     Messages stack from the TOP (founder preference) — natural flow. */
  body.is-flex-flow-chat.is-builder-chat:not(.is-builder-cards-view) .builder-shell--centered:not([data-builder-state="ready"]) .builder-chat-body {
    flex: 1 1 0 !important;
    min-height: 0 !important;
    max-height: none !important;
    overflow-y: auto !important;
    overflow-x: hidden !important;
    overscroll-behavior: contain !important;
    -webkit-overflow-scrolling: touch !important;
    padding-top: calc(52px + env(safe-area-inset-top, 0px)) !important;
    padding-bottom: 12px !important;
    -webkit-mask-image: none !important;
            mask-image: none !important;
  }
  /* Composer becomes a flex child in normal flow. Kills position:fixed
     and the bottom/left/right anchors that the L10162 rule in
     dashboard-v2.css sets. */
  body.is-flex-flow-chat.is-builder-chat:not(.is-builder-cards-view) .builder-shell--centered:not([data-builder-state="ready"]) .builder-input-wrap {
    position: static !important;
    left: auto !important;
    right: auto !important;
    bottom: auto !important;
    z-index: auto !important;
    flex: 0 0 auto !important;
    margin-top: 0 !important;
    /* Safe-area on the composer itself (was on body padding before). */
    padding-bottom: max(12px, env(safe-area-inset-bottom, 0px)) !important;
    /* No fade gradient needed — composer no longer floats over content. */
    background: var(--topband, #FEFEFD) !important;
  }
  /* Suggestion row sits ABOVE the composer (DOM order: composer THEN
     suggestion-row; flex order flips visually). */
  body.is-flex-flow-chat.is-builder-chat:not(.is-builder-cards-view) .builder-shell--centered:not([data-builder-state="ready"]) .builder-input-wrap {
    order: 2;
  }
  body.is-flex-flow-chat.is-builder-chat:not(.is-builder-cards-view) .builder-shell--centered:not([data-builder-state="ready"]) .builder-suggestion-row {
    order: 1;
    flex: 0 0 auto !important;
  }
  body.is-flex-flow-chat.is-builder-chat:not(.is-builder-cards-view) .builder-shell--centered:not([data-builder-state="ready"]) .builder-chat-body {
    order: 0;
  }

  /* Drawer slide via GPU `transform` on main.dash (and rich containers).
     Beats the L6491 v9b override that uses `left:`. With composer no
     longer position:fixed in chat mode, transform creates no problem.
     EXCLUDED from cards-view (the cards shell is position:fixed and
     would re-anchor to main.dash if main.dash had transform). */
  /* 2026-06-11: [data-rich-mount] removed — it's a descendant of main.dash
     on this page, so its own translate DOUBLED the drawer slide (chat pane
     off-screen at x≈655; fixed preview/sections panes re-anchored to the
     transformed mount and went blank too). main.dash's transform is the
     single slide; everything inside (and every fixed pane whose containing
     block becomes main.dash) rides along. */
  body.is-flex-flow-chat.is-builder-chat:not(.is-builder-cards-view) .shell > main.dash,
  body.is-flex-flow-chat.is-builder-chat:not(.is-builder-cards-view) .shell > .pg,
  body.is-flex-flow-chat.is-builder-chat:not(.is-builder-cards-view) .shell > .rich-page {
    transform: translateX(var(--drawer-offset, 0px)) !important;
    /* Match home-page transition exactly: transform + border-radius +
       box-shadow all animate together with the same 0.32s curve so the
       card-edge appears smoothly as the slide progresses. */
    transition:
      transform 0.32s cubic-bezier(0.2, 0, 0, 1),
      border-radius 0.32s cubic-bezier(0.2, 0, 0, 1),
      box-shadow 0.32s cubic-bezier(0.2, 0, 0, 1) !important;
    will-change: transform;
    -webkit-backface-visibility: hidden;
            backface-visibility: hidden;
    position: relative;
    left: auto !important;
    animation: none !important;
    opacity: 1 !important;
  }
  /* Cards-view: shell is position:fixed inset:52,0,0,0 of viewport. It
     needs its own transform to slide with the drawer. main.dash stays
     untransformed in this mode so it doesn't break the shell's CB. */
  body.is-flex-flow-chat.is-builder-cards-view .builder-shell {
    transform: translateX(var(--drawer-offset, 0px)) !important;
    transition:
      transform 0.32s cubic-bezier(0.2, 0, 0, 1),
      border-radius 0.32s cubic-bezier(0.2, 0, 0, 1),
      box-shadow 0.32s cubic-bezier(0.2, 0, 0, 1) !important;
    will-change: transform;
    -webkit-backface-visibility: hidden;
            backface-visibility: hidden;
  }
  /* Cards-shell gets the same card-edge treatment that main.dash gets
     in chat mode (dashboard-v2.css L1750): rounded bottom-left corner
     + left-edge shadow so the shell visibly stacks over the sidebar
     when drawer is open. */
  body.is-flex-flow-chat.is-builder-cards-view.mob-drawer-open .builder-shell {
    border-bottom-left-radius: 22px;
    box-shadow:
      -1px 0 0 0 rgba(31, 22, 17, 0.08),
      -6px 0 22px -8px rgba(31, 22, 17, 0.18) !important;
  }
  /* Cards-view: kill main.dash animation entirely. The v9b `left:` rule
     at L6491 fires here too (it's gated on body.is-builder-chat without
     :not(.is-builder-cards-view)), causing main.dash to animate via slow
     `left` while the cards-shell animates via GPU transform — desync =
     glitchy. main.dash has no visible content in cards-view (shell is
     position:fixed and floats above), so killing its animation is safe
     and removes the desync source. */
  body.is-flex-flow-chat.is-builder-cards-view .shell > main.dash,
  body.is-flex-flow-chat.is-builder-cards-view .shell > .pg,
  body.is-flex-flow-chat.is-builder-cards-view .shell > .rich-page,
  body.is-flex-flow-chat.is-builder-cards-view [data-rich-mount] {
    transform: none !important;
    left: auto !important;
    transition: none !important;
    will-change: auto !important;
    /* main.dash keeps its base z-index:10 (above sidebar's z-index:1)
       and is NOT static — but we make it visually transparent so the
       sidebar's content (BookingSprint logo, nav links) shows through
       when drawer is open. The cards-shell at z-index:60 is still above
       main.dash; the sidebar at z-index:1 shows through the transparent
       main.dash because main.dash has no opaque background. */
    background-color: transparent !important;
  }
  /* Cards-dock (Publish/Share): hide while drawer is open. The buttons
     are centered with full-width container; sliding the container by
     --drawer-offset puts the centered buttons off-screen entirely.
     Keeping it visible without sliding overlaps the sidebar footer
     awkwardly. Hiding while drawer is open keeps the UI clean — the
     user can't usefully tap dock buttons through the drawer anyway. */
  body.is-flex-flow-chat.is-builder-cards-view .builder-cards-dock {
    transition: opacity 0.2s ease;
  }
  body.is-flex-flow-chat.is-builder-cards-view.mob-drawer-open .builder-cards-dock {
    opacity: 0;
    pointer-events: none;
  }
  /* Topbar slides via its base rule transform — already GPU. */
  /* Composer is in flow inside main.dash now — it slides automatically
     with main.dash's transform. Kill the redundant composer-transform
     rule from v9b L6520+. */
  body.is-flex-flow-chat.is-builder-chat.mob-drawer-open .builder-shell--centered:not([data-builder-state="ready"]) .builder-input-wrap {
    transform: none !important;
  }

  /* Empty-state centering: chat-pane centers hero+chips when no chat
     content. The empty-hero remains an inline element of chat-pane. */
  body.is-flex-flow-chat.is-builder-chat:not(.is-builder-cards-view):not(.has-chat-messages) .builder-shell--centered:not([data-builder-state="ready"]) .builder-chat-body {
    flex: 1 1 0 !important;
    display: flex;
    flex-direction: column;
    justify-content: center;
  }

  /* ── BEHIND-SCROLL GLASS, refine state (founder 2026-06-16) ───────────────
     The refine view of a built site is data-builder-state="ready" (+ the body
     is is-flex-flow-chat). Get rid of the white card behind the composer +
     chips so the chat thread scrolls cleanly BEHIND the frosted bar: make the
     chat-pane a positioning context, turn the composer (.builder-input-wrap,
     which contains the chips) into a TRANSPARENT absolute overlay pinned to
     the bottom, and reserve chat-body space = composer height so the last
     message rests above it while older ones frost behind. Loaded last, so it
     beats the other ready/flex-flow rules. Not in cards-view. */
  body.is-builder-chat:not(.is-builder-cards-view) .builder-shell--centered[data-builder-state="ready"] .builder-chat-pane {
    position: relative !important;
  }
  body.is-builder-chat:not(.is-builder-cards-view) .builder-shell--centered[data-builder-state="ready"] .builder-input-wrap {
    position: absolute !important;
    left: 16px !important;
    right: 16px !important;
    bottom: 0 !important;
    width: auto !important;
    max-width: none !important;
    z-index: 6 !important;
    margin: 0 !important;
    background: transparent !important;
    padding: 0 0 max(12px, env(safe-area-inset-bottom, 0px)) !important;
  }
  /* Chips (suggestion/refine) get the SAME 16px frosted glass as the composer
     (founder 2026-06-16) so text frosts behind them too — no opaque white pill,
     no feather fade above them. */
  body.is-builder-chat:not(.is-builder-cards-view) .builder-shell--centered[data-builder-state="ready"] .builder-refine-chip,
  body.is-builder-chat:not(.is-builder-cards-view) .builder-shell--centered[data-builder-state="ready"] .builder-suggestion-row .builder-suggestion-chip {
    background: rgba(248, 248, 247, 0.66) !important;
    -webkit-backdrop-filter: blur(16px) saturate(135%) !important;
    backdrop-filter: blur(16px) saturate(135%) !important;
    border: 1px solid rgba(255, 255, 255, 0.5) !important;
    /* Same even ambient halo as the composer (founder 2026-06-16) so the pills
       carry the same slight shading around their edges and read equally glassy. */
    box-shadow:
      0 0 0 1px rgba(20, 16, 12, 0.025),
      0 0 12px rgba(20, 16, 12, 0.06),
      0 -1px 6px rgba(20, 16, 12, 0.03),
      0 2px 8px rgba(20, 16, 12, 0.05) !important;
  }
  /* The chip ROW's right-edge scroll-fade mask was the bug: a mask on the
     parent re-roots backdrop-filter, so the chips' blur sampled nothing and
     they read as plain 66% translucent (way more see-through than the bar).
     Drop the mask here so the chips actually frost like the composer. */
  body.is-builder-chat:not(.is-builder-cards-view) .builder-shell--centered[data-builder-state="ready"] .builder-refine-row,
  body.is-builder-chat:not(.is-builder-cards-view) .builder-shell--centered[data-builder-state="ready"] .builder-suggestion-row {
    -webkit-mask-image: none !important;
    mask-image: none !important;
  }
  /* thread fills behind the overlay + a fallback reserve before JS measures */
  body.is-builder-chat:not(.is-builder-cards-view) .builder-shell--centered[data-builder-state="ready"] .builder-chat-body {
    padding-bottom: 168px !important;
  }
}

/* ============================================================================
   2026-05-22 v6 — Cards-view redesign (tap-the-play-button view)
   ============================================================================
   Founder feedback: the cards-view "looks cheesy" — specifically the
   centered "Chat" label above the card reads as an afterthought, and the
   card chrome is plain. Replit reference uses a TAG PILL inside the card
   header (not floating above), softer card chrome, and a denser bottom
   action dock. Match that pattern.

   Scope: mobile + body.is-builder-cards-view only. */
@media (max-width: 720px) {

  /* Cards-view backdrop: --topband (#FEFEFD) to match the sidebar.
     Founder rule (CLAUDE.md): topbar + sidebar + chrome all read as
     one continuous warm panel. Cards-view backdrop joins the same
     surface — when the user opens the drawer over the cards, the
     two surfaces should be the same colour. Previous v6/v7/v8 used
     --cream which is slightly lighter / different tint and produced
     a visible seam against the sidebar. */
  body.is-builder-cards-view {
    background-color: var(--topband, #FEFEFD) !important;
  }
  body.is-builder-cards-view .builder-shell,
  body.is-builder-cards-view .mob-topbar {
    background-color: var(--topband, #FEFEFD) !important;
  }

  /* Card wrap: keep horizontal-snap layout but reset gap between label
     and card to 0 (label is going INSIDE the card now). */
  body.is-builder-cards-view .builder-shell--centered .builder-card-wrap {
    gap: 0 !important;
    position: relative !important;
  }
  /* Card label: from "floating centered small text above the card" to
     "pill tag absolutely positioned in the top-left of the card". Like
     the Replit "Agent" tag. Higher z-index so it sits above the pane's
     content + overflow:hidden. */
  body.is-builder-cards-view .builder-shell--centered .builder-card-label {
    position: absolute !important;
    top: 12px !important;
    left: 12px !important;
    z-index: 5 !important;
    display: inline-flex !important;
    align-items: center !important;
    gap: 5px !important;
    padding: 4px 10px 4px 8px !important;
    background: rgba(255, 255, 255, 0.78) !important;
    -webkit-backdrop-filter: blur(8px) saturate(160%);
            backdrop-filter: blur(8px) saturate(160%);
    border: 1px solid rgba(31, 22, 17, 0.06) !important;
    border-radius: 999px !important;
    color: var(--ink) !important;
    font-size: 0.72rem !important;
    font-weight: 600 !important;
    letter-spacing: 0.005em !important;
    box-shadow: 0 1px 2px rgba(31, 22, 17, 0.04) !important;
    text-transform: capitalize;
  }
  body.is-builder-cards-view .builder-shell--centered .builder-card-label svg {
    width: 12px !important;
    height: 12px !important;
    opacity: 0.7;
  }

  /* Pane (the card itself): bigger radius, much softer shadow, top
     padding-top to clear the absolute label pill. The Replit cards
     use a 16-20px radius + a very soft 1px hairline + a quiet shadow,
     not the aggressive 50% opacity drop-shadow we had. */
  body.is-builder-cards-view .builder-shell--centered .builder-pane {
    border-radius: 22px !important;
    /* 2026-05-22 V6 treatment — gradient surface + defined border +
       even edge shadows so the card reads as a floating element with
       depth, matching the topbar buttons / chat bar.
       2026-05-23 founder iteration: border + shadow bumped so cards
       lift more clearly off the cream-3 backdrop and read as
       distinct elevated panels (not flat panes blending into the
       page). Border opacity 0.12 → 0.18, shadow stack deepened. */
    background: linear-gradient(180deg, #FFFFFF 0%, #F6F6F6 100%) !important;
    border: 1px solid rgba(31, 22, 17, 0.18) !important;
    box-shadow:
      0 0 0 1px rgba(20, 14, 8, 0.05),
      0 0 24px rgba(20, 14, 8, 0.08),
      0 2px 4px rgba(20, 14, 8, 0.06),
      0 12px 32px -8px rgba(20, 14, 8, 0.18),
      0 32px 64px -16px rgba(20, 14, 8, 0.20),
      inset 0 1.5px 0 rgba(255, 255, 255, 0.9),
      inset 0 -1px 1px rgba(0, 0, 0, 0.04) !important;
    /* Slightly taller card so it has presence — was 42vh / 380px cap. */
    height: 52vh !important;
    max-height: 480px !important;
    padding-top: 0 !important;
  }

  /* Card head (for non-chat panes that have an internal head — Sections,
     Preview): left-pad to clear the absolute label pill at top:12/left:12
     (the pill is ~70px wide; add 78px left padding so the head's title
     and inner controls start to the RIGHT of the pill instead of
     overlapping it). */
  body.is-builder-cards-view .builder-pane__card-head {
    padding: 14px 14px 12px 78px !important;
    border-bottom: 1px solid rgba(31, 22, 17, 0.06) !important;
    font-size: 0.85rem !important;
    min-height: 46px !important;
  }
  /* Preview-pane head specifically — overflow:hidden any tab strip
     content that would otherwise clip the label region awkwardly. */
  body.is-builder-cards-view .builder-preview-pane > * {
    overflow: hidden !important;
  }

  /* Cards-view backdrop topbar: Back pill gets simple 3D style
     matching the project pill / preview pill so all topbar elements
     read as one matching set. */
  body.is-builder-cards-view .builder-cards-back {
    height: 44px !important;
    padding: 0 18px 0 14px !important;
    font-size: 14px !important;
    font-weight: 500 !important;
    background: linear-gradient(180deg, #FFFFFF 0%, #F8F8F8 100%) !important;
    border: 1px solid rgba(31, 22, 17, 0.13) !important;
    border-bottom-color: rgba(31, 22, 17, 0.19) !important;
    box-shadow:
      0 1px 3px rgba(31, 22, 17, 0.07),
      0 2px 1px -1px rgba(31, 22, 17, 0.04),
      inset 0 1px 0 rgba(255, 255, 255, 0.9) !important;
  }

  /* Bottom dock buttons: tighter, more elegant. The previous look had
     two big chunky pills; reduce padding and refine the shadow. */
  body.is-builder-cards-view .builder-cards-dock {
    background: linear-gradient(to bottom,
      rgba(248, 248, 248, 0) 0%,
      var(--cream) 32%) !important;
    padding: 28px 16px max(20px, env(safe-area-inset-bottom)) !important;
  }
  /* P4 2026-06-10: 4-tile dock — compact icon-over-label tiles so
     Preview / Sections / Share / Publish all fit a 390px viewport.
     KEEP IN SYNC with the inline backup in dashboard-v2-page.html. */
  body.is-builder-cards-view .builder-cards-dock { gap: 8px !important; }
  body.is-builder-cards-view .builder-cards-dock__btn {
    flex: 1 1 0 !important;
    min-width: 0 !important;
    max-width: 96px;
    flex-direction: column !important;
    align-items: center;
    justify-content: center;
    gap: 3px !important;
    height: 52px !important;
    padding: 0 6px !important;
    border-radius: 14px !important;
    font-size: 11.5px !important;
    font-weight: 600 !important;
    white-space: nowrap;
    /* Simple 3D treatment for the light tiles — matches burger,
       project pill, preview pill, and back button. */
    background: linear-gradient(180deg, #FFFFFF 0%, #F8F8F8 100%) !important;
    border: 1px solid rgba(31, 22, 17, 0.13) !important;
    border-bottom-color: rgba(31, 22, 17, 0.19) !important;
    box-shadow:
      0 1px 3px rgba(31, 22, 17, 0.07),
      0 2px 1px -1px rgba(31, 22, 17, 0.04),
      inset 0 1px 0 rgba(255, 255, 255, 0.9) !important;
  }
  body.is-builder-cards-view .builder-cards-dock__btn svg {
    width: 17px !important;
    height: 17px !important;
    flex-shrink: 0;
  }
  /* Publish (primary CTA): dark surface with simple 3D shadow. */
  body.is-builder-cards-view .builder-cards-dock__btn[data-cards-dock="publish"] {
    background: linear-gradient(180deg, #2A2520 0%, #1F1611 100%) !important;
    color: #FAFAFA !important;
    border-color: #1F1611 !important;
    border-bottom-color: #0F0B08 !important;
    box-shadow:
      0 1px 3px rgba(31, 22, 17, 0.2),
      inset 0 1px 0 rgba(255, 255, 255, 0.08) !important;
  }
}

/* ============================================================================
   2026-05-22 v7 — Cards-view refinement v2 (founder iteration on v6)
   ============================================================================
   - Cards too stubby → taller (70vh, max 620px)
   - Cards too narrow → wider (94vw, shell side padding 6vw → 3vw)
   - Heading should be OUTSIDE the card (not inside) but more premium →
     serif italic above the card, no pill bg, no generic icon
   - Open/close animations should be clean + consistent → mirror enter /
     exit with one shared easing + duration, no stagger
   ============================================================================ */
@media (max-width: 720px) {

  /* Shell: tighter side padding, bottom padding sized to clear the
     fixed dock entirely. Card should NOT extend under the Publish/
     Share buttons (founder feedback 2026-05-22 v8b: 'I need them not
     to go past the publish and share button'). Dock height ≈ 14 (top
     pad) + 42 (button) + max(16, safe-area-bot) ≈ 92px, so 100px +
     safe-area-bot bottom padding gives the dock breathing room. */
  body.is-builder-cards-view .builder-shell {
    padding: 16px 6vw calc(100px + env(safe-area-inset-bottom, 0px)) !important;
    gap: 12px !important;
  }

  /* Card wrap: thinner per founder ref (Replit screenshot) so the
     card reads as a distinct object with breathing room either side
     and a clearer peek of the next card. 94vw -> 82vw -> 80vw (P4
     2026-06-10: with FOUR cards, neighbours must visibly peek); shell
     side padding stays 6vw to centre the row. KEEP IN SYNC with the
     inline backup in dashboard-v2-page.html (~L612) — it loads after
     this file and wins ties. */
  body.is-builder-cards-view .builder-shell--centered .builder-card-wrap {
    width: 80vw !important;
    max-width: 80vw !important;
    flex: 0 0 80vw !important;
    gap: 12px !important;
    position: static !important;
  }

  /* Label: from "absolute pill inside the card" back to "elegant serif
     italic above the card" — no pill, no backdrop blur, no generic icon.
     Reads as a premium chapter title rather than a UI tag. */
  body.is-builder-cards-view .builder-shell--centered .builder-card-label {
    position: static !important;
    display: flex !important;
    align-items: baseline !important;
    justify-content: flex-start !important;
    gap: 0 !important;
    padding: 0 4px !important;
    margin: 0 !important;
    background: transparent !important;
    -webkit-backdrop-filter: none !important;
            backdrop-filter: none !important;
    border: 0 !important;
    border-radius: 0 !important;
    box-shadow: none !important;
    /* Founder 2026-06-10: no italics in cards-view — clean sans labels
       (was Newsreader italic; read as decorative against the new panes). */
    font-family: inherit !important;
    font-style: normal !important;
    font-weight: 700 !important;
    font-size: 0.98rem !important;
    letter-spacing: -0.01em !important;
    line-height: 1.1 !important;
    color: var(--ink) !important;
    opacity: 0.88 !important;
    text-transform: none !important;
    user-select: none;
    -webkit-user-select: none;
  }
  /* Drop the generic chat/grid/screen icon next to the label — the
     serif italic word stands on its own. */
  body.is-builder-cards-view .builder-shell--centered .builder-card-label svg {
    display: none !important;
  }

  /* Pane (card body): much taller — fills almost all the vertical
     space between the topbar bottom and viewport bottom. The card
     extends UNDER the dock area; the dock's own gradient mask + the
     pane's overflow:hidden + the scaled-content padding produce a
     soft fade-out at the bottom of the card, so the dock buttons
     read as floating over the card edge rather than cutting it off.
     calc breakdown: 100dvh - 52 (topbar) - safe-area-top - 32 (label
     + gap above card). No dock subtraction — that's the intentional
     'card goes behind dock' trick to maximize visible card area. */
  body.is-builder-cards-view .builder-shell--centered .builder-pane {
    /* calc breakdown (matches shell padding 16 top + 100+safe-bot
       bottom — the bottom reserve clears the fixed dock so the card
       does NOT extend under the Publish/Share buttons):
         100dvh             viewport
         - 52               fixed topbar above shell
         - safe-area-top    iPhone notch
         - 16               shell padding-top
         - 100              shell padding-bottom (clears dock)
         - safe-area-bot    home-indicator inset
         - 24               label height above the card
         - 12               gap between label and card
       On 844-tall iPhone with no notch:  640px card
       On 844-tall iPhone with notch (47/34): 559px card
       Still significantly taller than v7's 581px; now bounded above
       the dock instead of overlapping it. */
    height: calc(100dvh - 52px - env(safe-area-inset-top, 0px) - 16px - 100px - env(safe-area-inset-bottom, 0px) - 24px - 12px) !important;
    max-height: 720px !important;
    border-radius: 24px !important;
    overflow: hidden !important;
  }
  body.is-builder-cards-view .builder-pane__card-head {
    padding-left: 16px !important;
  }
  /* Tighter dock — was 28+20 padding; trim to 14+max(16,safe-bot) so the
     dock takes less vertical space and the card extension under it is
     a clean fade rather than a chunky bar over the card. */
  body.is-builder-cards-view .builder-cards-dock {
    padding: 14px 16px max(16px, env(safe-area-inset-bottom)) !important;
    /* Dock gradient ends in --topband (#FEFEFD) to match the cards-view
       backdrop — single continuous surface from cards down through the
       dock and out to the safe-area inset. */
    background: linear-gradient(to bottom,
      rgba(253, 253, 253, 0) 0%,
      var(--topband, #FEFEFD) 60%) !important;
  }

  /* "Zoomed-out app preview" — scale the pane's INNER content to ~0.7
     so the full chat thread / preview iframe / sections list reads as
     a shrunken thumbnail of the live pane.
     Use `zoom` (vs transform:scale) because zoom actually changes the
     LAYOUT — the content's children re-flow at the smaller size, so
     right-aligned message bubbles land correctly inside the card and
     the width-compensation math (153.85% + margin-left tricks) isn't
     needed. zoom is non-standard but supported in every WebKit /
     Blink browser; Firefox does not, but mobile Firefox is <1% share.
     IMPORTANT: target only the INNER content elements (chat-body /
     preview-body / sections-list), NOT the .builder-preview-pane
     itself — scaling the pane would also scale its bg/border/radius
     and break the card chrome. Founder report 2026-05-22: the v7
     attempt scaled `.builder-preview-pane` and the card rendered as
     a tiny dark rectangle with the label "Preview" stacked vertically. */
  /* Zoom EVERY direct child of each pane so the head (tab strip, URL
     bar, publish button — for preview pane) AND the body content
     (iframe, chat thread, sections list) ALL render as a uniform
     thumbnail. Without this, the head stays full-width and its
     contents get squashed (Pr/ev/iew tabs stacked vertically because
     the tab buttons are narrower than their text — the founder
     screenshot showed exactly this). */
  body.is-builder-cards-view .builder-shell--centered .builder-pane > *,
  body.is-builder-cards-view .builder-shell--centered .builder-chat-pane .builder-chat-body {
    zoom: 0.7 !important;
    pointer-events: none !important;
    transform: none !important;
    width: auto !important;
    margin-left: 0 !important;
  }
  /* Strip chat-body's page-scroll min-height so the zoomed view doesn't
     carry a viewport-sized empty area under the messages. */
  /* Founder feedback 2026-05-23: at 16px CSS × zoom 0.7 (~11px visual)
     the content text sat too close to the card edges and read as flush.
     Bumped to 28px horizontal (~20px visual at zoom 0.7) to match the
     visible inset of the input-wrap below (which has margin: 0 14px,
     un-zoomed = 14px visual). Same "slight inset from card edge"
     treatment for both rows. */
  body.is-builder-cards-view .builder-shell--centered .builder-chat-body {
    min-height: 0 !important;
    height: auto !important;
    max-height: none !important;
    padding: 12px 28px !important;
  }
  /* dashboard-v2.css:10420 strips chat-body left/right padding when the
     business-info form-card is mounted (so the edge-to-edge form fills
     the chat-pane in single-mode). In cards-view we WANT the inset back
     so the form-card sits off the card edges with breathing room.
     Match its :has() selector + add body.is-builder-cards-view scope. */
  body.is-builder-cards-view .builder-shell--centered .builder-chat-body:has(.builder-form-card:not(.builder-choice-card)) {
    padding-left: 28px !important;
    padding-right: 28px !important;
  }

  /* ────────────────────────────────────────────────────────────
     Chat card layout: chat-body fills, input-wrap pins to bottom
     ────────────────────────────────────────────────────────────
     Without this, the chat-body takes its natural (tall) height
     and pushes the input-wrap + suggestion-row OUT of the bottom
     of the chat-pane (overflow:hidden then clips them). The
     founder asked for the input bar + chips to be visible inside
     the chat card as part of the 1:1 preview, so we make the
     chat-pane a flex column with the chat-body flex:1 (clipped
     by overflow) and the bottom rows flex:0 (always visible).
     ──────────────────────────────────────────────────────────── */
  body.is-builder-cards-view .builder-shell--centered .builder-chat-pane {
    display: flex !important;
    flex-direction: column !important;
    overflow: hidden !important;
  }
  body.is-builder-cards-view .builder-shell--centered .builder-chat-pane > .builder-chat-body {
    /* flex-basis: 0 (not auto) so chat-body ignores its intrinsic
       (empty) size and aggressively grows to fill available space —
       otherwise an empty chat would collapse to 0 and the input-wrap
       would float right under the hero instead of pinning to the
       card bottom. */
    flex: 1 1 0 !important;
    min-height: 0 !important;
    overflow: hidden !important;
    /* Override the global ".builder-chat-body:empty { display: none }"
       rule — in cards-view we need chat-body to occupy its flex slot
       even when empty so the input-wrap below it pins to the card
       bottom (otherwise empty chats collapse and the composer floats
       to the middle of the card). */
    display: block !important;
  }
  body.is-builder-cards-view .builder-shell--centered .builder-chat-pane > .builder-input-wrap,
  body.is-builder-cards-view .builder-shell--centered .builder-chat-pane > .builder-suggestion-row {
    flex: 0 0 auto !important;
    /* Inset from the card edges so the input-wrap's own rounded
       background doesn't merge into the card's rounded edge and read
       as the card border. Founder feedback 2026-05-23: at 100% width
       the input bar's bottom-corners hit the card's bottom-corners
       and the two boundaries blur together. 14px inset gives a clean
       gap on both sides + bottom. */
    margin: 0 14px 14px !important;
    max-width: calc(100% - 28px) !important;
    width: calc(100% - 28px) !important;
    /* CRITICAL OVERRIDE: dashboard-v2.css:10192 sets
       `.builder-shell--centered:not([data-builder-state="ready"]) .builder-input-wrap
       { position: fixed; bottom: 0; }` — that makes the composer pin
       to the viewport bottom in single mode (correct) and ALSO in
       cards-view (wrong — it escapes the chat-pane and floats below
       the card). Force back to normal flow inside the chat-pane so
       flex-column places it at the bottom of the card. */
    position: relative !important;
    left: auto !important;
    right: auto !important;
    bottom: auto !important;
    z-index: auto !important;
    /* Composer in single-mode has paper bg + warm gradient + heavy
       safe-area padding (matches viewport-bottom chrome). Inside the
       card those styles look like a second "viewport composer"
       glued to the card bottom — kill them so the composer just
       looks like part of the card. */
    background: transparent !important;
    padding: 8px 0 0 !important;
  }
  /* Same override for the position:fixed rule — silence its margin-top:auto
     so the input doesn't try to push itself further than its flex slot. */
  body.is-builder-cards-view .builder-shell--centered .builder-input-wrap {
    margin-top: 0 !important;
  }

  /* ────────────────────────────────────────────────────────────
     Open / close animation — JS-driven FLIP morph
     ────────────────────────────────────────────────────────────
     The actual morph is driven by JS in dashboard-v2-page.html
     (wireCardsView → flipMorph). It captures the chat card-wrap's
     position before + after the body-class change and animates a
     CSS transform between the two rects. Chat content stays 100%
     solid the entire morph — no crossfade, no fade overlap.

     This block silences every CSS keyframe animation that used to
     run on .builder-shell or .builder-card-wrap when the cards-view
     class lands. The previous iterations (v6/v7 staggered scale in
     dashboard-v2.css, v8 symmetric scale here, view-transition
     crossfade) would all double-animate over the top of the JS
     transform — they're all neutralised below.

     Sibling cards (Sections / Preview) + dock fade in/out via the
     separate keyframes further down so they don't snap.
     ──────────────────────────────────────────────────────────── */
  body.is-builder-cards-view .builder-shell,
  body.is-builder-cards-view .builder-shell--centered .builder-card-wrap,
  body.is-builder-cards-closing .builder-shell,
  body.is-builder-cards-closing .builder-shell--centered .builder-card-wrap {
    animation: none !important;
  }

  /* Pane chrome transitions — without this, the .builder-pane's
     border-radius / box-shadow / border-color SNAP at t=0 when the
     body class flips (they're applied by CSS at different selectors
     per mode). With this, they morph smoothly over the same 720ms
     window as the JS FLIP transform on the wrap, so the chat content
     reads as one continuous element scaling down.

     Gradient backgrounds can't be CSS-transitioned (browser limit) so
     background-image still snaps — usually invisible since the
     cards-mode gradient is subtle white→cream and the single-mode
     pane already sits on a white-ish surface.

     Applied to all panes so close (cards → single) also morphs the
     chrome back smoothly, not just open. */
  body.is-builder-chat .builder-shell--centered .builder-pane,
  body.is-builder-cards-view .builder-shell--centered .builder-pane {
    transition:
      border-radius 720ms cubic-bezier(0.22, 1, 0.36, 1),
      border-color 720ms cubic-bezier(0.22, 1, 0.36, 1),
      box-shadow 720ms cubic-bezier(0.22, 1, 0.36, 1),
      background-color 720ms cubic-bezier(0.22, 1, 0.36, 1) !important;
  }
  @media (prefers-reduced-motion: reduce) {
    body.is-builder-chat .builder-shell--centered .builder-pane,
    body.is-builder-cards-view .builder-shell--centered .builder-pane {
      transition: none !important;
    }
  }

  /* ────────────────────────────────────────────────────────────
     Active-pane swap (single-mode)
     ────────────────────────────────────────────────────────────
     When NOT in cards-view, only the active pane's card-wrap is
     visible — others are display:none. Default active pane is
     "chat" (set on body as data-builder-active-pane="chat") so
     out-of-the-box behaviour is identical to before this feature
     landed. Tapping the Sections or Preview card in cards-view
     flips the attribute to that pane key, and on close the morph
     puts THAT pane into the chat's slot fullscreen.

     dashboard-v2-page.html wireCardsView controls the JS side.
     ──────────────────────────────────────────────────────────── */
  /* Specificity has to MATCH the is-flex-flow-chat rule at line ~6782
     that sets chat-wrap to display:flex !important. Two-classes-on-body
     here so we tie the score, then win by source order (later in file). */
  body.is-flex-flow-chat.is-builder-chat:not(.is-builder-cards-view)[data-builder-active-pane="sections"] .builder-card-wrap[data-pane-key="chat"],
  body.is-flex-flow-chat.is-builder-chat:not(.is-builder-cards-view)[data-builder-active-pane="preview"]  .builder-card-wrap[data-pane-key="chat"],
  body:not(.is-builder-cards-view)[data-builder-active-pane="sections"] .builder-card-wrap[data-pane-key="preview"],
  body:not(.is-builder-cards-view)[data-builder-active-pane="preview"]  .builder-card-wrap[data-pane-key="sections"] {
    display: none !important;
  }
  /* Non-chat active pane wraps fill the shell like chat does.
     Specificity matches the is-flex-flow-chat chat-wrap rule at
     line ~6782 (2 classes on body) so source order wins. NOT
     position:fixed — a transformed ancestor breaks it (the shell's
     drawer transform), pushing the wrap down past the topbar. */
  body.is-flex-flow-chat.is-builder-chat:not(.is-builder-cards-view)[data-builder-active-pane="sections"] .builder-card-wrap[data-pane-key="sections"],
  body.is-flex-flow-chat.is-builder-chat:not(.is-builder-cards-view)[data-builder-active-pane="preview"]  .builder-card-wrap[data-pane-key="preview"] {
    display: flex !important;
    flex-direction: column !important;
    height: 100dvh !important;
    min-height: 0 !important;
    max-height: 100dvh !important;
    overflow: hidden !important;
    /* --topband (not --cream): the wrap paints the top safe-area on iOS; a
       greyer cream read as a grey band / card edge behind the sections
       (founder-reported). Keep it identical to the pane + chrome. */
    background: var(--topband) !important;
  }
  /* The pane inside (the actual sections-list / preview-iframe
     container) needs to take the wrap's full space.
     2026-05-24 v2: active-pane gate restored + is-builder-sliding
     parallel selector so the styles apply during the slide too. */
  body:not(.is-builder-cards-view)[data-builder-active-pane="sections"] .builder-sections-pane,
  body:not(.is-builder-cards-view)[data-builder-active-pane="preview"]  .builder-preview-pane,
  body.is-builder-sliding:not(.is-builder-cards-view) .builder-sections-pane,
  body.is-builder-sliding:not(.is-builder-cards-view) .builder-preview-pane {
    display: flex !important;
    flex-direction: column !important;
    flex: 1 1 auto !important;
    min-height: 0 !important;
    width: 100% !important;
  }
  /* Preview pane goes truly fullscreen (full-bleed iframe) in single-
     mode regardless of builder-state, so the template iframe fills the
     viewport below the topbar without the rounded card chrome around
     it. Mirrors the existing data-builder-state="ready" fullscreen
     rule but doesn't gate on the AI having generated a site. The dock
     + DRAFT pill float on top via their own position:fixed/absolute. */
  body:not(.is-builder-cards-view)[data-builder-active-pane="preview"] .builder-preview-pane,
  body.is-builder-sliding:not(.is-builder-cards-view) .builder-preview-pane {
    padding: 0 !important;
    margin: 0 !important;
    border: 0 !important;
    border-radius: 0 !important;
    background: var(--topband) !important;
  }
  /* 2026-06-03 GREY-BAR ROOT CAUSE + FIX (founder: "use the exact same
     method as the preview page").
     The preview pane has NO grey at the top; the sections pane did. The
     ONLY structural difference: the preview pane is `position: fixed`
     (dashboard-v2.css ~L7768) while the sections pane was in-flow.
     On iOS Safari with viewport-fit=cover, an IN-FLOW element's
     background is NOT painted into the top safe-area / notch strip —
     so the bare canvas shows through there as a grey band behind the
     floating topbar buttons. A POSITIONED (fixed) element's background
     IS painted into that zone (which is exactly why the fixed preview
     pane is clean). So give the sections pane the preview pane's exact
     fixed full-bleed model: it becomes a positioned cream surface that
     paints the safe-area strip, with the section list scrolling inside
     its __body. Fixed is relative to the transformed main.dash ancestor
     (same containing block as the preview pane), so the geometry matches
     preview 1:1. No card, no margin, no rounded corners, no grey. */
  body:not(.is-builder-cards-view)[data-builder-active-pane="sections"] .builder-sections-pane,
  body.is-builder-sliding:not(.is-builder-cards-view) .builder-sections-pane {
    position: fixed !important;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    width: auto !important;
    height: auto !important;
    min-height: 0 !important;
    z-index: 1;
    margin: 0 !important;
    border: 0 !important;
    border-radius: 0 !important;
    background: var(--cream) !important;
    display: flex !important;
    flex-direction: column !important;
    overflow: hidden !important;
  }
  /* The section list scrolls INSIDE the fixed pane (mirrors the preview
     pane's flex:1 body holding the iframe). flex:1 + min-height:0 lets
     it take the remaining height; overflow-y:auto makes only the list
     scroll, leaving the fixed cream surface (incl. the painted safe-area
     strip) stationary behind the topbar. */
  body:not(.is-builder-cards-view)[data-builder-active-pane="sections"] .builder-sections-pane__body,
  body.is-builder-sliding:not(.is-builder-cards-view) .builder-sections-pane__body {
    flex: 1 1 auto !important;
    min-height: 0 !important;
    overflow-y: auto !important;
    -webkit-overflow-scrolling: touch;
  }
  body:not(.is-builder-cards-view)[data-builder-active-pane="preview"] .builder-preview-body,
  body.is-builder-sliding:not(.is-builder-cards-view) .builder-preview-body {
    flex: 1 1 auto !important;
    padding: 0 !important;
    margin: 0 !important;
    border: 0 !important;
    border-radius: 0 !important;
    width: 100% !important;
    height: 100% !important;
  }
  /* main.dash has padding: 0 16px globally for the dashboard content
     gutter — but the AI builder wants edge-to-edge for the preview
     iframe, and during a pane slide all 3 wraps are visible at once.
     If chat keeps its gutter (16px each side) and preview doesn't,
     when the slide ends and the attribute flips to "chat", the gutter
     comes back and the chat pane snaps 32px narrower in one frame.
     Founder feedback 2026-05-24: "when it's ended and im back on the
     chat page the chat page will snap into position". Fix: zero the
     gutter for ALL builder single-mode panes so widths stay constant
     across the slide and into the resting state. */
  body.is-builder-chat:not(.is-builder-cards-view) main.dash {
    padding: 0 !important;
  }
  /* Hide the cards-view-only card-label when the pane is fullscreen
     in single mode — labels only belong in cards-view chrome. */
  body:not(.is-builder-cards-view) .builder-card-label {
    display: none !important;
  }

  /* ────────────────────────────────────────────────────────────
     Single-mode pane slide animation (founder 2026-05-23)
     ────────────────────────────────────────────────────────────
     When the user swipes between chat / preview / sections in
     single-mode, JS adds body.is-builder-sliding for the duration
     of the morph + sets inline translateX on the from- and to-
     wraps. This block forces ALL three wraps + panes visible and
     pinned over the area below the topbar, regardless of the
     current data-builder-active-pane attribute — so both the
     out-going and in-coming panes are on screen at the same time.
     JS strips the class on transitionend, returning to the normal
     active-pane CSS (which hides the from-pane via display:none).

     Specificity gotcha: the active-pane hide rules at ~7676 use
     `body.<2-classes>:not(.is-builder-cards-view)[data-active-pane=..]
     .builder-card-wrap[data-pane=..]` = 2 cls + 1 :not + 1 attr +
     1 cls + 1 attr = (0,6,0). We match that by stacking 3 body
     classes + :not here (no body attr — the boot code only sets
     [data-builder-active-pane] when a saved non-chat pane is
     restored, so on fresh "active=chat" the attr is MISSING and a
     rule requiring it never fires; that's the original "to-pane
     stays display:none during the slide" bug). 3 classes + :not =
     (0,4,0); + wrap (0,2,0) = (0,6,0). Same specificity, mine
     comes later in source so wins on tiebreak.
     ──────────────────────────────────────────────────────────── */
  body.is-builder-sliding.is-flex-flow-chat.is-builder-chat:not(.is-builder-cards-view) .builder-card-wrap[data-pane-key="chat"],
  body.is-builder-sliding.is-flex-flow-chat.is-builder-chat:not(.is-builder-cards-view) .builder-card-wrap[data-pane-key="preview"],
  body.is-builder-sliding.is-flex-flow-chat.is-builder-chat:not(.is-builder-cards-view) .builder-card-wrap[data-pane-key="sections"] {
    display: flex !important;
    flex-direction: column !important;
    position: fixed !important;
    /* main.dash + the rich-mount wrapper both have transform:translateX
       (drawer-offset animation) which makes them containing blocks for
       position:fixed descendants. The nearest one (rich-mount) starts
       at the natural top of the wrap area (~97px below viewport top,
       i.e. below the mob-topbar + any banner). So top:0 here = natural
       wrap top, NOT viewport top. Don't use 52px — that would push
       the slide 52px LOWER than its natural resting position and the
       wrap would snap up by 52px on cleanup. */
    top: 0 !important;
    left: 0 !important;
    right: 0 !important;
    bottom: 0 !important;
    width: 100% !important;
    height: auto !important;
    min-height: 0 !important;
    max-height: none !important;
    z-index: 12 !important;
    background: var(--cream) !important;
    overflow: hidden !important;
  }
  /* Force the inner pane visible — preview-pane + sections-pane default
     to display:none until their wrap's active-pane attr matches. */
  body.is-builder-sliding.is-flex-flow-chat.is-builder-chat:not(.is-builder-cards-view) .builder-pane[data-pane-key="chat"],
  body.is-builder-sliding.is-flex-flow-chat.is-builder-chat:not(.is-builder-cards-view) .builder-pane[data-pane-key="preview"],
  body.is-builder-sliding.is-flex-flow-chat.is-builder-chat:not(.is-builder-cards-view) .builder-pane[data-pane-key="sections"] {
    display: flex !important;
    flex-direction: column !important;
    flex: 1 1 auto !important;
    min-height: 0 !important;
    width: 100% !important;
  }
  /* Preview chrome (empty hero / dock / status pill) fades opacity 0
     when active-pane ≠ preview — that fade is what makes the new pane
     look blank during the slide and then snap in at the end (founder
     report 2026-05-23 "pages only load after the swipe animation is
     completed"). Override during the slide so they paint immediately
     at full opacity alongside the moving wrap. The opacity rules at
     ~3887 / ~4019 / ~4071 are (0,3,0) (1 :not + 1 :not + 1 class +
     1 class); our (0,5,0) selector beats them. */
  body.is-builder-sliding .builder-preview-empty,
  body.is-builder-sliding .builder-preview-dock,
  body.is-builder-sliding .builder-preview-status {
    opacity: 1 !important;
    transition: none !important;
  }

  /* Sibling cards + dock fade in alongside the JS morph so they
     don't pop into existence. The chat card-wrap is explicitly
     excluded — JS handles its transform animation.
     Duration synced to the JS OPEN_MS (720ms) so the whole
     transition lands together — no competing rhythms. */
  body.is-builder-cards-view .builder-shell--centered .builder-card-wrap:not([data-pane-key="chat"]),
  body.is-builder-cards-view .builder-cards-dock,
  body.is-builder-cards-view .builder-cards-back {
    animation: bsCardsSiblingFadeIn 720ms cubic-bezier(0.22, 1, 0.36, 1) both;
  }
  @keyframes bsCardsSiblingFadeIn {
    from { opacity: 0; }
    to   { opacity: 1; }
  }

  @media (prefers-reduced-motion: reduce) {
    body.is-builder-cards-view .builder-shell--centered .builder-card-wrap:not([data-pane-key="chat"]),
    body.is-builder-cards-view .builder-cards-dock,
    body.is-builder-cards-view .builder-cards-back {
      animation: none !important;
    }
  }
}

/* ============================================================================
   Settings 3D-gradient upgrade (founder 2026-06-04). Brings the Forms-page
   control language — raised gradient dropdowns, 3D toggles, tactile buttons —
   to EVERY settings tab. Scoped to .set-shell so the home/builder surfaces are
   untouched. Mirrors the .fhub treatment in dashboard-v2-page-renderers.js.
   ============================================================================ */

/* Dropdowns -> raised 3D-gradient well + chevron (covers .set-select, .ss-select,
   and any bare <select> in a settings section). */
.set-shell select,
.set-shell .set-select,
.set-shell .ss-select {
  -webkit-appearance: none; appearance: none;
  background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%236b5a4c' stroke-width='2.6' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E") no-repeat right 10px center,
              linear-gradient(180deg, #ffffff, #f3f3f3);
  border: 1px solid rgba(31,22,17,0.14);
  border-bottom-color: rgba(31,22,17,0.2);
  border-radius: 8px;
  padding: 8px 30px 8px 12px;
  color: var(--ink);
  box-shadow: 0 1px 2px rgba(31,22,17,0.07), inset 0 1px 0 rgba(255,255,255,0.85);
}
.set-shell select:focus,
.set-shell .set-select:focus,
.set-shell .ss-select:focus { outline: none; border-color: rgba(31,22,17,0.4); background-color: #fff; }

/* Toggles -> 3D-gradient (off = cream bevel, on = blue gradient). Geometry from
   the base .set-switch is preserved so the knob travel still lines up. */
.set-shell .set-switch-slider {
  background: linear-gradient(180deg, #e4ddd2, #d8d0c4);
  box-shadow: inset 0 1px 2px rgba(31,22,17,0.18);
}
.set-shell .set-switch-slider::before {
  background: linear-gradient(180deg, #fff, #f1f1f1);
  box-shadow: 0 1px 2px rgba(31,22,17,0.3), inset 0 1px 0 rgba(255,255,255,0.9);
}
.set-shell .set-switch input:checked + .set-switch-slider {
  background: linear-gradient(180deg, #5aa2ff, #2563eb);
  box-shadow: inset 0 1px 0 rgba(255,255,255,0.45), 0 1px 2px rgba(37,99,235,0.4);
}

/* Secondary / ghost action buttons -> light 3D-gradient (matches .fd-btn).
   Covers the generic .btn-ghost AND the Account tab's custom .sa-btn-ghost. */
.set-shell .btn-ghost,
.set-shell .sa .sa-btn-ghost {
  background: linear-gradient(180deg, #ffffff, #f8f8f8);
  border: 1px solid rgba(31,22,17,0.14);
  border-bottom-color: rgba(31,22,17,0.2);
  color: var(--ink);
  box-shadow: 0 1px 3px rgba(31,22,17,0.07), 0 2px 1px -1px rgba(31,22,17,0.04), inset 0 1px 0 rgba(255,255,255,0.9);
}
.set-shell .btn-ghost:hover,
.set-shell .sa .sa-btn-ghost:hover {
  background: linear-gradient(180deg, #ffffff, #f4f4f4);
  border-color: rgba(31,22,17,0.2); border-bottom-color: rgba(31,22,17,0.26);
  box-shadow: 0 2px 5px rgba(31,22,17,0.09), 0 2px 1px -1px rgba(31,22,17,0.04), inset 0 1px 0 rgba(255,255,255,0.9);
}
.set-shell .btn-ghost:active,
.set-shell .sa .sa-btn-ghost:active { transform: translateY(0.5px); box-shadow: 0 0 2px rgba(31,22,17,0.05), inset 0 1px 0 rgba(255,255,255,0.7); }

/* Primary CTAs -> keep their prominent fill, add a tactile 3D bevel + lift. */
.set-shell .btn-primary {
  box-shadow: inset 0 1px 0 rgba(255,255,255,0.22), 0 1px 2px rgba(31,22,17,0.16), 0 2px 6px -2px rgba(31,22,17,0.22);
}
.set-shell .btn-primary:active { transform: translateY(0.5px); box-shadow: inset 0 1px 2px rgba(0,0,0,0.2); }

/* ============================================================================
   Page headings now live in the mobile topbar (founder 2026-06-04) — drop the
   duplicated in-content title + subtitle so every sub-page starts clean like
   the Forms page. This stylesheet only loads on the sub-page shell, so the
   home page is unaffected. Action bars (.rich-actions) are preserved; a
   heading block with no actions is removed entirely to reclaim the space.
   ============================================================================ */
.rich-head-text { display: none !important; }
.rich-head:not(:has(.rich-actions)) { display: none !important; }
.leads-v4 .page-title,
.leads-v4 .page-sub { display: none !important; }
.pg-head { display: none !important; }
/* Settings: hide only the title TEXT, not .set-shell-head — that element is a
   grid row (grid-column:1/-1); display:none on it breaks the rail/content grid. */
.set-shell-title { display: none !important; }
.fd-page-title,
.fd-page-sub { display: none !important; }

/* Settings (mobile): the page heading now lives in the topbar, so the empty
   .set-shell-head row + grid gap left the rail sitting too low with no space
   before the first section (founder 2026-06-04). Collapse the empty head, pull
   the rail up under the topbar, and add breathing room before the content. */
@media (max-width: 900px) {
  /* Drop the grid on mobile — with the heading row gone, the grid's row
     structure still held the rail ~44px down. Block flow stacks rail → content
     cleanly, with the rail sitting right under the topbar. */
  .set-shell { display: block !important; padding-top: 6px !important; }
  .set-shell-head { display: none !important; }
  /* The sticky rail was rendering ~50px below its flow position (a sticky vs
     fixed-topbar containing-block quirk), leaving a big gap under the topbar.
     Make it static so it sits at its natural top, with space before content. */
  .set-rail { position: static !important; margin: 0 -18px 18px !important; }
}


/* ────────────────────────────────────────────────────────────────────
   PUBLISH PANE — 4th card (founder 2026-06-10, Replit-style publish
   surface). Mirrors the sections pane's visibility + fixed-pane model
   EXACTLY: the iOS safe-area position:fixed rule (grey-bar fix above)
   and the (0,6,0) slide-specificity tie at ~L8561. The publish body
   moved here from the chat-pane tab; its component styles live in
   dashboard-v2.css ~L8118 and apply unchanged. */

/* Base: hidden in single mode, shown in cards-view (mirrors the
   .builder-sections-pane default in dashboard-v2.css ~L13441). */
.builder-shell .builder-publish-pane { display: none; }
body.is-builder-cards-view .builder-shell .builder-publish-pane {
  display: flex !important;
  flex-direction: column;
}

@media (max-width: 720px) {
  /* Hide the publish WRAP whenever publish isn't the active pane.
     Both variants sit at (0,5,0) — deliberately BELOW the slide rule's
     (0,6,0) so both panes paint during a slide. The second selector
     covers states where is-builder-chat is absent (mirrors the
     2026-05-24 "wrap renders visible underneath" bleed class). */
  body.is-builder-chat:not(.is-builder-cards-view):not([data-builder-active-pane="publish"]) .builder-card-wrap[data-pane-key="publish"],
  body:not(.is-builder-cards-view):not([data-builder-active-pane="publish"]):not(.is-builder-sliding) .builder-card-wrap[data-pane-key="publish"] {
    display: none !important;
  }
  /* Other wraps hide when publish is active (mirrors the ~L8408 group). */
  body.is-flex-flow-chat.is-builder-chat:not(.is-builder-cards-view)[data-builder-active-pane="publish"] .builder-card-wrap[data-pane-key="chat"],
  body:not(.is-builder-cards-view)[data-builder-active-pane="publish"] .builder-card-wrap[data-pane-key="preview"],
  body:not(.is-builder-cards-view)[data-builder-active-pane="publish"] .builder-card-wrap[data-pane-key="sections"] {
    display: none !important;
  }
  /* Active publish wrap fills the shell (mirrors ~L8419). --topband so the
     wrap paints the top safe-area the same colour as the chrome. */
  body.is-flex-flow-chat.is-builder-chat:not(.is-builder-cards-view)[data-builder-active-pane="publish"] .builder-card-wrap[data-pane-key="publish"] {
    display: flex !important;
    flex-direction: column !important;
    height: 100dvh !important;
    min-height: 0 !important;
    max-height: 100dvh !important;
    overflow: hidden !important;
    background: var(--topband) !important;
  }
  /* THE pane: fixed full-bleed — a positioned element paints the iOS
     top safe-area strip (grey-bar root cause + fix, 2026-06-03). */
  body:not(.is-builder-cards-view)[data-builder-active-pane="publish"] .builder-publish-pane,
  body.is-builder-sliding:not(.is-builder-cards-view) .builder-publish-pane {
    position: fixed !important;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    width: auto !important;
    height: auto !important;
    min-height: 0 !important;
    z-index: 1;
    margin: 0 !important;
    border: 0 !important;
    border-radius: 0 !important;
    background: var(--cream) !important;
    display: flex !important;
    flex-direction: column !important;
    overflow: hidden !important;
  }
  /* Only the body scrolls; the fixed cream surface stays put. */
  body:not(.is-builder-cards-view)[data-builder-active-pane="publish"] .builder-publish-pane__body,
  body.is-builder-sliding:not(.is-builder-cards-view) .builder-publish-pane__body {
    flex: 1 1 auto !important;
    min-height: 0 !important;
    overflow-y: auto !important;
    -webkit-overflow-scrolling: touch;
  }
  /* Slide participation — EXACT (0,6,0) tie (mirrors ~L8561 group). */
  body.is-builder-sliding.is-flex-flow-chat.is-builder-chat:not(.is-builder-cards-view) .builder-card-wrap[data-pane-key="publish"] {
    display: flex !important;
    flex-direction: column !important;
    position: fixed !important;
    top: 0 !important;
    left: 0 !important;
    right: 0 !important;
    bottom: 0 !important;
    width: 100% !important;
    height: auto !important;
    min-height: 0 !important;
    max-height: none !important;
    z-index: 12 !important;
    background: var(--cream) !important;
    overflow: hidden !important;
  }

  /* Pane chrome + Replit-style components. Head clears the floating
     mob-topbar; generous rhythm matches the clean-on-cream system. */
  .builder-publish-pane__head {
    padding: calc(64px + env(safe-area-inset-top, 0px)) 20px 4px;
    flex-shrink: 0;
  }
  .builder-publish-pane__title {
    margin: 0;
    font-size: 1.35rem;
    font-weight: 800;
    letter-spacing: -0.01em;
    color: var(--ink);
  }
  .builder-publish-pane__lede {
    margin: 6px 0 0;
    font-size: 0.92rem;
    color: var(--ink-soft, #6b6459);
  }
  .builder-publish-pane__body {
    padding: 14px 16px calc(28px + env(safe-area-inset-bottom, 0px));
  }
  /* (0,3,0) + later-file order: must beat the OLD chat-pane publish-tab
     styling in css/builder-shell-pane.css (~L1502 "unified card" block,
     `.builder-shell--centered[data-builder-state="ready"] .builder-publish-body`
     gap:0 + padding 24/20/32) which otherwise bleeds into this pane. */
  .builder-shell--centered .builder-publish-pane .builder-publish-body,
  .builder-publish-pane .builder-publish-body {
    display: flex;
    flex-direction: column;
    gap: 12px; /* P5 rhythm: 12px between cards in a group */
    padding: 0;
  }
  /* Neutralise the rest of the old unified-card bleed inside the PANE:
     the editor is its own full card here (the old stack relied on the
     status row to close its bottom edge), and the "Last published" meta
     line is quiet text, not a bordered row. */
  .builder-publish-pane .builder-publish-editor {
    border: 1px solid var(--hairline);
    border-radius: 14px;
    background: var(--paper);
    overflow: hidden;
  }
  /* "Last published Xh ago" — right-aligned 12px muted line ABOVE the
     publish button (P5; markup order puts it first in the action block). */
  .builder-publish-pane .builder-publish-action { gap: 6px; }
  .builder-publish-pane .builder-publish-action__status--meta {
    border: 0;
    border-radius: 0;
    background: transparent;
    padding: 0 2px;
    margin: 0;
    justify-content: flex-end;
    text-align: right;
    font-size: 12px;
    color: var(--ink-soft, #6b6459);
  }
  /* Publish button: 52px tall, radius 14, full width (P5). */
  .builder-publish-pane .builder-publish-btn--mob {
    width: 100%;
    height: 52px;
    padding: 0 18px;
    border-radius: 14px;
    margin: 0;
  }
  /* "What you're publishing" preview card — scaled, non-interactive.
     P5: always visible; soft cream-gradient empty state (business
     initial in a 44px circle + caption) paints first, the iframe
     overlays it once loaded — never a grey void. */
  .builder-pubpane-preview {
    border: 1px solid var(--hairline);
    border-radius: 14px;
    overflow: hidden;
    background: var(--paper);
  }
  .builder-pubpane-preview__frame {
    position: relative;
    height: 210px;
    overflow: hidden;
    pointer-events: none;
    background: linear-gradient(160deg, #FCFAF6 0%, #F4EFE6 58%, #EFE8DC 100%);
  }
  .builder-pubpane-preview__empty {
    position: absolute;
    inset: 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 10px;
  }
  .builder-pubpane-preview__initial {
    width: 44px;
    height: 44px;
    border-radius: 50%;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    background: var(--paper, #fff);
    box-shadow: 0 1px 2px rgba(31, 22, 17, 0.06), 0 0 0 1px var(--hairline);
    font-size: 1.05rem;
    font-weight: 700;
    color: var(--ink);
  }
  .builder-pubpane-preview__emptycap {
    font-size: 0.82rem;
    font-weight: 550;
    color: var(--ink-soft, #6b6459);
  }
  .builder-pubpane-preview__iframe {
    position: absolute;
    top: 0;
    left: 0;
    width: 200%;
    height: 420px;
    border: 0;
    transform: scale(0.5);
    transform-origin: 0 0;
    display: block;
    background: transparent;
    opacity: 0;
    transition: opacity 0.25s ease;
  }
  .builder-pubpane-preview__iframe.is-loaded {
    opacity: 1;
    background: #fff;
  }
  .builder-pubpane-preview__cap {
    padding: 9px 14px;
    font-size: 0.78rem;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--ink-soft, #6b6459);
    border-top: 1px solid var(--hairline);
  }
  /* Open / Pause — ONE row of two equal side-by-side ghost buttons (P5). */
  .builder-pubpane-rows {
    display: flex;
    flex-direction: row;
    gap: 8px;
  }
  .builder-pubpane-rows:not(:has(:not([hidden]))) { display: none; }
  .builder-pubpane-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    width: 100%;
    appearance: none;
    text-decoration: none;
    border: 1px solid var(--hairline);
    background: var(--paper);
    border-radius: 14px;
    padding: 13px 16px;
    font: inherit;
    font-weight: 600;
    font-size: 0.95rem;
    color: var(--ink);
    cursor: pointer;
  }
  /* Inside the Open/Pause pair the two ghosts split the row equally and
     centre their content (icon trails the label at a 8px gap). */
  .builder-pubpane-rows .builder-pubpane-row {
    flex: 1 1 0;
    min-width: 0;
    justify-content: center;
    gap: 8px;
    padding: 13px 12px;
  }
  .builder-pubpane-row:active { background: var(--cream-2, #f2efe9); }
  .builder-pubpane-row svg { color: var(--ink-soft, #6b6459); flex-shrink: 0; }

  /* ── P4 regroup (founder 2026-06-10): labelled clusters with eyebrow
     captions ("YOUR ADDRESS" / "GROWTH") + the compact address chip that
     merges status dot + live URL + copy into one row (replaces the old
     hero card + separate status row). publish.js hooks unchanged. ── */
  .builder-pubgroup {
    display: flex;
    flex-direction: column;
    gap: 12px;       /* P5 rhythm: 12px between cards in a group */
    margin-top: 16px; /* + the body's 12px gap = 28px between groups */
  }
  .builder-pubgroup__eyebrow {
    font-size: 11px;
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--ink-faint, #9C9183);
    margin: 0 2px -4px; /* 12px gap − 4px = 8px below the eyebrow */
  }
  .builder-pubchip__copy {
    appearance: none;
    width: 100%;
    display: flex;
    align-items: center;
    gap: 10px;
    border: 1px solid var(--hairline);
    background: var(--paper);
    border-radius: 14px;
    padding: 14px;
    font: inherit;
    text-align: left;
    color: var(--ink);
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
  }
  .builder-pubchip__copy:active { background: var(--cream-2, #f2efe9); }
  /* P5: status reads as one soft pill — 8px dot + 11px caps text inside
     a tinted capsule. Colour pivots on the chip's data-state. */
  .builder-pubchip__pill {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 4px 9px 4px 7px;
    border-radius: 999px;
    background: rgba(46, 125, 50, 0.10);
  }
  .builder-pubchip__dot {
    flex: 0 0 auto;
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: #2e7d32;
  }
  .builder-pubchip__state {
    flex: 0 0 auto;
    font-size: 11px;
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: #2a6b2e;
  }
  .builder-pubchip[data-state="paused"] .builder-pubchip__pill { background: rgba(184, 130, 7, 0.12); }
  .builder-pubchip[data-state="paused"] .builder-pubchip__dot { background: #b88207; }
  .builder-pubchip[data-state="paused"] .builder-pubchip__state { color: #8f6605; }
  .builder-pubchip[data-state="draft"] .builder-pubchip__pill { background: var(--cream-2, #f2efe9); }
  .builder-pubchip[data-state="draft"] .builder-pubchip__dot { background: var(--ink-faint, #9C9183); }
  .builder-pubchip[data-state="draft"] .builder-pubchip__state { color: var(--ink-soft, #6b6459); }
  /* URL value: sans-serif 15px semibold (P5 — monospace dropped). */
  .builder-pubchip__url {
    flex: 1 1 auto;
    min-width: 0;
    font-size: 15px;
    font-weight: 600;
    letter-spacing: -0.005em;
    color: var(--ink);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  }
  .builder-pubchip__icon { flex: 0 0 auto; display: inline-flex; margin-left: auto; color: var(--ink-soft, #6b6459); }
  .builder-pubchip__copy.is-copied .builder-pubchip__icon { color: #2e7d32; }
  /* P5 card consistency: the custom-domain upsell matches the 14px radius
     + standard hairline of every other card in the pane. */
  .builder-publish-pane .builder-publish-custom-row {
    border-radius: 14px;
    border-color: var(--hairline);
    padding: 15px 16px;
  }
  /* Badge row (GROWTH cluster): stacked title + sub. */
  .builder-pubpane-row--badge { text-decoration: none; }
  .builder-pubpane-row__main {
    display: flex;
    flex-direction: column;
    gap: 2px;
    flex: 1 1 auto;
    min-width: 0;
  }
  .builder-pubpane-row__sub {
    font-size: 0.78rem;
    font-weight: 500;
    color: var(--ink-soft, #6b6459);
  }
}


/* ────────────────────────────────────────────────────────────────────
   SECTIONS PANE v2 — library swap system (S3, founder spec
   docs/SECTIONS_PANE_REDESIGN_SPEC.md §5, 2026-06-10).

   The pane CHROME (fixed full-bleed, iOS safe-area paint, slide ties,
   wrap hide/show) is the EXISTING .builder-sections-pane enumeration —
   no new pane keys here. This block styles only the new INNER content:
   the library block list ([data-builder-secpane], which also carries
   builder-sections-pane__body so the existing scroll + padding rules
   apply) and the bottom sheet + toast that mount on document.body.

   Mode gate: secpane.js adds .is-secpane-library to the pane ONLY when
   GET /api/builder/library-blocks confirms a library draft. V5 drafts
   never get the class, so their pane renders exactly as before.
   All new classes are builder-secpane- prefixed (no home-page bleed —
   this stylesheet is builder-page-only anyway).
   ──────────────────────────────────────────────────────────────────── */

/* Self-contained box model — don't depend on the monolith's global
   `* { box-sizing: border-box }` (dashboard-v2.css is slated for deletion
   once the css/ refactor stabilises; width:100% + padding rows overflow
   without this). */
.builder-secpane, .builder-secpane *,
.builder-secpane-sheet, .builder-secpane-sheet *,
.builder-secpane-toast { box-sizing: border-box; }

/* Default: the library container is invisible until the GET confirms
   library mode. (0,1,0) base loses to every is-secpane-library rule. */
.builder-secpane { display: none !important; }

/* Library mode: show the library list, hide the V5 body + emptystate.
   (0,3,0) + !important + end-of-file source order beats the not-ready
   state gate at ~L4614 (also (0,3,0) !important) — if the GET returned
   blocks, a draft exists and the list must show regardless of the
   shell's V5-centric builder-state attribute. */
.builder-sections-pane.is-secpane-library .builder-secpane {
  display: flex !important;
  flex-direction: column;
}
.builder-sections-pane.is-secpane-library .builder-sections-emptystate,
.builder-sections-pane.is-secpane-library .builder-sections-pane__body:not(.builder-secpane) {
  display: none !important;
}

/* ── Head ──────────────────────────────────────────────────────────── */
.builder-secpane__head { flex-shrink: 0; }
.builder-secpane__titlerow {
  display: flex;
  align-items: baseline;
  gap: 8px;
}
.builder-secpane__title {
  margin: 0;
  font-size: 1.35rem;
  font-weight: 800;
  letter-spacing: -0.01em;
  color: var(--ink);
}
.builder-secpane__count {
  font-size: 0.82rem;
  font-weight: 600;
  color: var(--ink-soft, #8A7866);
}
.builder-secpane__lede {
  margin: 6px 0 0;
  font-size: 0.92rem;
  line-height: 1.5;
  color: var(--ink-soft, #8A7866);
}

/* ── Block list (P8 density 2026-06-10: back to the DENSE overview —
   ~52px rows, 44×26 thumbs, the whole page anatomy on one phone screen.
   Keeps the P4 one-card + hairline-separator shell.) ── */
.builder-secpane__list {
  list-style: none;
  margin: 4px 0 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  flex-shrink: 0; /* P8: never shrink-clip rows — the pane body scrolls instead */
  /* founder design 2026-06-10 (mock B): rows are standalone 3D tiles */
  gap: 10px;
  border: 0;
  background: transparent;
}
.builder-secpane.is-busy .builder-secpane__list,
.builder-secpane.is-busy .builder-secpane__addrow {
  pointer-events: none;
  opacity: 0.72;
  transition: opacity 0.15s;
}
.builder-secpane__row {
  display: flex;
  align-items: center;
  gap: 4px;
  transition: transform 0.12s ease; /* premium pass: rows acknowledge touch */
  /* founder design 2026-06-10: the 3D-gradient squircle tile (composer recipe) */
  background: linear-gradient(180deg, #FFFFFF 0%, #F5F5F5 100%);
  border: 1px solid rgba(31, 22, 17, 0.10);
  border-radius: 16px;
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.9),
    inset 0 -1px 0 rgba(31, 22, 17, 0.04),
    0 1px 2px rgba(31, 22, 17, 0.06),
    0 2px 6px -2px rgba(31, 22, 17, 0.08);
  padding: 0 8px 0 12px;
  transition: transform 0.12s, box-shadow 0.12s;
}
.builder-secpane__row:active { transform: translateY(0.5px); }
/* Drag-handle glyph — quiet touch-hold affordance only (reorder lives in
   the ⋯ menu); cursor:grab signals the future direct-drag interaction. */
.builder-secpane__grip {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 16px;
  margin-left: 0;
  color: var(--ink-faint, #C9C2B8);
  opacity: 0.3;
  cursor: grab;
}
.builder-secpane__main {
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  align-items: center;
  gap: 10px;
  appearance: none;
  border: 0;
  background: transparent;
  font: inherit;
  text-align: left;
  padding: 9px 4px 9px 4px; /* P8: 9px vertical row padding → ~52px rows */
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
/* Thumb 96×60 (sections-editor 2026-06-10 — founder: the 44×26 chips were
   illegible). Grey placeholder + archetype initial when the PNG 404s
   (data-thumb-missing stamped by onerror). */
.builder-secpane__thumb {
  position: relative;
  flex: 0 0 96px;
  width: 96px;
  height: 60px;
  border-radius: 8px;
  overflow: hidden;
  background: var(--cream-2, #F1F1F1);
  box-shadow: inset 0 0 0 1px var(--hairline);
}
.builder-secpane__thumb img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: top;
  display: block;
}
.builder-secpane__thumb[data-thumb-missing] img { display: none; }
.builder-secpane__thumb[data-thumb-missing]::after {
  content: attr(data-initial);
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 0.7rem;
  font-weight: 700;
  color: var(--ink-faint, #B5ADA2);
}
.builder-secpane__text {
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 2px; /* P8: tight 2px between eyebrow+dot row and the label */
}
.builder-secpane__eyerow {
  display: flex;
  align-items: center;
  gap: 6px;
  min-width: 0;
}
/* famdots removed (premium pass 2026-06-11: unlabelled colour codes are
   decoration pretending to be information; families show in the drawer) */
.builder-secpane__eyebrow {
  font-size: 9.5px;
  font-weight: 700;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: var(--ink-faint, #9C9183);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
/* Treatment label: single line at P8 density — ellipsis acceptable here.
   Registry labels are kept ≤ ~26 chars (P5 shortening) so nothing clips
   at 390px in practice (~32-char budget). */
.builder-secpane__name {
  font-size: 13.5px;
  font-weight: 600;
  letter-spacing: -0.005em;
  line-height: 1.3;
  color: var(--ink);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.builder-secpane__iconbtn {
  flex: 0 0 auto;
  width: 24px;
  height: 24px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  appearance: none;
  border: 0;
  border-radius: 7px;
  background: transparent;
  color: var(--ink-soft, #8A7866);
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
.builder-secpane__iconbtn:active { background: var(--cream-2, #F1F1F1); }

/* Hidden block: dim thumb + text 45%, keep the pill + restore eye crisp. */
.builder-secpane__row.is-hidden .builder-secpane__thumb,
.builder-secpane__row.is-hidden .builder-secpane__text { opacity: 0.45; }
.builder-secpane__hidpill {
  flex: 0 0 auto;
  font-size: 0.68rem;
  font-weight: 700;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--ink-soft, #8A7866);
  background: var(--cream-2, #F1F1F1);
  border-radius: 999px;
  padding: 3px 9px;
  margin-left: 6px;
}

/* Skeleton rows (loading state — 4 of them). */
.builder-secpane__row--skeleton { pointer-events: none; padding: 9px 14px; gap: 10px; }
.builder-secpane__skel {
  display: block;
  border-radius: 6px;
  background: linear-gradient(90deg, var(--cream-2, #F1F1F1) 25%, var(--cream-3, #E5E5E5) 50%, var(--cream-2, #F1F1F1) 75%);
  background-size: 200% 100%;
  animation: bsSecpaneShimmer 1.3s ease-in-out infinite;
}
.builder-secpane__thumb.builder-secpane__skel { box-shadow: none; }
.builder-secpane__skel--eyebrow { width: 56px; height: 8px; border-radius: 4px; }
.builder-secpane__skel--name { width: 120px; height: 11px; border-radius: 5px; margin-top: 3px; }
@keyframes bsSecpaneShimmer {
  0% { background-position: 180% 0; }
  100% { background-position: -20% 0; }
}
@media (prefers-reduced-motion: reduce) {
  .builder-secpane__skel { animation: none; }
}

/* Error state — calm retry row. */
.builder-secpane__error {
  border: 1px dashed var(--hairline-2);
  border-radius: 12px;
  padding: 22px 16px;
  text-align: center;
  display: flex;
  flex-direction: column;
  gap: 12px;
  align-items: center;
}
.builder-secpane__error-msg {
  margin: 0;
  font-size: 0.92rem;
  color: var(--ink-soft, #8A7866);
}
.builder-secpane__retry {
  appearance: none;
  border: 1px solid var(--hairline-2);
  background: var(--paper, #fff);
  border-radius: 999px;
  font: inherit;
  font-size: 0.88rem;
  font-weight: 600;
  color: var(--ink);
  padding: 8px 18px;
  cursor: pointer;
}
.builder-secpane__retry:active { background: var(--cream-2, #F1F1F1); }

/* "Chat first" no-draft state (Phase 0 gate, 2026-06-11) — shown when the
   thread hasn't built a site yet, instead of another thread's sections. */
.builder-secpane__nodraft {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: 10px;
  padding: 56px 26px 30px;
}
.builder-secpane__nodraft-mark {
  width: 54px;
  height: 54px;
  border-radius: 16px;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--ink-soft, #8A7866);
  background: linear-gradient(180deg, #FFFFFF 0%, #F5F4F1 100%);
  border: 1px solid rgba(31, 22, 17, 0.10);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.9), 0 1px 2px rgba(31, 22, 17, 0.05);
  margin-bottom: 4px;
}
.builder-secpane__nodraft-title {
  margin: 0;
  font-size: 1.06rem;
  font-weight: 700;
  letter-spacing: -0.01em;
  color: var(--ink, #1F1611);
}
.builder-secpane__nodraft-lede {
  margin: 0;
  font-size: 0.9rem;
  line-height: 1.5;
  color: var(--ink-soft, #8A7866);
  max-width: 300px;
}
.builder-secpane__nodraft-cta {
  appearance: none;
  border: 0;
  margin-top: 8px;
  border-radius: 999px;
  font: inherit;
  font-size: 0.92rem;
  font-weight: 600;
  color: #FAFAFA;
  background: linear-gradient(180deg, #2A2520 0%, #1F1611 100%);
  padding: 11px 24px;
  cursor: pointer;
  box-shadow: 0 1px 3px rgba(31, 22, 17, 0.2), inset 0 1px 0 rgba(255, 255, 255, 0.08);
}
.builder-secpane__nodraft-cta:active { transform: scale(0.97); }

/* "+ Add a section" ghost row. */
.builder-secpane__addrow {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  appearance: none;
  width: 100%;
  flex-shrink: 0;
  border: 1px solid rgba(31, 22, 17, 0.10);
  border-radius: 14px;
  background: linear-gradient(180deg, #FFFFFF 0%, #F5F5F5 100%);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.9),
    inset 0 -1px 0 rgba(31, 22, 17, 0.04),
    0 1px 2px rgba(31, 22, 17, 0.06),
    0 2px 6px -2px rgba(31, 22, 17, 0.08);
  font: inherit;
  font-size: 0.9rem;
  font-weight: 650;
  color: var(--ink, #1F1D17);
  min-height: 44px; /* P8: compact 44px ghost row */
  padding: 0 16px;
  margin-top: 2px;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
.builder-secpane__addrow:active { background: var(--cream-2, #F1F1F1); color: var(--ink); }
.builder-secpane__addrow-icon { display: inline-flex; }

/* ── Bottom sheet (swap drawer / action sheet / add grid) ──────────── */
.builder-secpane-sheet {
  position: fixed;
  inset: 0;
  z-index: 9999;
  display: flex;
  align-items: flex-end;
  justify-content: center;
}
.builder-secpane-sheet[hidden] { display: none !important; }
.builder-secpane-sheet__backdrop {
  position: absolute;
  inset: 0;
  background: rgba(15, 10, 6, 0.32);
}
.builder-secpane-sheet__card {
  position: relative;
  z-index: 1;
  width: 100%;
  max-width: 480px;
  max-height: 88dvh;
  display: flex;
  flex-direction: column;
  background: var(--paper, #fff);
  border-radius: 18px 18px 0 0;
  box-shadow: 0 -6px 32px rgba(15, 10, 6, 0.16);
  /* transition-based slide (2026-06-10: replayed keyframes snapped on iOS).
     Default = parked below the viewport; .is-open carries it up. */
  transform: translateY(105%);
  transition: transform 0.46s cubic-bezier(0.32, 0.72, 0, 1);
  padding-bottom: env(safe-area-inset-bottom, 0px);
}
.builder-secpane-sheet.is-open .builder-secpane-sheet__card { transform: translateY(0); }
.builder-secpane-sheet__backdrop { opacity: 0; transition: opacity 0.32s ease; }
.builder-secpane-sheet.is-open .builder-secpane-sheet__backdrop { opacity: 1; }
.builder-secpane-sheet.is-closing .builder-secpane-sheet__card { transition-duration: 0.3s; transition-timing-function: cubic-bezier(0.4, 0, 1, 1); }
@media (prefers-reduced-motion: reduce) {
  .builder-secpane-sheet__card { transition: none; transform: none; }
  .builder-secpane-sheet__backdrop { transition: none; opacity: 1; }
}
.builder-secpane-sheet__grab {
  flex-shrink: 0;
  width: 38px;
  height: 4px;
  border-radius: 999px;
  background: var(--hairline-2);
  margin: 9px auto 2px;
}
.builder-secpane-sheet__head {
  flex-shrink: 0;
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 16px 12px;
  border-bottom: 1px solid var(--hairline);
}
.builder-secpane-sheet__back[hidden] { display: none !important; } /* author display beats UA [hidden] otherwise */
.builder-secpane-sheet__back {
  flex: 0 0 auto;
  width: 32px;
  height: 32px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  appearance: none;
  border: 0;
  border-radius: 9px;
  background: var(--cream-2, #F1F1F1);
  color: var(--ink);
  cursor: pointer;
}
.builder-secpane-sheet__titles {
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 1px;
}
.builder-secpane-sheet__title {
  margin: 0;
  font-size: 1.05rem;
  font-weight: 750;
  letter-spacing: -0.01em;
  color: var(--ink);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.builder-secpane-sheet__sub {
  font-size: 0.8rem;
  color: var(--ink-soft, #8A7866);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.builder-secpane-sheet__close {
  flex: 0 0 auto;
  width: 32px;
  height: 32px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  appearance: none;
  border: 0;
  border-radius: 9px;
  background: transparent;
  color: var(--ink-soft, #8A7866);
  cursor: pointer;
}
.builder-secpane-sheet__close:active,
.builder-secpane-sheet__back:active { background: var(--cream-3, #E5E5E5); }
.builder-secpane-sheet__body {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  padding: 14px 16px calc(20px + env(safe-area-inset-bottom, 0px));
}
.builder-secpane-sheet__body.is-busy { pointer-events: none; opacity: 0.72; }

/* "Picked for your style" rail — horizontal scroll, FIRST in the drawer. */
.builder-secpane-rail { margin-bottom: 18px; }
.builder-secpane-rail__head,
.builder-secpane-group__head {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: var(--ink-faint, #9C9183);
  margin-bottom: 9px;
}
.builder-secpane-rail__scroll {
  display: flex;
  gap: 10px;
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
  margin: 0 -16px;
  padding: 2px 16px 6px;
}
.builder-secpane-rail__scroll::-webkit-scrollbar { display: none; }
.builder-secpane-railcard {
  flex: 0 0 148px;
  display: flex;
  flex-direction: column;
  gap: 7px;
  appearance: none;
  border: 1px solid var(--hairline);
  border-radius: 12px;
  background: var(--paper, #fff);
  padding: 7px;
  font: inherit;
  text-align: left;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
.builder-secpane-railcard:active { border-color: var(--hairline-3); }
.builder-secpane-railcard__thumb {
  position: relative;
  display: block;
  width: 100%;
  aspect-ratio: 4 / 3;
  border-radius: 8px;
  overflow: hidden;
  background: var(--cream-2, #F1F1F1);
  box-shadow: inset 0 0 0 1px var(--hairline);
}
.builder-secpane-railcard__thumb img,
.builder-secpane-opt__thumb img {
  width: 100%;
  height: 100%;
  /* contain, not cover: short strip sections were zoom-cropped to blur,
     tall ones decapitated. Full section, cream letterbox (founder fix). */
  object-fit: contain;
  object-position: center top;
  display: block;
}
.builder-secpane-railcard__thumb[data-thumb-missing] img,
.builder-secpane-opt__thumb[data-thumb-missing] img { display: none; }
.builder-secpane-railcard__thumb[data-thumb-missing]::after,
.builder-secpane-opt__thumb[data-thumb-missing]::after {
  content: attr(data-initial);
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 1.1rem;
  font-weight: 700;
  color: var(--ink-faint, #B5ADA2);
}
.builder-secpane-railcard__name {
  font-size: 0.82rem;
  font-weight: 650;
  line-height: 1.25;
  color: var(--ink);
  padding: 0 3px 3px;
  display: -webkit-box; /* P5: no truncation — wrap to max 2 lines */
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

/* Family groups — 2-col option grid (spec §5.3). */
.builder-secpane-group { margin-bottom: 18px; }
.builder-secpane-group:last-child { margin-bottom: 4px; }
.builder-secpane-group__grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 10px;
}
.builder-secpane-opt {
  display: flex;
  flex-direction: column;
  gap: 6px;
  appearance: none;
  border: 1px solid var(--hairline);
  border-radius: 12px;
  background: var(--paper, #fff);
  padding: 7px 7px 9px;
  font: inherit;
  text-align: left;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  min-width: 0;
}
.builder-secpane-opt:active { border-color: var(--hairline-3); }
.builder-secpane-opt.is-current {
  border-color: var(--orange, #D9541E);
  box-shadow: 0 0 0 1.5px var(--orange, #D9541E);
}
.builder-secpane-opt__thumb {
  position: relative;
  display: block;
  width: 100%;
  /* 2026-06-10: thumbs are now MOBILE captures (390w) — 4/3 top-anchored
     shows the section's head legibly instead of a desktop corner crop */
  aspect-ratio: 4 / 3;
  border-radius: 8px;
  overflow: hidden;
  background: var(--cream-2, #F1F1F1);
  box-shadow: inset 0 0 0 1px var(--hairline);
}
.builder-secpane-opt__name {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 0.86rem;
  font-weight: 650;
  color: var(--ink);
  padding: 0 3px;
  min-width: 0;
}
.builder-secpane-opt__name > :first-child { min-width: 0; }
.builder-secpane-opt__pill {
  flex: 0 0 auto;
  font-size: 0.62rem;
  font-weight: 700;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: #fff;
  background: var(--orange, #D9541E);
  border-radius: 999px;
  padding: 2px 7px;
}
.builder-secpane-opt__desc {
  font-size: 0.76rem;
  line-height: 1.4;
  color: var(--ink-soft, #8A7866);
  padding: 0 3px;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

/* ⋯ action sheet rows. */
.builder-secpane-acts {
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.builder-secpane-act {
  display: flex;
  align-items: center;
  gap: 12px;
  appearance: none;
  width: 100%;
  border: 1px solid var(--hairline);
  background: var(--paper, #fff);
  border-radius: 12px;
  padding: 13px 16px;
  font: inherit;
  font-size: 0.95rem;
  font-weight: 600;
  color: var(--ink);
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
.builder-secpane-act:active { background: var(--cream-2, #F1F1F1); }
.builder-secpane-act.is-off { opacity: 0.38; cursor: default; }
.builder-secpane-act.is-off:active { background: var(--paper, #fff); }
.builder-secpane-act__icon {
  display: inline-flex;
  color: var(--ink-soft, #8A7866);
}
.builder-secpane-act.is-danger {
  padding: 0;
  border-color: color-mix(in srgb, var(--red, #C03A1B) 28%, transparent);
}
.builder-secpane-act__danger-btn {
  display: flex;
  align-items: center;
  gap: 12px;
  appearance: none;
  width: 100%;
  border: 0;
  background: transparent;
  border-radius: 12px;
  padding: 13px 16px;
  font: inherit;
  font-size: 0.95rem;
  font-weight: 600;
  color: var(--red, #C03A1B);
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
.builder-secpane-act__danger-btn .builder-secpane-act__icon { color: var(--red, #C03A1B); }
/* Inline "Remove — sure?" confirm (spec §5.2 — no native dialog). */
.builder-secpane-act.is-confirm {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 9px 10px 9px 16px;
}
.builder-secpane-act__q {
  font-size: 0.92rem;
  font-weight: 650;
  color: var(--ink);
}
.builder-secpane-act__confirm {
  display: inline-flex;
  gap: 8px;
}
.builder-secpane-act__yes,
.builder-secpane-act__no {
  appearance: none;
  border-radius: 9px;
  font: inherit;
  font-size: 0.86rem;
  font-weight: 650;
  padding: 8px 14px;
  cursor: pointer;
}
.builder-secpane-act__yes {
  border: 0;
  background: var(--red, #C03A1B);
  color: #fff;
}
.builder-secpane-act__no {
  border: 1px solid var(--hairline-2);
  background: var(--paper, #fff);
  color: var(--ink);
}

/* Add-a-section archetype grid (17 tiles, count badge when on page). */
.builder-secpane-archgrid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 10px;
}
.builder-secpane-arch {
  display: flex;
  align-items: center;
  gap: 11px;
  appearance: none;
  border: 1px solid var(--hairline);
  border-radius: 12px;
  background: var(--paper, #fff);
  padding: 12px 13px;
  font: inherit;
  text-align: left;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: transform 0.12s ease;
}
.builder-secpane-arch:active { background: var(--cream-2, #F1F1F1); transform: scale(0.985); }
.builder-secpane-arch__icon {
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 34px;
  height: 34px;
  border-radius: 10px;
  background: linear-gradient(180deg, #FFFFFF 0%, #F3F2EF 100%);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.9), inset 0 0 0 1px rgba(31, 22, 17, 0.09);
  color: var(--ink, #1F1D17);
}
.builder-secpane-arch__text { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.builder-secpane-arch__label {
  font-size: 0.92rem;
  font-weight: 650;
  color: var(--ink);
}
.builder-secpane-arch__count {
  font-size: 0.72rem;
  font-weight: 600;
  color: var(--ink-soft, #8A7866);
  background: var(--cream-2, #F1F1F1);
  border-radius: 999px;
  padding: 2px 8px;
}

/* ── Toast — calm bottom pill, auto-dismiss ───────────────────────── */
.builder-secpane-toast {
  position: fixed;
  left: 50%;
  bottom: calc(24px + env(safe-area-inset-bottom, 0px));
  transform: translateX(-50%) translateY(12px);
  z-index: 10000;
  max-width: min(92vw, 420px);
  background: var(--ink, #1F1611);
  color: var(--cream, #FBFBFB);
  font-size: 0.88rem;
  font-weight: 550;
  line-height: 1.45;
  border-radius: 12px;
  padding: 11px 16px;
  box-shadow: 0 8px 28px rgba(15, 10, 6, 0.25);
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.2s ease, transform 0.2s ease;
}
.builder-secpane-toast.is-on {
  opacity: 1;
  transform: translateX(-50%) translateY(0);
}

/* ── 3D gradient finish (founder ask 2026-06-10): the May-30 composer
   recipes applied to the new surfaces — Publish CTA gets the dark
   send-button treatment; dock tiles + Open/Pause ghosts get the light
   pill treatment. Lovable/Stripe tactility, same matched set as chat. */
@media (max-width: 720px) {
  .builder-publish-btn--mob {
    background: linear-gradient(180deg, #2A211B 0%, #1F1611 100%) !important;
    border: 1px solid rgba(0, 0, 0, 0.55) !important;
    box-shadow:
      0 1px 2px rgba(0, 0, 0, 0.18),
      0 4px 10px -2px rgba(0, 0, 0, 0.22),
      inset 0 1px 0 rgba(255, 255, 255, 0.10) !important;
    transition: transform 0.12s, box-shadow 0.12s;
  }
  .builder-publish-btn--mob:active { transform: translateY(0.5px); }
  .builder-pubpane-row,
  .builder-cards-dock__btn {
    background: linear-gradient(180deg, #FFFFFF 0%, #F5F5F5 100%) !important;
    border: 1px solid rgba(31, 22, 17, 0.10) !important;
    box-shadow:
      inset 0 1px 0 rgba(255, 255, 255, 0.9),
      inset 0 -1px 0 rgba(31, 22, 17, 0.04),
      0 1px 2px rgba(31, 22, 17, 0.06),
      0 2px 6px -2px rgba(31, 22, 17, 0.08) !important;
    transition: background 0.12s, transform 0.12s;
  }
  .builder-pubpane-row:active,
  .builder-cards-dock__btn:active { transform: translateY(0.5px); }
}

/* ── Section editor sheet (docs/SECTIONS_EDITOR_PLAN.md, 2026-06-10) ──
   Tap a row → editor sheet: big preview + Style/Animation/Photos/Video/
   Text rows (rendered only when the treatment declares them). All classes
   builder-secpane- prefixed; sheets mount on body (same as the drawer). */
.builder-secpane-ed__hero {
  margin: 2px 2px 14px;
  border-radius: 12px;
  overflow: hidden;
  box-shadow: inset 0 0 0 1px var(--hairline);
  background: var(--cream-2, #F1F1F1);
}
.builder-secpane-ed__thumb { display: block; }
.builder-secpane-ed__thumb img {
  display: block;
  width: 100%;
  height: auto;
  max-height: 340px;
  object-fit: contain;
  object-position: center top;
}
.builder-secpane__row:active { transform: scale(0.988); }
/* View on page: a quiet ghost button under the editor preview */
.builder-secpane-ed__viewbtn {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  width: 100%;
  margin: -4px 0 12px;
  padding: 11px 0;
  border: 1px solid rgba(31, 22, 17, 0.13);
  border-radius: 999px;
  background: var(--paper, #fff);
  font: inherit;
  font-size: 0.88rem;
  font-weight: 650;
  color: var(--ink, #1F1D17);
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: transform 0.12s ease;
}
.builder-secpane-ed__viewbtn:active { transform: scale(0.985); background: var(--cream-2, #F1F1F1); }
.builder-secpane-edrows {
  display: flex;
  flex-direction: column;
  border: 1px solid var(--hairline);
  border-radius: 12px;
  overflow: hidden;
  background: var(--paper, #fff);
}
.builder-secpane-edrow {
  display: flex;
  align-items: center;
  gap: 12px;
  width: 100%;
  padding: 12px 13px;
  border: 0;
  border-top: 1px solid var(--hairline);
  background: transparent;
  font: inherit;
  /* buttons inherit UA/link blues elsewhere on the page — pin the ink */
  color: var(--ink, #1F1D17);
  text-align: left;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
.builder-secpane-edrow:first-child { border-top: 0; }
.builder-secpane-edrow:active { background: var(--cream-2, #F4F2EE); }
.builder-secpane-edrow__icon {
  flex: none;
  width: 30px;
  height: 30px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 9px;
  background: var(--cream-2, #F4F2EE);
  color: var(--ink, #1F1D17);
  box-shadow: inset 0 0 0 1px var(--hairline);
}
.builder-secpane-edrow__icon svg { display: block; }
.builder-secpane-edrow__label { font-weight: 650; font-size: 14.5px; flex: none; color: var(--ink, #1F1D17); letter-spacing: -0.01em; }
.builder-secpane-edrow__value {
  margin-left: auto;
  font-size: 13px;
  color: var(--ink-soft, #8A8578);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 46%;
}
.builder-secpane-edrow__chev { flex: none; color: var(--ink-soft, #8A8578); display: inline-flex; }
.builder-secpane-ed__note {
  margin: 10px 4px;
  font-size: 13px;
  line-height: 1.5;
  color: var(--ink-soft, #8A8578);
}
.builder-secpane-ed__mini {
  flex: none;
  width: 40px;
  height: 26px;
  border-radius: 6px;
  background-size: cover;
  background-position: center;
  box-shadow: inset 0 0 0 1px var(--hairline);
}
.builder-secpane-act.is-current { box-shadow: inset 0 0 0 1.5px var(--ink, #1F1D17); }

/* media picker grid */
.builder-secpane-medi__upload { margin: 0 0 12px; }
.builder-secpane-medi__reset {
  display: block;
  width: 100%;
  margin: 0 0 12px;
  padding: 11px;
  border: 1px dashed var(--hairline-2, #D8D4CB);
  border-radius: 10px;
  background: transparent;
  font: inherit;
  font-size: 13.5px;
  color: var(--ink-soft, #8A8578);
  cursor: pointer;
}
.builder-secpane-medi__grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 8px;
  margin: 8px 0 16px;
}
.builder-secpane-medi__cell {
  position: relative;
  aspect-ratio: 4 / 3;
  border: 0;
  border-radius: 9px;
  background-size: cover;
  background-position: center;
  background-color: var(--cream-2, #F1F1F1);
  box-shadow: inset 0 0 0 1px var(--hairline);
  cursor: pointer;
  overflow: hidden;
  padding: 0;
}
.builder-secpane-medi__cell.is-current { box-shadow: 0 0 0 2.5px var(--ink, #1F1D17); }
.builder-secpane-medi__cell video {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  pointer-events: none;
}
.builder-secpane-medi__grid--vid { grid-template-columns: repeat(2, 1fr); }

/* text sheet */
/* Gap #11 — per-section AI rewrite control at the top of the Text sheet. */
.builder-secpane-txt__ai {
  display: flex;
  gap: 8px;
  align-items: stretch;
  margin: 0 0 16px;
  padding: 0 0 16px;
  border-bottom: 1px solid var(--hairline, #ECE7DD);
}
.builder-secpane-txt__dir {
  flex: 1 1 auto;
  min-width: 0;
  padding: 10px 12px;
  border: 1px solid var(--hairline-2, #D8D4CB);
  border-radius: 10px;
  background: var(--paper, #fff);
  font: inherit;
  font-size: 13.5px;
}
.builder-secpane-txt__dir:focus { outline: none; border-color: var(--ink, #1F1D17); }
.builder-secpane-txt__rewrite {
  flex: none;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 10px 14px;
  border: 1px solid var(--ink, #1F1D17);
  border-radius: 10px;
  background: var(--ink, #1F1D17);
  color: #fff;
  font: inherit;
  font-size: 13.5px;
  font-weight: 650;
  cursor: pointer;
  white-space: nowrap;
  transition: opacity 0.15s, transform 0.15s;
}
.builder-secpane-txt__rewrite:active { transform: scale(0.97); }
.builder-secpane-txt__rewrite.is-busy { opacity: 0.55; pointer-events: none; }
.builder-secpane-txt__rewrite.is-busy span::after {
  content: '…';
}
.builder-secpane-txt__input.is-rewritten {
  border-color: var(--accent, #B5542B);
  background: color-mix(in srgb, var(--accent, #B5542B) 6%, var(--paper, #fff));
}
.builder-secpane-txt__field { display: block; margin: 0 0 14px; }
.builder-secpane-txt__label {
  display: block;
  margin: 0 0 6px;
  font-size: 12.5px;
  font-weight: 650;
  letter-spacing: 0.01em;
}
.builder-secpane-txt__label em { font-style: normal; color: var(--ink-soft, #8A8578); font-weight: 500; }
.builder-secpane-txt__input {
  display: block;
  width: 100%;
  padding: 11px 12px;
  border: 1px solid var(--hairline-2, #D8D4CB);
  border-radius: 10px;
  background: var(--paper, #fff);
  font: inherit;
  font-size: 14px;
  line-height: 1.45;
  resize: vertical;
}
.builder-secpane-txt__input:focus { outline: none; border-color: var(--ink, #1F1D17); }
.builder-secpane-txt__save {
  display: block;
  width: 100%;
  margin: 6px 0 2px;
  padding: 13px;
  border: 0;
  border-radius: 999px;
  background: var(--ink, #1F1D17);
  color: #fff;
  font: inherit;
  font-size: 14.5px;
  font-weight: 650;
  cursor: pointer;
}

/* ── Animation option demos (founder 2026-06-10: show the motion) ──────
   Each option row carries a 64x48 looping mini-scene: bar = headline,
   chips = cards, odo = counting figure, photo = the section's own thumb.
   All loops pause under prefers-reduced-motion (static scene stands). */
.builder-secpane-act--demo { display: flex; align-items: center; gap: 13px; }
.builder-secpane-animdemo {
  flex: none;
  width: 64px;
  height: 48px;
  border-radius: 8px;
  overflow: hidden;
  background: var(--cream-2, #F4F2EE);
  box-shadow: inset 0 0 0 1px var(--hairline);
  display: block;
  position: relative;
}
.builder-secpane-animdemo__scene {
  position: absolute;
  inset: 7px 9px;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  gap: 5px;
}
.builder-secpane-animdemo__bar {
  display: block;
  width: 70%;
  height: 6px;
  border-radius: 3px;
  background: var(--ink, #1F1D17);
  opacity: 0.85;
}
.builder-secpane-animdemo__chips { display: flex; gap: 4px; }
.builder-secpane-animdemo__chip {
  flex: 1;
  height: 14px;
  border-radius: 4px;
  background: var(--paper, #fff);
  box-shadow: inset 0 0 0 1px var(--hairline-2, #D8D4CB);
}
.builder-secpane-animdemo__photo {
  position: absolute;
  inset: 0;
  background-size: cover;
  background-position: center top;
}
.builder-secpane-animdemo__odo {
  display: block;
  height: 16px;
  overflow: hidden;
  font-size: 13px;
  font-weight: 800;
  line-height: 16px;
  color: var(--ink, #1F1D17);
  letter-spacing: -0.01em;
}
.builder-secpane-animdemo__digits { display: block; }

@keyframes bsSecpaneDemoReveal {
  0% { transform: translateY(14px); opacity: 0; }
  28% { transform: translateY(0); opacity: 1; }
  78% { transform: translateY(0); opacity: 1; }
  92%, 100% { transform: translateY(0); opacity: 0; }
}
@keyframes bsSecpaneDemoChip {
  0% { transform: translateY(12px); opacity: 0; }
  22% { transform: translateY(0); opacity: 1; }
  78% { transform: translateY(0); opacity: 1; }
  92%, 100% { transform: translateY(0); opacity: 0; }
}
@keyframes bsSecpaneDemoZoom {
  from { transform: scale(1); }
  to { transform: scale(1.18); }
}
@keyframes bsSecpaneDemoOdo {
  0%, 18% { transform: translateY(0); }
  28%, 44% { transform: translateY(-16px); }
  54%, 70% { transform: translateY(-32px); }
  80%, 100% { transform: translateY(-48px); }
}
@keyframes bsSecpaneDemoHover {
  0%, 35% { transform: translateY(0); box-shadow: inset 0 0 0 1px var(--hairline-2, #D8D4CB); }
  60%, 80% { transform: translateY(-4px); box-shadow: 0 4px 8px rgba(15, 10, 6, 0.18); }
  100% { transform: translateY(0); }
}
@keyframes bsSecpaneDemoDrift {
  from { transform: scale(1.16) translateY(3px); }
  to { transform: scale(1.16) translateY(-3px); }
}
@keyframes bsSecpaneDemoBlur {
  0% { filter: blur(4px); opacity: 0.35; }
  32% { filter: blur(0); opacity: 1; }
  80% { filter: blur(0); opacity: 1; }
  94%, 100% { filter: blur(4px); opacity: 0.35; }
}
@keyframes bsSecpaneDemoWipe {
  0% { clip-path: inset(0 100% 0 0); }
  38% { clip-path: inset(0 0 0 0); }
  86% { clip-path: inset(0 0 0 0); }
  96%, 100% { clip-path: inset(0 100% 0 0); }
}
@keyframes bsSecpaneDemoSettle {
  0% { transform: scale(1.12) rotate(1.4deg); opacity: 0; }
  40% { transform: scale(1) rotate(0deg); opacity: 1; }
  84% { transform: scale(1) rotate(0deg); opacity: 1; }
  96%, 100% { transform: scale(1.12) rotate(1.4deg); opacity: 0; }
}
@keyframes bsSecpaneDemoLine {
  0% { transform: translateY(110%); }
  26% { transform: translateY(0); }
  80% { transform: translateY(0); }
  94%, 100% { transform: translateY(110%); }
}
@keyframes bsSecpaneDemoStar {
  0% { transform: scale(0.2); opacity: 0; }
  18% { transform: scale(1.25); opacity: 1; }
  28% { transform: scale(1); opacity: 1; }
  82% { transform: scale(1); opacity: 1; }
  94%, 100% { transform: scale(0.2); opacity: 0; }
}
@keyframes bsSecpaneDemoSlide {
  0% { transform: translateX(26px); opacity: 0; }
  32% { transform: translateX(0); opacity: 1; }
  82% { transform: translateX(0); opacity: 1; }
  95%, 100% { transform: translateX(26px); opacity: 0; }
}
.builder-secpane-animdemo[data-demo="reveal"] .builder-secpane-animdemo__scene {
  animation: bsSecpaneDemoReveal 2.4s ease-in-out infinite;
}
.builder-secpane-animdemo[data-demo="stagger"] .builder-secpane-animdemo__chip {
  animation: bsSecpaneDemoChip 2.6s ease-in-out infinite;
}
.builder-secpane-animdemo[data-demo="stagger"] .builder-secpane-animdemo__chip:nth-child(2) { animation-delay: 0.18s; }
.builder-secpane-animdemo[data-demo="stagger"] .builder-secpane-animdemo__chip:nth-child(3) { animation-delay: 0.36s; }
.builder-secpane-animdemo[data-demo="kenburns"] .builder-secpane-animdemo__photo {
  animation: bsSecpaneDemoZoom 3s ease-in-out infinite alternate;
}
.builder-secpane-animdemo[data-demo="countup"] .builder-secpane-animdemo__digits {
  animation: bsSecpaneDemoOdo 2.8s ease-in-out infinite;
}
.builder-secpane-animdemo[data-demo="hover"] .builder-secpane-animdemo__chip:nth-child(2) {
  animation: bsSecpaneDemoHover 2.4s ease-in-out infinite;
}
.builder-secpane-animdemo[data-demo="parallax"] .builder-secpane-animdemo__photoabs {
  animation: bsSecpaneDemoDrift 2.2s ease-in-out infinite alternate;
}
.builder-secpane-animdemo[data-demo="blurfade"] .builder-secpane-animdemo__scene {
  animation: bsSecpaneDemoBlur 2.6s ease-in-out infinite;
}
.builder-secpane-animdemo[data-demo="wipe"] .builder-secpane-animdemo__photoabs {
  animation: bsSecpaneDemoWipe 2.6s cubic-bezier(0.6, 0.1, 0.2, 1) infinite;
}
.builder-secpane-animdemo[data-demo="settle"] .builder-secpane-animdemo__photoabs {
  animation: bsSecpaneDemoSettle 2.8s ease-in-out infinite;
}
/* textrise mini-demo: three text bars rising inside masks, staggered */
.builder-secpane-animdemo__lines {
  position: absolute;
  inset: 8px 10px;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 4px;
}
.builder-secpane-animdemo__line {
  display: block;
  height: 7px;
  overflow: hidden;
}
.builder-secpane-animdemo__line > span {
  display: block;
  height: 6px;
  border-radius: 3px;
  background: var(--ink, #1F1D17);
  opacity: 0.85;
}
.builder-secpane-animdemo__line:nth-child(2) > span { width: 78%; }
.builder-secpane-animdemo__line:nth-child(3) > span { width: 52%; }
.builder-secpane-animdemo[data-demo="textrise"] .builder-secpane-animdemo__line > span {
  animation: bsSecpaneDemoLine 2.6s cubic-bezier(0.16, 1, 0.3, 1) infinite;
}
.builder-secpane-animdemo[data-demo="textrise"] .builder-secpane-animdemo__line:nth-child(2) > span { animation-delay: 0.14s; }
.builder-secpane-animdemo[data-demo="textrise"] .builder-secpane-animdemo__line:nth-child(3) > span { animation-delay: 0.28s; }
/* starshine mini-demo: gold stars popping over rising review chips */
.builder-secpane-animdemo__starrow {
  display: flex;
  justify-content: center;
  gap: 2px;
  margin-bottom: 2px;
}
.builder-secpane-animdemo__shinestar {
  display: inline-flex;
  color: #f6b21b;
}
.builder-secpane-animdemo[data-demo="starshine"] .builder-secpane-animdemo__shinestar {
  animation: bsSecpaneDemoStar 2.8s cubic-bezier(0.34, 1.56, 0.64, 1) infinite;
}
.builder-secpane-animdemo[data-demo="starshine"] .builder-secpane-animdemo__shinestar:nth-child(2) { animation-delay: 0.1s; }
.builder-secpane-animdemo[data-demo="starshine"] .builder-secpane-animdemo__shinestar:nth-child(3) { animation-delay: 0.2s; }
.builder-secpane-animdemo[data-demo="starshine"] .builder-secpane-animdemo__shinestar:nth-child(4) { animation-delay: 0.3s; }
.builder-secpane-animdemo[data-demo="starshine"] .builder-secpane-animdemo__shinestar:nth-child(5) { animation-delay: 0.4s; }
.builder-secpane-animdemo[data-demo="starshine"] .builder-secpane-animdemo__chip {
  animation: bsSecpaneDemoChip 2.8s ease-in-out infinite;
  animation-delay: 0.55s;
}
.builder-secpane-animdemo[data-demo="starshine"] .builder-secpane-animdemo__chip:nth-child(2) { animation-delay: 0.68s; }
.builder-secpane-animdemo[data-demo="starshine"] .builder-secpane-animdemo__chip:nth-child(3) { animation-delay: 0.81s; }
.builder-secpane-animdemo[data-demo="photoslide"] .builder-secpane-animdemo__photoabs {
  animation: bsSecpaneDemoSlide 2.6s cubic-bezier(0.16, 1, 0.3, 1) infinite;
}
@media (prefers-reduced-motion: reduce) {
  .builder-secpane-animdemo__scene,
  .builder-secpane-animdemo__chip,
  .builder-secpane-animdemo__photo,
  .builder-secpane-animdemo__line > span,
  .builder-secpane-animdemo__shinestar,
  .builder-secpane-animdemo__digits { animation: none !important; }
}

/* ── Animation STAGE: the section's own preview playing the pick ───────── */
.builder-secpane-animstage {
  margin: 2px 2px 14px;
  border-radius: 12px;
  overflow: hidden;
  background: var(--cream-2, #F1F1F1);
  box-shadow: inset 0 0 0 1px var(--hairline);
  /* 2026-06-12 live stage: the real-render frame sizes itself — the old
     fixed 4/3 scene box left a grey under-fill below the Replay pill */
  position: relative;
  padding: 10px 10px 12px;
  text-align: center;
}
/* ── stage SCENES (founder 2026-06-11: animating the flat thumb couldn't
   demonstrate most motions — each animation gets a bespoke staged
   demonstration). Every loop is 3.2s; rebuilding the scene restarts it. ── */
.builder-secpane-stg {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 16px;
}
.builder-secpane-stg__frame {
  position: relative;
  width: 56%;
  height: 86%;
  border-radius: 10px;
  overflow: hidden;
  background: #E8E5DF;
  box-shadow: 0 14px 30px -14px rgba(31, 22, 17, 0.35), 0 0 0 1px rgba(31, 22, 17, 0.07);
  will-change: transform, opacity, filter;
}
.builder-secpane-sheet.is-desktop-view .builder-secpane-stg__frame { width: 90%; height: 64%; }
.builder-secpane-stg__photo {
  position: absolute;
  inset: 0;
  background-size: cover;
  background-position: center top;
  will-change: transform, opacity;
}
.builder-secpane-stg__frame.is-dim::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, rgba(15, 18, 26, 0.28), rgba(15, 18, 26, 0.62));
}
/* reveal: the section rises + fades in */
@keyframes bsStgRise {
  0% { transform: translateY(26px); opacity: 0; }
  26% { transform: translateY(0); opacity: 1; }
  84% { transform: translateY(0); opacity: 1; }
  96%, 100% { transform: translateY(0); opacity: 0; }
}
.builder-secpane-stg[data-play="reveal"] .builder-secpane-stg__frame { animation: bsStgRise 3.2s ease-in-out infinite; }
/* blurfade: soft focus in */
@keyframes bsStgBlur {
  0% { filter: blur(12px); opacity: 0.25; }
  30% { filter: blur(0); opacity: 1; }
  84% { filter: blur(0); opacity: 1; }
  96%, 100% { filter: blur(12px); opacity: 0.25; }
}
.builder-secpane-stg[data-play="blurfade"] .builder-secpane-stg__frame { animation: bsStgBlur 3.2s ease-in-out infinite; }
/* kenburns: the photo zooms INSIDE the masked frame */
@keyframes bsStgZoom { from { transform: scale(1); } to { transform: scale(1.2); } }
.builder-secpane-stg[data-play="kenburns"] .builder-secpane-stg__photo { animation: bsStgZoom 3.2s ease-in-out infinite alternate; }
/* parallax: an oversized photo drifts vertically inside the masked frame */
.builder-secpane-stg[data-play="parallax"] .builder-secpane-stg__photo {
  inset: -14% 0;
  animation: bsStgDrift 2.6s ease-in-out infinite alternate;
}
@keyframes bsStgDrift { from { transform: translateY(-4.5%); } to { transform: translateY(4.5%); } }
/* wipe: clip sweep with a bright front edge travelling the reveal */
@keyframes bsStgWipe {
  0% { clip-path: inset(0 100% 0 0); }
  34% { clip-path: inset(0 0 0 0); }
  88% { clip-path: inset(0 0 0 0); }
  98%, 100% { clip-path: inset(0 100% 0 0); }
}
.builder-secpane-stg[data-play="wipe"] .builder-secpane-stg__photo:not(.is-ghost) { animation: bsStgWipe 3.2s cubic-bezier(0.6, 0.1, 0.2, 1) infinite; }
.builder-secpane-stg__photo.is-ghost { opacity: 0.18; }
.builder-secpane-stg__wipefront {
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  width: 3px;
  border-radius: 2px;
  background: var(--orange, #D9541E);
  box-shadow: 0 0 14px 1px rgba(217, 84, 30, 0.55);
  opacity: 0;
}
@keyframes bsStgWipefront {
  0% { left: 0; opacity: 1; }
  34% { left: calc(100% - 3px); opacity: 1; }
  40%, 100% { left: calc(100% - 3px); opacity: 0; }
}
.builder-secpane-stg[data-play="wipe"] .builder-secpane-stg__wipefront { animation: bsStgWipefront 3.2s cubic-bezier(0.6, 0.1, 0.2, 1) infinite; }
/* settle: zoomed + tilted -> seated */
@keyframes bsStgSettle {
  0% { transform: scale(1.12) rotate(1.6deg); opacity: 0; }
  34% { transform: scale(1) rotate(0deg); opacity: 1; }
  86% { transform: scale(1) rotate(0deg); opacity: 1; }
  97%, 100% { transform: scale(1.12) rotate(1.6deg); opacity: 0; }
}
.builder-secpane-stg[data-play="settle"] .builder-secpane-stg__photo { animation: bsStgSettle 3.2s cubic-bezier(0.16, 1, 0.3, 1) infinite; }
/* hover: the card lifts under the cursor */
@keyframes bsStgLift {
  0%, 32% { transform: translateY(0); box-shadow: 0 14px 30px -14px rgba(31, 22, 17, 0.35), 0 0 0 1px rgba(31, 22, 17, 0.07); }
  52%, 78% { transform: translateY(-10px); box-shadow: 0 26px 44px -16px rgba(31, 22, 17, 0.45), 0 0 0 1px rgba(31, 22, 17, 0.07); }
  100% { transform: translateY(0); }
}
.builder-secpane-stg[data-play="hover"] .builder-secpane-stg__frame { animation: bsStgLift 3.2s ease-in-out infinite; }
/* photoslide: three photo cards glide in from the right, staggered */
.builder-secpane-stg__cardrow {
  display: flex;
  gap: 10px;
  width: 92%;
  align-items: stretch;
}
.builder-secpane-stg__photocard {
  position: relative;
  flex: 1;
  aspect-ratio: 3 / 4;
  border-radius: 9px;
  overflow: hidden;
  background: linear-gradient(160deg, #DDD9D2, #C8C3BA);
  box-shadow: 0 12px 24px -12px rgba(31, 22, 17, 0.35);
  opacity: 0;
}
@keyframes bsStgSlideIn {
  0% { transform: translateX(56px); opacity: 0; }
  26% { transform: translateX(0); opacity: 1; }
  86% { transform: translateX(0); opacity: 1; }
  97%, 100% { transform: translateX(56px); opacity: 0; }
}
.builder-secpane-stg[data-play="photoslide"] .builder-secpane-stg__photocard { animation: bsStgSlideIn 3.2s cubic-bezier(0.16, 1, 0.3, 1) infinite; }
.builder-secpane-stg[data-play="photoslide"] .builder-secpane-stg__photocard:nth-child(2) { animation-delay: 0.16s; }
.builder-secpane-stg[data-play="photoslide"] .builder-secpane-stg__photocard:nth-child(3) { animation-delay: 0.32s; }
/* textrise: heading lines rise out of masks over the dimmed section */
.builder-secpane-stg__words {
  position: absolute;
  left: 10%;
  right: 10%;
  bottom: 12%;
  z-index: 1;
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.builder-secpane-stg__word { display: block; height: 15px; overflow: hidden; }
.builder-secpane-stg__word > span {
  display: block;
  height: 13px;
  border-radius: 6px;
  background: #fff;
  transform: translateY(120%);
}
@keyframes bsStgWordRise {
  0% { transform: translateY(120%); }
  22% { transform: translateY(0); }
  86% { transform: translateY(0); }
  96%, 100% { transform: translateY(120%); }
}
.builder-secpane-stg[data-play="textrise"] .builder-secpane-stg__word > span { animation: bsStgWordRise 3.2s cubic-bezier(0.16, 1, 0.3, 1) infinite; }
.builder-secpane-stg[data-play="textrise"] .builder-secpane-stg__word:nth-child(2) > span { animation-delay: 0.13s; }
.builder-secpane-stg[data-play="textrise"] .builder-secpane-stg__word:nth-child(3) > span { animation-delay: 0.26s; }
.builder-secpane-stg__pillbtn {
  width: 92px;
  height: 24px;
  margin-top: 8px;
  border-radius: 999px;
  background: var(--orange, #D9541E);
  opacity: 0;
}
@keyframes bsStgFadeUp {
  0%, 14% { transform: translateY(10px); opacity: 0; }
  34% { transform: translateY(0); opacity: 1; }
  86% { transform: translateY(0); opacity: 1; }
  96%, 100% { transform: translateY(10px); opacity: 0; }
}
.builder-secpane-stg[data-play="textrise"] .builder-secpane-stg__pillbtn { animation: bsStgFadeUp 3.2s ease-in-out infinite; }
/* starshine / countup / stagger: a light review/stat panel scene */
.builder-secpane-stg__panel {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 10px;
  width: 84%;
  height: 88%;
  border-radius: 12px;
  background: linear-gradient(180deg, #FFFFFF, #F6F4F0);
  box-shadow: 0 14px 30px -14px rgba(31, 22, 17, 0.3), 0 0 0 1px rgba(31, 22, 17, 0.06);
}
.builder-secpane-stg__bigscore {
  display: block;
  font-size: 42px;
  font-weight: 800;
  color: var(--ink, #1F1D17);
  letter-spacing: -0.02em;
  line-height: 1;
}
.builder-secpane-stg__odo { display: block; height: 44px; overflow: hidden; text-align: center; }
.builder-secpane-stg__odo > span { display: block; }
.builder-secpane-stg__odo i { display: block; height: 44px; line-height: 44px; font-style: normal; }
@keyframes bsStgOdo {
  0%, 14% { transform: translateY(0); }
  26%, 40% { transform: translateY(-44px); }
  52%, 66% { transform: translateY(-88px); }
  78%, 100% { transform: translateY(-132px); }
}
.builder-secpane-stg[data-play="starshine"] .builder-secpane-stg__odo > span,
.builder-secpane-stg[data-play="countup"] .builder-secpane-stg__odo > span { animation: bsStgOdo 3.2s ease-in-out infinite; }
.builder-secpane-stg__stars { display: flex; gap: 5px; }
.builder-secpane-stg__star { display: inline-flex; width: 21px; height: 21px; color: #f6b21b; opacity: 0; }
.builder-secpane-stg__star svg { width: 100%; height: 100%; }
@keyframes bsStgStarPop {
  0% { transform: scale(0.2); opacity: 0; }
  14% { transform: scale(1.3); opacity: 1; }
  22% { transform: scale(1); opacity: 1; }
  88% { transform: scale(1); opacity: 1; }
  98%, 100% { transform: scale(0.2); opacity: 0; }
}
.builder-secpane-stg[data-play="starshine"] .builder-secpane-stg__star { animation: bsStgStarPop 3.2s cubic-bezier(0.34, 1.56, 0.64, 1) infinite; }
.builder-secpane-stg[data-play="starshine"] .builder-secpane-stg__star:nth-child(2) { animation-delay: 0.11s; }
.builder-secpane-stg[data-play="starshine"] .builder-secpane-stg__star:nth-child(3) { animation-delay: 0.22s; }
.builder-secpane-stg[data-play="starshine"] .builder-secpane-stg__star:nth-child(4) { animation-delay: 0.33s; }
.builder-secpane-stg[data-play="starshine"] .builder-secpane-stg__star:nth-child(5) { animation-delay: 0.44s; }
.builder-secpane-stg__quotes { display: flex; gap: 8px; width: 78%; }
.builder-secpane-stg__quote {
  flex: 1;
  height: 34px;
  border-radius: 7px;
  background: var(--cream-2, #F1EFEA);
  box-shadow: inset 0 0 0 1px rgba(31, 22, 17, 0.08);
  opacity: 0;
}
@keyframes bsStgQuoteRise {
  0%, 26% { transform: translateY(16px); opacity: 0; }
  44% { transform: translateY(0); opacity: 1; }
  88% { transform: translateY(0); opacity: 1; }
  98%, 100% { transform: translateY(16px); opacity: 0; }
}
.builder-secpane-stg[data-play="starshine"] .builder-secpane-stg__quote,
.builder-secpane-stg[data-play="stagger"] .builder-secpane-stg__quote { animation: bsStgQuoteRise 3.2s cubic-bezier(0.16, 1, 0.3, 1) infinite; }
.builder-secpane-stg[data-play="starshine"] .builder-secpane-stg__quote:nth-child(2),
.builder-secpane-stg[data-play="stagger"] .builder-secpane-stg__quote:nth-child(2) { animation-delay: 0.14s; }
.builder-secpane-stg[data-play="starshine"] .builder-secpane-stg__quote:nth-child(3),
.builder-secpane-stg[data-play="stagger"] .builder-secpane-stg__quote:nth-child(3) { animation-delay: 0.28s; }
.builder-secpane-stg[data-play="stagger"] .builder-secpane-stg__quote { height: 52px; }
.builder-secpane-stg__caption {
  width: 38%;
  height: 9px;
  border-radius: 5px;
  background: var(--ink, #1F1D17);
  opacity: 0.22;
}
.builder-secpane-stg__caption.is-head { opacity: 0.85; height: 11px; width: 46%; margin-bottom: 2px; }

/* abstract photo glyph for the kenburns mini-demo */
.builder-secpane-animdemo__photoabs {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--ink, #1F1D17);
  background: linear-gradient(160deg, var(--cream-2, #F4F2EE), var(--hairline-2, #D8D4CB));
}
.builder-secpane-animdemo[data-demo="kenburns"] .builder-secpane-animdemo__photoabs {
  animation: bsSecpaneDemoZoom 3s ease-in-out infinite alternate;
}

/* sheet-body content swap: every navigation rises in cleanly */
@keyframes bsSecpaneBodySwap {
  from { transform: translateY(16px); opacity: 0; }
  to { transform: translateY(0); opacity: 1; }
}
.builder-secpane-sheet__body.is-swapping > * { animation: bsSecpaneBodySwap 0.22s cubic-bezier(0.22, 1, 0.36, 1) both; }

@media (prefers-reduced-motion: reduce) {
  .builder-secpane-stg *,
  .builder-secpane-animdemo__photoabs,
  .builder-secpane-sheet__body.is-swapping > * { animation: none !important; }
  /* hidden-by-animation scene layers must still show when static */
  .builder-secpane-stg__photocard,
  .builder-secpane-stg__star,
  .builder-secpane-stg__quote,
  .builder-secpane-stg__pillbtn { opacity: 1 !important; }
  .builder-secpane-stg__word > span { transform: none !important; }
}

/* ── mobile/desktop view toggle (founder 2026-06-11) ───────────────────── */
.builder-secpane-vtoggle {
  display: inline-flex;
  gap: 2px;
  padding: 3px;
  border-radius: 999px;
  background: linear-gradient(180deg, #FFFFFF 0%, #F5F5F5 100%);
  border: 1px solid rgba(31, 22, 17, 0.10);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.9), 0 1px 3px rgba(31, 22, 17, 0.10);
}
.builder-secpane-vtoggle__btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 34px;
  height: 26px;
  border: 0;
  border-radius: 999px;
  background: transparent;
  color: var(--ink-faint, #8E867B);
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
.builder-secpane-vtoggle__btn.is-on {
  background: var(--ink, #1F1D17);
  color: #fff;
  box-shadow: 0 1px 3px rgba(31, 22, 17, 0.25);
}
.builder-secpane-viewrow {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin: 0 2px 12px;
}
.builder-secpane-viewrow__label {
  font-size: 0.8rem;
  font-weight: 650;
  color: var(--ink-soft, #6E675D);
}
/* P4: form-type picker on form-capable sections (Quote / Booking / Contact).
   Placement only; fields + on/off live on the Forms page. */
.builder-secpane-formrow { margin: 14px 2px 2px; padding-top: 12px; border-top: 1px solid var(--hairline, rgba(31, 22, 17, 0.08)); }
.builder-secpane-formrow__head { font-size: 0.8rem; font-weight: 650; color: var(--ink-soft, #6E675D); margin-bottom: 8px; }
.builder-secpane-formrow__segs { display: flex; gap: 6px; }
.builder-secpane-formrow__seg {
  flex: 1; padding: 9px 4px; font: inherit; font-size: 0.8rem; font-weight: 600;
  color: var(--ink-2, #2a1f17); background: var(--paper, #fff);
  border: 1px solid var(--hairline, rgba(31, 22, 17, 0.12)); border-radius: 9px; cursor: pointer;
}
.builder-secpane-formrow__seg.is-on {
  background: var(--ink, #1f1611); color: #fff; border-color: var(--ink, #1f1611);
}
.builder-secpane-formrow__seg:active { transform: scale(0.985); }
.builder-secpane-formrow__hint { font-size: 0.72rem; line-height: 1.45; color: var(--ink-faint, #a39585); margin: 8px 0 0; }

/* editor hero: device toggle lives in the "Preview as" row ABOVE the
   preview (2026-06-12 — the floating overlay covered the capture) */
/* desktop view: wide captures sit on the cream letterbox cleanly */
.builder-secpane-sheet.is-desktop-view .builder-secpane-ed__thumb img { max-height: 260px; }

/* (2026-06-12: the header+hero tie tile was removed — founder reversed the
   2026-06-11 merge; blocks render as individual tiles.) */

/* page-body entrance: plays ONLY when the tab changes (renderList gates it) */
@keyframes bsSecpanePageEnter {
  from { opacity: 0; transform: translateY(10px); }
  to { opacity: 1; transform: translateY(0); }
}
.builder-secpane-pagebody { display: contents; }
.builder-secpane-pagebody.is-entering > * { animation: bsSecpanePageEnter 0.26s cubic-bezier(0.22, 1, 0.36, 1) both; }
@media (prefers-reduced-motion: reduce) {
  .builder-secpane-pagebody.is-entering > * { animation: none !important; }
}

/* ── multipage tabs + page state (docs/MULTIPAGE_EDITOR_ARCHITECTURE.md) ── */
.builder-secpane-tabs {
  position: relative; /* anchors the sliding active pill */
  display: flex;
  flex-shrink: 0;
  gap: 6px;
  overflow-x: auto;
  margin: 2px 0 12px;
  padding: 2px;
  scrollbar-width: none;
}
.builder-secpane-tabs::-webkit-scrollbar { display: none; }
/* the active pill is ONE element that slides between tabs (FLIP-positioned
   by positionTabIndicator) — the tabs themselves stay light */
.builder-secpane-tabs__ind {
  position: absolute;
  top: 2px;
  left: 0;
  height: calc(100% - 4px);
  border-radius: 999px;
  background: var(--ink, #1F1D17);
  box-shadow: 0 1px 3px rgba(31, 22, 17, 0.25);
  opacity: 0;
  z-index: 0;
  transition: transform 0.32s cubic-bezier(0.32, 0.72, 0, 1), width 0.32s cubic-bezier(0.32, 0.72, 0, 1);
  pointer-events: none;
}
.builder-secpane-tab {
  position: relative;
  z-index: 1;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  flex: none;
  border: 1px solid rgba(31, 22, 17, 0.12);
  background: linear-gradient(180deg, #FFFFFF 0%, #F5F5F5 100%);
  border-radius: 999px;
  padding: 8px 14px;
  font: inherit;
  font-size: 0.85rem;
  font-weight: 650;
  color: var(--ink, #1F1D17);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.9), 0 1px 2px rgba(31, 22, 17, 0.06);
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: color 0.22s ease, transform 0.12s ease;
}
.builder-secpane-tab:active { transform: scale(0.97); }
.builder-secpane-tab.is-on {
  background: transparent;
  color: #fff;
  border-color: transparent;
  box-shadow: none;
}
.builder-secpane-tab.is-offpage { opacity: 0.55; }
.builder-secpane-tab__n { font-size: 0.66rem; font-weight: 700; opacity: 0.55; }
.builder-secpane-tab.is-on .builder-secpane-tab__n { opacity: 0.7; }
/* customised marker: this page has been taken over from Home */
.builder-secpane-tab__dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--orange, #D9541E);
  flex: none;
}
.builder-secpane-tab.is-on .builder-secpane-tab__dot { background: #fff; opacity: 0.9; }
/* the "+" tab: add your own page — a quiet dashed circle, never the active
   pill (the sliding indicator only targets .is-on, which "+" never is) */
.builder-secpane-tab.is-add {
  padding: 8px 11px;
  background: transparent;
  border-style: dashed;
  border-color: rgba(31, 22, 17, 0.22);
  box-shadow: none;
  color: rgba(31, 22, 17, 0.55);
}
.builder-secpane-tab.is-add svg { display: block; width: 14px; height: 14px; }
.builder-secpane-tab.is-add:hover { color: var(--ink, #1F1D17); border-color: rgba(31, 22, 17, 0.4); }
.builder-secpane-pagestate {
  display: flex;
  flex-shrink: 0;
  gap: 9px;
  align-items: center;
  font-size: 0.8rem;
  line-height: 1.35;
  color: var(--ink-soft, #55504A);
  background: linear-gradient(180deg, #FFFFFF, #F7F6F3);
  border: 1px solid rgba(31, 22, 17, 0.10);
  border-radius: 999px;
  padding: 7px 8px 7px 14px;
  margin: 0 0 12px;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.9), 0 1px 2px rgba(31, 22, 17, 0.05);
}
.builder-secpane-pagestate__dot {
  flex: none;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: #2E8B57;
  box-shadow: 0 0 0 3px rgba(46, 139, 87, 0.15);
}
.builder-secpane-pagestate.is-custom .builder-secpane-pagestate__dot {
  background: var(--orange, #D9541E);
  box-shadow: 0 0 0 3px rgba(217, 84, 30, 0.14);
}
.builder-secpane-pagestate__txt { flex: 1; min-width: 0; }
.builder-secpane-pagestate__act {
  flex: none;
  border: 1px solid rgba(31, 22, 17, 0.16);
  background: var(--paper, #fff);
  border-radius: 999px;
  padding: 6px 12px;
  font: inherit;
  font-size: 0.76rem;
  font-weight: 700;
  color: var(--ink, #1F1D17);
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
.builder-secpane-pagestate__act.is-arm {
  background: #B3261E;
  border-color: #B3261E;
  color: #fff;
}
.builder-secpane-pagestate__acts { display: flex; gap: 6px; flex: none; }
.builder-secpane-pagestate__act.is-quiet {
  border-color: rgba(31, 22, 17, 0.10);
  color: var(--ink-soft, #6E675D);
}
.builder-secpane__sharedpill {
  font-size: 0.58rem;
  font-weight: 700;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--ink-soft, #6E675D);
  background: var(--cream-2, #F1EFEA);
  border-radius: 999px;
  padding: 2px 7px;
  box-shadow: inset 0 0 0 1px rgba(31, 22, 17, 0.12);
}
.builder-secpane-pagehidden {
  flex-shrink: 0;
  text-align: center;
  padding: 36px 20px;
  border: 1px dashed rgba(31, 22, 17, 0.18);
  border-radius: 16px;
  background: var(--paper, #fff);
}
.builder-secpane-pagehidden__msg {
  margin: 0 0 16px;
  font-size: 0.9rem;
  line-height: 1.5;
  color: var(--ink-soft, #55504A);
}

/* ── Sections summary card + order label (founder design 2026-06-10,
   mock A structure WITHOUT the gradient bloom — plain paper card). ── */
.builder-secpane-summary {
  display: flex;
  gap: 14px;
  align-items: center;
  background: #FFFDFB;
  border: 1px solid rgba(31, 22, 17, 0.09);
  border-radius: 18px;
  box-shadow: 0 2px 10px -4px rgba(31, 22, 17, 0.10);
  padding: 14px;
  margin: 2px 0 18px;
}
.builder-secpane-summary__thumb {
  position: relative;
  flex: 0 0 82px;
  width: 82px;
  height: 102px;
  border-radius: 12px;
  overflow: hidden;
  background: var(--cream-2, #F1F1F1);
  box-shadow: inset 0 0 0 1px var(--hairline);
}
.builder-secpane-summary__thumb img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: top;
  display: block;
}
.builder-secpane-summary__body { flex: 1; min-width: 0; }
.builder-secpane-summary__chips { display: flex; gap: 6px; margin-bottom: 7px; }
.builder-secpane-summary__chip {
  display: inline-flex;
  padding: 3px 9px;
  border-radius: 999px;
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  background: var(--cream-2, #F1EFEA);
  color: var(--ink-soft, #8A8578);
}
.builder-secpane-summary__chip.is-live { background: #E5F4EA; color: #1F7A43; }
.builder-secpane-summary__name {
  display: block;
  font-size: 16.5px;
  font-weight: 750;
  letter-spacing: -0.015em;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.builder-secpane-summary__sub {
  display: block;
  margin-top: 2px;
  font-size: 12.5px;
  color: var(--ink-soft, #8A8578);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.builder-secpane-summary__btn {
  margin-top: 11px;
  border-radius: 999px;
  padding: 8px 18px;
  font: inherit;
  font-size: 12.5px;
  font-weight: 700;
  cursor: pointer;
  color: #fff;
  background: linear-gradient(180deg, #2A211B 0%, #1F1611 100%);
  border: 1px solid rgba(0, 0, 0, 0.55);
  box-shadow:
    0 1px 2px rgba(0, 0, 0, 0.18),
    0 4px 10px -2px rgba(0, 0, 0, 0.22),
    inset 0 1px 0 rgba(255, 255, 255, 0.10);
  transition: transform 0.12s;
}
.builder-secpane-summary__btn:active { transform: translateY(0.5px); }
.builder-secpane__orderlabel {
  font-size: 11px;
  font-weight: 750;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: #A39E91;
  margin: 0 2px 8px;
}

/* ── Thumb fit pass 2 + drag affordance (2026-06-10) ──────────────────── */
/* drawer cards: natural height (max 200px) so tall sections aren't shrunk
   into a fixed 4:3 box and strips aren't floating in empty squares */
.builder-secpane-opt__thumb { aspect-ratio: auto; min-height: 64px; max-height: 200px; display: flex; align-items: flex-start; }
.builder-secpane-opt__thumb img { height: 100%; width: 100%; object-fit: contain; object-position: center top; }
/* row chips: the top-crop fades out at the bottom so it reads intentional */
.builder-secpane__thumb img {
  -webkit-mask-image: linear-gradient(180deg, #000 70%, rgba(0,0,0,0.25) 100%);
  mask-image: linear-gradient(180deg, #000 70%, rgba(0,0,0,0.25) 100%);
}
/* real drag handle */
.builder-secpane__grip { touch-action: none; cursor: grab; padding: 12px 4px; margin: -12px 0; }
.builder-secpane__grip.is-off { opacity: 0.35; cursor: default; touch-action: auto; }
.builder-secpane__row.is-dragging {
  position: relative;
  z-index: 5;
  box-shadow: 0 10px 26px -8px rgba(31, 22, 17, 0.28), inset 0 1px 0 rgba(255, 255, 255, 0.9);
  transition: none;
}
/* toast undo action */
.builder-secpane-toast__act {
  margin-left: 12px;
  border: 0;
  background: transparent;
  color: #F3B27A;
  font: inherit;
  font-weight: 750;
  cursor: pointer;
  text-decoration: underline;
  text-underline-offset: 2px;
}

/* ── Logo sheet + strip chips + drill navigation (2026-06-10) ─────────── */
.builder-secpane-logo__preview {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 22px;
  margin: 0 0 12px;
  border-radius: 12px;
  background:
    linear-gradient(45deg, rgba(31,22,17,0.05) 25%, transparent 25%, transparent 75%, rgba(31,22,17,0.05) 75%),
    linear-gradient(45deg, rgba(31,22,17,0.05) 25%, transparent 25%, transparent 75%, rgba(31,22,17,0.05) 75%),
    var(--paper, #fff);
  background-size: 16px 16px;
  background-position: 0 0, 8px 8px;
  box-shadow: inset 0 0 0 1px var(--hairline);
}
.builder-secpane-logo__preview img { max-height: 64px; max-width: 70%; object-fit: contain; }

/* strip sections (header/footer/ticker — aspect > 3:1): show the FULL strip
   contained in the row chip instead of a zoomed mid-crop ("umbing") */
.builder-secpane__thumb.is-strip { display: flex; align-items: center; }
.builder-secpane__thumb.is-strip img {
  object-fit: contain;
  object-position: center;
  -webkit-mask-image: none;
  mask-image: none;
}

/* drill navigation: forward slides in from the right, back from the left */
@keyframes bsSecpaneNavFwd {
  from { transform: translateX(26px); opacity: 0; }
  to { transform: translateX(0); opacity: 1; }
}
@keyframes bsSecpaneNavBack {
  from { transform: translateX(-26px); opacity: 0; }
  to { transform: translateX(0); opacity: 1; }
}
.builder-secpane-sheet__body.is-swapping.is-nav-fwd > * { animation: bsSecpaneNavFwd 0.28s cubic-bezier(0.22, 1, 0.36, 1) both; }
.builder-secpane-sheet__body.is-swapping.is-nav-back > * { animation: bsSecpaneNavBack 0.28s cubic-bezier(0.22, 1, 0.36, 1) both; }
@media (prefers-reduced-motion: reduce) {
  .builder-secpane-sheet__body.is-swapping > * { animation: none !important; }
}

/* ── Site styles drawer (2026-06-11) ──────────────────────────────────── */
.builder-secpane-styles {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  appearance: none;
  margin: 0 0 14px;
  padding: 12px 14px;
  border: 1px solid rgba(31, 22, 17, 0.10);
  border-radius: 14px;
  background: linear-gradient(180deg, #FFFFFF 0%, #F7F6F4 100%);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.9), 0 1px 2px rgba(31, 22, 17, 0.05);
  font: inherit;
  color: var(--ink, #1F1611);
  cursor: pointer;
  text-align: left;
}
.builder-secpane-styles:active { transform: scale(0.99); }
.builder-secpane-styles__icon { display: flex; color: var(--ink-soft, #8A7866); flex: none; }
.builder-secpane-styles__label { font-weight: 700; font-size: 0.95rem; }
.builder-secpane-styles__hint { font-size: 0.8rem; color: var(--ink-soft, #8A7866); margin-left: auto; }
.builder-secpane-styles__chev { display: flex; color: var(--ink-soft, #8A7866); flex: none; }

.builder-styles-group { margin: 0 0 22px; }
.builder-styles-label { font-size: 0.72rem; font-weight: 800; letter-spacing: 0.12em; text-transform: uppercase; color: var(--ink-soft, #8A7866); margin: 0 0 10px; }
.builder-styles-swatches { display: flex; flex-wrap: wrap; gap: 10px; margin-bottom: 12px; }
.builder-styles-swatch {
  appearance: none;
  width: 40px;
  height: 40px;
  border-radius: 50%;
  border: 2px solid rgba(255, 255, 255, 0.9);
  box-shadow: 0 0 0 1px rgba(31, 22, 17, 0.14), 0 1px 3px rgba(31, 22, 17, 0.16);
  cursor: pointer;
}
.builder-styles-swatch.is-on { box-shadow: 0 0 0 2.5px var(--ink, #1F1611), 0 1px 3px rgba(31, 22, 17, 0.2); }
.builder-styles-swatch:active { transform: scale(0.94); }
.builder-styles-hexrow { display: flex; gap: 8px; }
.builder-styles-hex {
  flex: 1;
  font: inherit;
  font-size: 0.92rem;
  padding: 10px 13px;
  border: 1px solid rgba(31, 22, 17, 0.14);
  border-radius: 10px;
  background: #fff;
  color: var(--ink, #1F1611);
}
.builder-styles-hex.is-bad { border-color: #C0392B; animation: bk-styles-shake 0.3s; }
@keyframes bk-styles-shake { 25% { transform: translateX(-3px); } 75% { transform: translateX(3px); } }
.builder-styles-hexgo {
  appearance: none;
  font: inherit;
  font-size: 0.88rem;
  font-weight: 700;
  padding: 0 18px;
  border: 1px solid rgba(31, 22, 17, 0.14);
  border-radius: 10px;
  background: linear-gradient(180deg, #FFFFFF 0%, #F5F4F1 100%);
  color: var(--ink, #1F1611);
  cursor: pointer;
}
.builder-styles-fontrow {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  appearance: none;
  font: inherit;
  text-align: left;
  padding: 13px 14px;
  margin-bottom: 8px;
  border: 1px solid rgba(31, 22, 17, 0.10);
  border-radius: 12px;
  background: #fff;
  color: var(--ink, #1F1611);
  cursor: pointer;
}
.builder-styles-fontrow.is-on { border-color: var(--ink, #1F1611); box-shadow: 0 0 0 1px var(--ink, #1F1611); }
.builder-styles-fontrow__name { font-weight: 700; font-size: 0.95rem; }
.builder-styles-fontrow__sub { font-size: 0.8rem; color: var(--ink-soft, #8A7866); margin-left: auto; }
.builder-styles-tick { display: flex; color: var(--ink, #1F1611); flex: none; }
.builder-styles-segs { display: flex; gap: 8px; }
.builder-styles-seg {
  flex: 1;
  appearance: none;
  font: inherit;
  font-size: 0.9rem;
  font-weight: 600;
  padding: 11px 0;
  border: 1px solid rgba(31, 22, 17, 0.12);
  border-radius: 11px;
  background: #fff;
  color: var(--ink, #1F1611);
  cursor: pointer;
}
.builder-styles-seg.is-on { background: var(--ink, #1F1611); color: #FAFAFA; border-color: var(--ink, #1F1611); }

/* ============================================================ */
/* Local pages (Local SEO capture UI — /dashboard-v2/local-pages)
   Design language matched to the Usage + Schedule&area pages
   (public/mockups/usage-page.html + public/prototypes/schedule-area.html):
   flat sections + hairline dividers, transparent outlined inputs, beige
   chips. The 3D-gradient is reserved for the toggle, the primary (black)
   button and the gate-meter fill — never on the page ground. */
/* ============================================================ */
.lp-loading { display: flex; align-items: center; justify-content: center; min-height: calc(100dvh - 140px); }
.lp-head-intro { font-size: 0.82rem; color: var(--ink-mute, #6B5A4C); line-height: 1.5; margin: 6px 0 0; }
.lp-head-intro b { color: var(--ink, #1F1611); font-weight: 600; }
.lp-sec { margin-top: 36px; }
.lp-sec-title { display: flex; align-items: baseline; gap: 10px; font-size: 1.05rem; font-weight: 700; letter-spacing: -0.01em; color: var(--ink, #1F1611); margin: 0 0 2px; }
.lp-sec-title .lp-tag { font-size: 0.85rem; font-weight: 500; color: var(--ink-mute, #6B5A4C); }

/* "your site isn't on the new engine yet" notice */
.lp-note { font-size: 0.8rem; color: #7a5a22; background: #FFF6EA; border: 1px solid #F0E2CC; border-radius: 12px; padding: 11px 14px; margin: 14px 0 0; line-height: 1.5; }
.lp-note a { color: #5e441a; font-weight: 700; }

/* serve toggle — flat hairline row */
.lp-master { display: flex; align-items: center; justify-content: space-between; gap: 18px; padding: 16px 0; margin-top: 8px; border-top: 1px solid var(--hairline, rgba(31,22,17,0.08)); }
.lp-master-text { display: flex; flex-direction: column; gap: 3px; }
.lp-master-text strong { font-size: 0.9rem; font-weight: 600; color: var(--ink, #1F1611); }
.lp-master-text span { font-size: 0.8rem; color: var(--ink-mute, #6B5A4C); line-height: 1.45; }

/* 3D toggle (the .set-switch recipe) */
.lp-toggle { flex: 0 0 auto; width: 42px; height: 24px; border-radius: 999px; border: 0; padding: 0; position: relative; cursor: pointer;
  background: linear-gradient(180deg, #e4ddd2, #d8d0c4); box-shadow: inset 0 1px 2px rgba(31,22,17,0.18); transition: background .18s ease; }
.lp-toggle span { position: absolute; top: 3px; left: 3px; width: 18px; height: 18px; border-radius: 50%;
  background: linear-gradient(180deg, #fff, #f1f1f1); box-shadow: 0 1px 2px rgba(31,22,17,0.3), inset 0 1px 0 rgba(255,255,255,0.9); transition: transform .18s ease; }
.lp-toggle.is-on { background: linear-gradient(180deg, #5aa2ff, #2563eb); box-shadow: inset 0 1px 0 rgba(255,255,255,0.45), 0 1px 2px rgba(37,99,235,0.4); }
.lp-toggle.is-on span { transform: translateX(18px); }

/* add a suburb */
.lp-add { display: flex; gap: 9px; }
.lp-add .lp-input { flex: 1; }
.lp-suggest { display: flex; flex-wrap: wrap; gap: 8px; margin: 12px 0 0; }
.lp-suggest-chip { display: inline-flex; align-items: center; gap: 5px; background: #F5F1EB; border: 1px solid rgba(31,22,17,0.08); color: var(--ink, #1F1611); border-radius: 999px; padding: 6px 12px; font-size: 0.8125rem; font-weight: 500; cursor: pointer; }
.lp-suggest-chip:active { transform: scale(.97); }

/* suburb pills — raised 3D-gradient cards (neutral white, not warm cream).
   Gradient uses FIXED-PX stops (not 0%->100%): the white->grey 3D sheen
   lives in the top ~58px (the head), so it stays crisp whether the pill is
   closed or expanded — and a fixed gradient doesn't re-paint as the card
   grows during the reveal (a key smoothness win). No box-shadow transition
   (animating box-shadow is an expensive per-frame repaint). */
.lp-card { background: linear-gradient(180deg, #FFFFFF 0px, #F4F4F4 58px);
  border: 1px solid rgba(0,0,0,0.08); border-bottom-color: rgba(0,0,0,0.13); border-radius: 14px;
  margin-bottom: 10px; overflow: hidden;
  box-shadow: 0 1px 2px rgba(0,0,0,0.06), 0 6px 16px -12px rgba(0,0,0,0.16), inset 0 1px 0 rgba(255,255,255,0.95); }
.lp-card-head { display: flex; align-items: center; gap: 10px; width: 100%; padding: 10px 12px 10px 16px; }
.lp-card-title { display: flex; align-items: center; gap: 12px; flex: 1; min-width: 0; background: none; border: 0; padding: 5px 0; cursor: pointer; text-align: left; }
.lp-card-actions { display: flex; align-items: center; gap: 8px; flex: 0 0 auto; }
.lp-mini { display: inline-flex; align-items: center; justify-content: center; height: 30px; padding: 0 13px; font-size: 0.78rem; font-weight: 600; color: var(--ink, #1F1611); background: #fff; border: 1px solid rgba(31,22,17,0.14); border-radius: 8px; cursor: pointer; text-decoration: none; font-family: inherit; }
.lp-mini:active { transform: scale(0.97); }
.lp-chatcta-btn { display: flex; width: 100%; justify-content: center; margin: 12px 0 2px; text-decoration: none; }
.lp-card-name { font-size: 0.92rem; font-weight: 600; color: var(--ink, #1F1611); margin-right: auto; }


/* status pills */
.lp-chip { display: inline-flex; align-items: center; gap: 6px; font-size: 0.7rem; font-weight: 600; border-radius: 6px; padding: 4px 9px; white-space: nowrap; }
.lp-chip--live { background: #E7F3EB; color: #1F7A4D; }
.lp-chip--live::before { content: ''; width: 5px; height: 5px; border-radius: 50%; background: #1F7A4D; }
.lp-chip--ready { background: #FFF3E0; color: #8A5A18; }
.lp-chip--needs { background: #F1EFEA; color: #6B5A4C; }
.lp-chip--hidden { background: #EFE9E1; color: #8A8077; }

/* per-suburb editor — GPU-friendly reveal: CSS grid-rows 0fr->1fr for the
   height (no JS height animation = no layout thrash), and a composited
   opacity+transform fade on the editor itself. Driven purely by the
   .is-open class toggled in the wire JS. */
.lp-editor-wrap { display: grid; grid-template-rows: 0fr; transition: grid-template-rows .36s cubic-bezier(.4,0,.2,1); will-change: grid-template-rows; }
.lp-card.is-open .lp-editor-wrap { grid-template-rows: 1fr; }
.lp-card.is-open .lp-card-head { border-bottom: 1px solid rgba(0,0,0,0.07); }
/* the editor is its own paint layer (contain) so revealing it doesn't repaint
   the rest of the card; the visible motion is a GPU opacity+transform fade. */
.lp-editor { overflow: hidden; min-height: 0; padding: 14px 16px 18px; background: #F4F4F4;
  contain: paint; opacity: 0; transform: translateY(-4px) translateZ(0);
  transition: opacity .3s ease, transform .34s cubic-bezier(.4,0,.2,1); will-change: opacity, transform; }
.lp-card.is-open .lp-editor { opacity: 1; transform: translateY(0) translateZ(0); }
.lp-fieldwrap { display: block; margin-top: 14px; }
.lp-fieldlabel { display: block; font-size: 0.9375rem; font-weight: 600; color: var(--ink, #1F1611); margin: 18px 0 6px; }
.lp-fieldlabel em { font-style: normal; font-weight: 400; color: #A39585; }
.lp-fieldwrap .lp-fieldlabel { margin-top: 0; margin-bottom: 6px; font-size: 0.8125rem; }

/* transparent outlined input (schedule-area .input) */
.lp-input { display: block; width: 100%; box-sizing: border-box; background: transparent; border: 1px solid rgba(31,22,17,0.08); border-radius: 10px;
  padding: 10px 14px; font-family: inherit; font-size: 0.8125rem; color: var(--ink, #1F1611); resize: vertical; }
.lp-input:focus { outline: 0; border-color: rgba(31,22,17,0.22); box-shadow: 0 0 0 3px rgba(31,22,17,0.04); }

/* gate meter — recessed track + blue 3D fill (the usage meter) */
.lp-meter { margin: 12px 0 4px; }
.lp-meter-bar { height: 8px; border-radius: 999px; background: var(--cream-2, #F1F1F1); box-shadow: inset 0 1px 2px rgba(31,22,17,0.16), inset 0 0 0 1px rgba(31,22,17,0.04); overflow: hidden; }
.lp-meter-bar span { display: block; height: 100%; border-radius: 999px; background: linear-gradient(180deg, #5aa2ff, #2563eb); box-shadow: inset 0 1px 0 rgba(255,255,255,0.45), 0 1px 2px rgba(37,99,235,0.4); transition: width .25s ease; }
.lp-meter-label { font-size: 0.82rem; color: var(--ink-mute, #6B5A4C); margin-top: 10px; font-weight: 600; }
.lp-meter-missing { display: none; }

/* AI assist */
.lp-assist__note { display: block; margin-top: 8px; font-size: 0.8rem; color: var(--ink-mute, #6B5A4C); line-height: 1.5; }

/* faq rows */
.lp-faq-row { position: relative; display: flex; flex-direction: column; gap: 6px; margin-bottom: 10px; padding-right: 30px; }
.lp-faq-del { position: absolute; top: 4px; right: 0; width: 24px; height: 24px; border: 1px solid rgba(31,22,17,0.1); background: transparent; color: #8A8077; border-radius: 50%; font-size: 15px; line-height: 1; cursor: pointer; }
.lp-add-faq { border: 0; background: none; color: var(--ink-mute, #6B5A4C); font-size: 0.82rem; font-weight: 600; cursor: pointer; padding: 6px 0; }

/* photos */
.lp-photos { display: flex; flex-wrap: wrap; gap: 8px; }
.lp-photo { width: 62px; height: 46px; border-radius: 9px; overflow: hidden; padding: 0; border: 2px solid transparent; cursor: pointer; background: #F5F1EB; }
.lp-photo img { width: 100%; height: 100%; object-fit: cover; display: block; }
.lp-photo.is-on { border-color: #2563eb; }
.lp-photo--add { background: transparent; border: 1px dashed rgba(31,22,17,0.12); color: #A39585; display: flex; align-items: center; justify-content: center; }
.lp-photo--add span { font-size: 20px; }
.lp-nophotos { font-size: 0.78rem; color: #A39585; margin: 10px 0 0; }

/* actions */
.lp-actions { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 18px; align-items: center; }
.lp-btn { display: inline-flex; align-items: center; justify-content: center; height: 38px; padding: 0 16px; font-size: 0.82rem; font-weight: 600; color: var(--ink-mute, #6B5A4C); background: transparent; border: 1px solid rgba(31,22,17,0.1); border-radius: 9px; cursor: pointer; font-family: inherit; }
.lp-btn:active { transform: scale(.985); }
.lp-btn--save { color: #FAFAFA; background: linear-gradient(180deg, #2A211B, #1F1611); border: 1px solid #1F1611; border-bottom-color: #000; box-shadow: inset 0 1px 0 rgba(255,255,255,0.18), 0 1px 2px rgba(31,22,17,0.22), 0 2px 6px -2px rgba(31,22,17,0.26); }
.lp-btn--danger { color: #A33B2E; border-color: rgba(163,59,46,0.28); }
.lp-livelink { display: block; margin-top: 14px; font-size: 0.72rem; color: #1F7A4D; font-family: 'Geist Mono', ui-monospace, monospace; word-break: break-all; text-decoration: none; }

/* teaching checklist (empty state) */
.lp-check-intro { font-size: 0.82rem; color: var(--ink-mute, #6B5A4C); line-height: 1.5; margin: 8px 0 6px; }
.lp-check-intro b { color: var(--ink, #1F1611); font-weight: 600; }
.lp-check-item { display: flex; align-items: flex-start; gap: 13px; padding: 14px 0; border-top: 1px solid var(--hairline, rgba(31,22,17,0.08)); }
.lp-check-ring { flex: 0 0 auto; width: 18px; height: 18px; border-radius: 50%; border: 1.5px solid #D2C9BC; margin-top: 1px; }
.lp-check-item strong { display: block; font-size: 0.875rem; font-weight: 500; margin-bottom: 2px; color: var(--ink, #1F1611); }
.lp-check-item span { font-size: 0.8rem; color: var(--ink-mute, #6B5A4C); line-height: 1.45; }
.lp-auto { margin-top: 18px; font-size: 0.8rem; color: var(--ink-mute, #6B5A4C); line-height: 1.55; }
.lp-auto b { color: var(--ink, #1F1611); font-weight: 600; }

/* ── §8 Google-traffic health strip + kill-switch ─────────────────────── */
.lp-health { margin: 4px 0 18px; padding: 14px 15px; border-radius: 14px;
  background: var(--paper-2, #F4F1EB); border: 1px solid var(--hairline, rgba(31,22,17,0.08)); }
.lp-health-head { font-size: 0.72rem; font-weight: 700; letter-spacing: 0.05em; text-transform: uppercase;
  color: var(--ink-mute, #6B5A4C); margin-bottom: 8px; }
.lp-health-stat, .lp-health-line { font-size: 0.9rem; line-height: 1.5; color: var(--ink, #1F1611); }
.lp-health-stat b { font-weight: 700; }
.lp-health-pct { color: var(--ink-mute, #6B5A4C); font-weight: 500; }
.lp-health-ok { margin-top: 7px; font-size: 0.82rem; line-height: 1.5; color: #2E7D55; }
.lp-health-warn { margin-top: 9px; padding: 10px 12px; border-radius: 10px;
  background: rgba(193,86,38,0.08); border: 1px solid rgba(193,86,38,0.22);
  font-size: 0.82rem; line-height: 1.5; color: var(--ink, #1F1611); }
.lp-health-warn b { color: #B0431E; font-weight: 700; }
.lp-health-prune { margin-top: 10px; display: flex; flex-wrap: wrap; gap: 6px; align-items: center;
  font-size: 0.8rem; color: var(--ink-mute, #6B5A4C); }
.lp-prune-chip { font: inherit; font-size: 0.78rem; padding: 4px 10px; border-radius: 999px;
  background: #fff; border: 1px solid var(--hairline, rgba(31,22,17,0.14)); color: var(--ink, #1F1611);
  cursor: pointer; transition: transform .08s ease, border-color .15s ease; }
.lp-prune-chip:active { transform: scale(0.96); }
.lp-prune-more { font-size: 0.78rem; }

/* ── GBP / entity-signal checklist (self-assessed) ────────────────────── */
.lp-ent { margin-top: 22px; }
.lp-ent-item { display: flex; align-items: flex-start; gap: 12px; width: 100%; text-align: left;
  padding: 13px 4px; border: 0; border-top: 1px solid var(--hairline, rgba(31,22,17,0.08));
  background: transparent; cursor: pointer; font: inherit; transition: transform .08s ease; }
.lp-ent-item:active { transform: scale(0.992); }
.lp-ent-tick { flex: 0 0 auto; width: 22px; height: 22px; border-radius: 50%; margin-top: 1px;
  border: 1.5px solid #D2C9BC; background: #fff; color: transparent;
  display: flex; align-items: center; justify-content: center; transition: background .15s ease, border-color .15s ease, color .15s ease; }
.lp-ent-item.is-on .lp-ent-tick { background: #2E7D55; border-color: #2E7D55; color: #fff; }
.lp-ent-text strong { display: block; font-size: 0.875rem; font-weight: 600; margin-bottom: 2px; color: var(--ink, #1F1611); }
.lp-ent-text span { font-size: 0.8rem; color: var(--ink-mute, #6B5A4C); line-height: 1.45; }
.lp-ent-item.is-on .lp-ent-text strong { color: var(--ink-mute, #6B5A4C); text-decoration: line-through; text-decoration-color: rgba(107,90,76,0.4); }

/* ── Suburb editor as a GPU bottom-sheet ──────────────────────────────
   Tapping a pill slides its editor up as a full bottom-sheet. The motion
   is a pure GPU transform on the panel (translateY) + a scrim fade — no
   inline height/layout reveal, so it's buttery on mobile. Appended to
   <body> (true viewport-fixed). */
.lp-sheet { position: fixed; inset: 0; z-index: 5000; }
.lp-sheet-scrim { position: absolute; inset: 0; background: rgba(20,16,12,0.42); opacity: 0; transition: opacity .45s ease; }
.lp-sheet.is-open .lp-sheet-scrim { opacity: 1; }
.lp-sheet-panel { position: absolute; left: 0; right: 0; bottom: 0; max-height: 82vh;
  display: flex; flex-direction: column; background: #F4F4F4; border-radius: 20px 20px 0 0;
  box-shadow: 0 -8px 40px -10px rgba(0,0,0,0.35);
  transform: translateY(100%); transition: transform .52s cubic-bezier(.22,1,.36,1); will-change: transform;
  padding-bottom: env(safe-area-inset-bottom, 0px); }
.lp-sheet.is-open .lp-sheet-panel { transform: translateY(0); }
.lp-sheet-grab { width: 38px; height: 4px; border-radius: 999px; background: rgba(0,0,0,0.18); margin: 9px auto 2px; flex: 0 0 auto; }
.lp-sheet .lp-card { margin: 0; border: 0; border-radius: 0; background: transparent; box-shadow: none;
  display: flex; flex-direction: column; min-height: 0; overflow: hidden; }
.lp-sheet-head { display: flex; align-items: center; gap: 12px; padding: 6px 16px 12px; flex: 0 0 auto; }
.lp-sheet-head .lp-card-name { font-size: 1.05rem; font-weight: 700; letter-spacing: -0.01em; margin-right: auto; }
.lp-sheet-x { flex: 0 0 auto; width: 32px; height: 32px; border-radius: 50%; border: 1px solid rgba(0,0,0,0.1);
  background: #fff; color: #6B5A4C; display: flex; align-items: center; justify-content: center; cursor: pointer; padding: 0; }
.lp-sheet-body { overflow-y: auto; -webkit-overflow-scrolling: touch; flex: 1 1 auto; min-height: 0; }
.lp-sheet .lp-editor { opacity: 1; transform: none; contain: none; background: transparent; padding: 0 16px 18px; }

/* Respect reduced-motion: no transitions. */
@media (prefers-reduced-motion: reduce) {
  .lp-sheet-scrim, .lp-sheet-panel { transition: none; }
  .lp-editor { opacity: 1; transform: none; }
}

/* ── LIVE section previews (real renders of the owner's draft, 2026-06-12) ── */
.builder-secpane-live {
  position: relative;
  display: block;
  width: 100%;
  height: 180px; /* pre-load reservation; sizeLiveFrame sets the real height */
  overflow: hidden;
  border-radius: 12px;
  background: #F4F0EA;
  transition: height .25s ease;
}
.builder-secpane-live__ph {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover; object-position: top;
  filter: saturate(.85);
  opacity: .55;
}
.builder-secpane-live iframe {
  position: absolute; top: 0; left: 0;
  border: 0;
  height: 1400px;            /* generous canvas; the box crops via its height */
  transform-origin: 0 0;
  background: #fff;
  opacity: 0;
  pointer-events: none;      /* previews are for looking, not tapping */
  transition: opacity .22s ease;
}
.builder-secpane-live.is-loaded iframe { opacity: 1; }
.builder-secpane-live.is-loaded .builder-secpane-live__ph { opacity: 0; }
/* sticky: the drawer auto-scrolls to the Current option on open and the
   list is long — the live panel must stay in view while options scroll
   under it (it's the whole point of the panel) */
.builder-secpane-swaplive {
  position: sticky;
  top: -1px;
  z-index: 3;
  margin: 2px 2px 14px;
  padding: 8px 8px 9px;
  background: var(--cream, #FAF8F4);
  border-radius: 14px;
  box-shadow: 0 6px 16px -8px rgba(31, 22, 17, 0.28);
}
/* airtight: cards scrolling under the panel peeked through the body's
   top-padding strip above it — cover it in the sheet's own paper */
.builder-secpane-swaplive::before {
  content: "";
  position: absolute;
  left: -14px;
  right: -14px;
  bottom: 100%;
  height: 16px;
  background: var(--paper, #fff);
}
.builder-secpane-swaplive__cap {
  font-size: 11.5px; font-weight: 600; color: #8A8077;
  margin-top: 7px; text-align: center;
}
.builder-secpane-stg__replay {
  display: inline-flex; align-items: center; gap: 6px;
  margin-top: 8px;
  border: 1px solid #E2DAD0; background: #fff; color: #6B6258;
  border-radius: 999px; padding: 6px 13px;
  font-size: 12px; font-weight: 650; cursor: pointer;
}
.builder-secpane-stg__replay:active { transform: scale(.97); }
.builder-secpane-animstage [data-secpane-stage-scene] { display: block; }

/* Site styles drawer: the Custom preset state note (not a button) */
.builder-styles-customnote {
  display: flex; flex-direction: column; gap: 2px;
  padding: 11px 14px;
  border: 1px dashed #D8CFC3; border-radius: 12px;
  margin-top: 8px;
}

/* Local pages: the AI quick-start block */
.lp-assist { background: #FAF7F2; border: 1px solid #EFE9E1; border-radius: 12px; padding: 2px 12px 12px; margin-top: 14px; }
.lp-assist__go { margin-top: 8px; }
.lp-assist__note { display: block; font-size: 12.5px; color: #6B6258; margin-top: 8px; }
.lp-summary { font-size: 13px; font-weight: 600; color: #6B6258; margin: 0 2px 10px; }
.lp-photo--add { display: inline-flex; align-items: center; justify-content: center; cursor: pointer; border: 2px dashed #D8CFC3; background: #FAF7F2; color: #B0A698; font-size: 22px; font-weight: 600; }

/* ── Local-pages clarity pass (founder 2026-06-24) ──────────────────────── */
/* Ready-but-switched-off banner: the finished pages are hidden until the
   master toggle is on, so make that loud with a one-tap turn-on. */
.lp-banner { display: flex; align-items: center; gap: 14px; margin: 14px 0 4px; padding: 13px 15px;
  border-radius: 12px; background: rgba(37,99,235,0.07); border: 1px solid rgba(37,99,235,0.22); }
.lp-banner-text { display: flex; flex-direction: column; gap: 2px; flex: 1 1 auto; min-width: 0; }
.lp-banner-text strong { font-size: 0.9rem; font-weight: 700; color: var(--ink, #1F1611); }
.lp-banner-text span { font-size: 0.8rem; color: var(--ink-mute, #6B5A4C); line-height: 1.4; }
.lp-banner .lp-btn { flex: 0 0 auto; }
.lp-head-intro a { color: #2563eb; text-decoration: none; font-weight: 600; }
.lp-head-intro a:hover { text-decoration: underline; }

/* "Connected to" status — which published site the suburb pages attach to. */
.lp-conn { display: flex; align-items: flex-start; gap: 11px; margin: 12px 0 2px; padding: 12px 14px;
  border-radius: 12px; border: 1px solid var(--hairline, rgba(31,22,17,0.10)); background: var(--cream-2, #FAF6F0); }
.lp-conn-dot { flex: 0 0 auto; width: 8px; height: 8px; border-radius: 50%; margin-top: 6px; background: #9aa0a6; }
.lp-conn-text { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.lp-conn-text strong { font-size: 0.86rem; font-weight: 600; color: var(--ink, #1F1611); }
.lp-conn-text span { font-size: 0.8rem; color: var(--ink-mute, #6B5A4C); line-height: 1.45; }
.lp-conn-text a { font-weight: 600; text-decoration: none; word-break: break-word; }
.lp-conn-text a:hover { text-decoration: underline; }
.lp-conn.is-ok { background: rgba(22,124,77,0.06); border-color: rgba(22,124,77,0.22); }
.lp-conn.is-ok .lp-conn-dot { background: #1a8a4f; box-shadow: 0 0 0 3px rgba(26,138,79,0.15); }
.lp-conn.is-ok .lp-conn-text a { color: #15703f; }
.lp-conn.is-warn { background: #FFF6EA; border-color: #F0E2CC; }
.lp-conn.is-warn .lp-conn-dot { background: #c98a2a; }
.lp-conn.is-warn .lp-conn-text a { color: #5e441a; }

/* AI assist hero: the primary way to build a page, lifted above the form. */
.lp-assist--hero { margin: 12px 0 6px; padding: 17px 18px 18px; border-radius: 13px;
  background: linear-gradient(180deg, #FFFFFF, #F7F9FF); border: 1px solid rgba(37,99,235,0.2);
  box-shadow: 0 1px 2px rgba(31,22,17,0.05); }
.lp-assist-h { font-size: 0.98rem; font-weight: 700; letter-spacing: -0.01em; color: var(--ink, #1F1611); }
.lp-assist-p { font-size: 0.82rem; color: var(--ink-mute, #6B5A4C); line-height: 1.5; margin: 4px 0 12px; }
.lp-assist--hero .lp-input { width: 100%; }
/* Roomier typing box — the placeholder is long, 3 rows felt cramped. */
.lp-facts-input { min-height: 132px; padding: 13px 14px; line-height: 1.5; resize: vertical; }
.lp-assist--hero .lp-assist__go { margin-top: 12px; }

/* Manual fields: a quiet disclosure beneath the assist, not the headline. */
.lp-manual { margin: 6px 0 2px; }
.lp-manual-sum { -webkit-appearance: none; appearance: none; background: none; border: 0; width: 100%; text-align: left;
  cursor: pointer; display: inline-flex; align-items: center; gap: 6px;
  font-size: 0.84rem; font-weight: 600; color: var(--ink-mute, #6B5A4C); padding: 8px 0; }
.lp-manual-sum::before { content: '+'; font-weight: 700; color: #B0A698; font-size: 1rem; line-height: 1; transition: transform .28s cubic-bezier(.4,0,.2,1); }
.lp-manual.is-open > .lp-manual-sum::before { content: '\2212'; }
/* Smooth slide-down: grid-template-rows 0fr -> 1fr animates the wrapper height
   (works on iOS Safari, unlike animating a native <details>). */
.lp-manual-grid { display: grid; grid-template-rows: 0fr; transition: grid-template-rows .32s cubic-bezier(.4,0,.2,1); }
.lp-manual.is-open > .lp-manual-grid { grid-template-rows: 1fr; }
.lp-manual-body { overflow: hidden; min-height: 0; }
.lp-manual.is-open > .lp-manual-grid > .lp-manual-body { padding-top: 4px; }
@media (prefers-reduced-motion: reduce) { .lp-manual-grid { transition: none; } }

/* Google checklist: collapsed by default so off-platform homework does not
   crowd the page-building task. */
.lp-ent--collapse { margin-top: 36px; border-top: 1px solid var(--hairline, rgba(31,22,17,0.08)); padding-top: 4px; }
.lp-ent-sum { list-style: none; cursor: pointer; display: flex; align-items: center; gap: 10px; padding: 14px 0 4px; }
.lp-ent-sum::-webkit-details-marker { display: none; }
.lp-ent-sum .lp-sec-title { margin: 0; }
.lp-ent-sum .lp-tag { margin-right: auto; }
.lp-ent-chev { color: #C2B7A8; transition: transform .3s cubic-bezier(.22,1,.36,1); flex: 0 0 auto; }
.lp-ent--collapse[open] .lp-ent-chev { transform: rotate(180deg); }

/* ── Drafts, Claude-style (founder 2026-06-12: "exactly like Claude's") ──
   Filter pills with counts, day-group captions, hairline card rows with a
   state ring (dotted = needs input, arc spinner = generating, check =
   ready, ! = failed) and the pending chat question inline. */
.drafts-filters { display: flex; gap: 7px; overflow-x: auto; scrollbar-width: none; margin: 4px 0 10px; padding: 2px; }
.drafts-filters::-webkit-scrollbar { display: none; }
.drafts-pill { flex-shrink: 0; font: inherit; font-size: 0.8rem; font-weight: 560; color: var(--ink-2, #2a1f17);
  /* exact recipe of .drafts-newchat-row: neutral gradient + heavier bottom
     edge (the warm cream version read YELLOW on device) */
  background: linear-gradient(180deg, #FFFFFF 0%, #F8F8F8 100%);
  border: 1px solid rgba(31, 22, 17, 0.13); border-bottom-color: rgba(31, 22, 17, 0.19); border-radius: 999px;
  padding: 8px 14px; cursor: pointer;
  box-shadow: 0 1px 2px rgba(31, 22, 17, 0.05), inset 0 1px 0 rgba(255, 255, 255, 0.9); }
.drafts-pill:active { transform: translateY(0.5px); }
.drafts-pill.is-on { color: #fff; font-weight: 640; border-color: transparent;
  background: transparent; box-shadow: none; }
/* the black pill is ONE element that slides between options */
.drafts-filters { position: relative; }
.drafts-pill { position: relative; z-index: 1; }
.drafts-pillind { position: absolute; z-index: 0; border-radius: 999px; opacity: 0;
  background: linear-gradient(180deg, #3a2f23, #1f1611);
  box-shadow: 0 5px 12px -5px rgba(31, 22, 17, 0.5), inset 0 1px 0 rgba(255, 255, 255, 0.16);
  transition: left 0.28s cubic-bezier(0.22, 1, 0.36, 1), width 0.28s cubic-bezier(0.22, 1, 0.36, 1),
    top 0.28s cubic-bezier(0.22, 1, 0.36, 1), height 0.28s cubic-bezier(0.22, 1, 0.36, 1), opacity 0.15s ease; }
@media (prefers-reduced-motion: reduce) { .drafts-pillind { transition: none; } }
.drafts-pill__n { color: var(--ink-faint, #a39585); font-weight: 500; margin-left: 2px; }
.drafts-pill.is-on .drafts-pill__n { color: rgba(255, 255, 255, 0.6); }
.drafts-day { font-size: 0.78rem; font-weight: 560; color: var(--ink-faint, #a39585); margin: 16px 4px 8px; }
.drafts-row--claude { display: flex; align-items: flex-start; gap: 12px; min-width: 0;
  background: linear-gradient(180deg, #FFFFFF 0%, #F8F8F8 100%);
  border: 1px solid rgba(31, 22, 17, 0.13); border-bottom-color: rgba(31, 22, 17, 0.19);
  border-radius: 14px; padding: 13px 14px; margin-bottom: 8px;
  box-shadow: 0 1px 2px rgba(31, 22, 17, 0.05), inset 0 1px 0 rgba(255, 255, 255, 0.9);
  text-decoration: none; }
.drafts-row--claude:active { transform: scale(0.995); }
.drafts-row__state { flex-shrink: 0; margin-top: 1px; }
.drafts-ring { position: relative; display: flex; align-items: center; justify-content: center; width: 26px; height: 26px;
  border-radius: 50%; color: var(--ink-mute, #6b5a4c); font-size: 0.8rem; font-weight: 700; }
.drafts-ring--input { border: 1.6px dashed rgba(31, 22, 17, 0.3); }
.drafts-ring--input .drafts-ring__pip { position: absolute; top: -2px; right: -2px; width: 9px; height: 9px;
  border-radius: 50%; background: #2a6fe1; border: 2px solid var(--paper, #fff); }
.drafts-ring--gen { border: 2px solid rgba(31, 22, 17, 0.12); border-top-color: var(--ink-2, #2a1f17);
  animation: bsDraftSpin 0.9s linear infinite; }
@keyframes bsDraftSpin { to { transform: rotate(360deg); } }
.drafts-ring--ready { border: 1.6px solid rgba(31, 22, 17, 0.16); }
.drafts-ring--ready svg { width: 13px; height: 13px; }
.drafts-ring--failed { border: 1.6px solid rgba(192, 57, 43, 0.4); color: #c0392b; }
.drafts-row--claude .drafts-row__meta { flex: 1; min-width: 0; }
.drafts-row--claude .drafts-row__title { font-size: 0.92rem; font-weight: 600; color: var(--ink, #1f1611);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.drafts-row__sub--claude { display: flex; align-items: center; gap: 5px; font-size: 0.76rem; color: var(--ink-faint, #a39585); margin-top: 3px; }
.drafts-row__subic { width: 12px; height: 12px; flex-shrink: 0; }
.drafts-row__ask { margin-top: 9px; font-size: 0.8rem; color: var(--ink-mute, #6b5a4c); background: #f4f4f3;
  border-radius: 9px; padding: 8px 11px; line-height: 1.4; }
.drafts-row__time { flex-shrink: 0; font-size: 0.76rem; color: var(--ink-faint, #a39585); margin-top: 3px; }
.drafts-row--claude .drafts-row__menu { margin-top: -3px; }

/* I0/I1 (docs/INBOX_REDESIGN_PLAN.md): the inbox stat sentence — prose over
   tiles, on the same card surface as the rows (the New-chat recipe) so it
   reads as a finished stat strip rather than floating text. */
.leads-pulse-card { display: flex; align-items: center; gap: 12px; padding: 13px 14px; margin: 0 0 16px;
  background: #F1F1F1;
  border: 1px solid rgba(31, 22, 17, 0.08);
  border-radius: 14px; box-shadow: none; }
.leads-pulse { flex: 1; min-width: 0; font-size: 0.92rem; line-height: 1.5; color: var(--ink-mute, #6b5a4c); margin: 0; }
.leads-pulse b { color: var(--ink, #1f1611); font-weight: 650; }
/* 7-day activity sparkline (Option B, founder-picked 2026-06-13): one bar
   per day, oldest left, today right; days with enquiries go dark. */
.leads-spark-wrap { flex-shrink: 0; }
.leads-spark { display: flex; align-items: flex-end; gap: 3px; height: 34px; padding-bottom: 1px; justify-content: center; }
.leads-spark__bar { width: 7px; border-radius: 3px 3px 2px 2px; background: rgba(31, 22, 17, 0.10); }
.leads-spark__bar.is-hot { background: linear-gradient(180deg, #3a2f23, #1f1611); }
.leads-spark__lbl { font-size: 0.62rem; color: var(--ink-faint, #a39585); text-align: center; margin-top: 3px; }

/* ── Vision grounding: the inline "Looking at your site" screenshot bubble
   (founder 2026-06-25). Ephemeral AI-side row showing what the AI is judging. */
.builder-shot-row { display: flex; flex-direction: column; align-items: flex-start; gap: 6px; margin: 2px 0 8px; animation: builder-shot-in 0.34s ease both; }
.builder-shot-cap { font-size: 0.72rem; font-weight: 600; letter-spacing: 0.01em; color: var(--ink-faint, #a39585); display: inline-flex; align-items: center; gap: 6px; }
.builder-shot-cap::before { content: ""; width: 7px; height: 7px; border-radius: 50%; background: currentColor; opacity: 0.6; }
@keyframes builder-shot-in { from { opacity: 0; transform: translateY(6px) scale(0.985); } to { opacity: 1; transform: none; } }

/* ── Fresh AI reply reveal (founder 2026-06-25): a gentle rise-in so a reply
   feels like it lands, not pops. Fresh rows only (restore adds no .is-fresh). ── */
.builder-msg-row.is-ai.is-fresh { animation: builder-msg-reveal 0.42s cubic-bezier(0.22, 1, 0.36, 1) both; }
@keyframes builder-msg-reveal { from { opacity: 0; transform: translateY(7px); } to { opacity: 1; transform: none; } }
@media (prefers-reduced-motion: reduce) { .builder-msg-row.is-ai.is-fresh { animation: none; } }

/* Site-health mini score RING in the project pill sheet (right of the row). */
.builder-project-sheet__health { margin-left: auto; display: inline-flex; align-items: center; flex: none; }
.builder-project-sheet__health svg { display: block; }
/* iOS Safari samples the viewport bottom for its toolbar tint - a sheet's dark
   backdrop turns the bottom bar grey. Paint a WHITE strip across the very bottom
   (position:fixed so it escapes the card's overflow clip) whenever a sheet is
   open, so the sampled region stays white (founder 2026-06-25; VERIFY ON A REAL
   IPHONE - Playwright-on-Linux cannot see the Safari toolbar). */
.builder-project-sheet.is-open::after,
.bs-health-overlay.is-open::after { content: ""; position: fixed; left: 0; right: 0; bottom: 0; height: max(env(safe-area-inset-bottom, 0px), 8px); background: #ffffff; z-index: 2; pointer-events: none; }

/* ── Site Health sheet (founder 2026-06-25): deterministic quality score +
   one-tap fixes. Slide-up sheet, premium card. ── */
.bs-health-overlay { position: fixed; inset: 0; z-index: 1200; display: flex; align-items: flex-end; justify-content: center; background: rgba(16, 12, 9, 0); pointer-events: none; transition: background 0.24s ease; }
.bs-health-overlay.is-open { background: rgba(16, 12, 9, 0.46); pointer-events: auto; }
/* inline vision shot is a small THUMBNAIL (founder: not a tall portrait) - crops
   to the hero; tap to open the full screenshot in a lightbox. */
.builder-shot-img { width: 124px; height: 124px; object-fit: cover; object-position: top center; border-radius: 12px; border: 1px solid rgba(31, 22, 17, 0.12); box-shadow: 0 6px 18px -9px rgba(10, 16, 26, 0.34); background: #fff; display: block; cursor: zoom-in; }
.builder-shot-lightbox { position: fixed; inset: 0; z-index: 1300; background: rgba(8, 6, 4, 0.84); display: flex; align-items: center; justify-content: center; padding: 22px; opacity: 0; transition: opacity 0.2s ease; cursor: zoom-out; }
.builder-shot-lightbox.is-open { opacity: 1; }
.builder-shot-lightbox img { max-width: 94vw; max-height: 92vh; border-radius: 14px; box-shadow: 0 24px 70px -20px rgba(0, 0, 0, 0.6); }

.bs-health-card { position: relative; width: 100%; max-width: 460px; background: #ffffff; color: #1f1611; --bs-health-accent: #1f6feb; border-radius: 22px 22px 0 0; box-shadow: 0 -18px 50px -16px rgba(10, 16, 26, 0.4); padding: 26px 22px max(30px, env(safe-area-inset-bottom)); transform: translateY(110%); transition: transform 0.3s cubic-bezier(0.22, 1, 0.36, 1); max-height: 90vh; overflow-y: auto; }
.bs-health-overlay.is-open .bs-health-card { transform: none; }
@media (min-width: 720px) { .bs-health-overlay { align-items: center; } .bs-health-card { border-radius: 22px; } }
.bs-health-close { position: absolute; top: 14px; right: 14px; width: 34px; height: 34px; border-radius: 50%; border: 0; background: rgba(31, 22, 17, 0.06); color: var(--ink, #1f1611); font-size: 1.2rem; line-height: 1; cursor: pointer; }
.bs-health-close:hover { background: rgba(31, 22, 17, 0.12); }
.bs-health-head { display: flex; align-items: center; gap: 18px; margin-bottom: 20px; }
.bs-health-score { position: relative; width: 96px; height: 96px; flex: none; }
.bs-health-ring { width: 96px; height: 96px; display: block; }
.bs-health-ring__bg { fill: none; stroke: rgba(31, 22, 17, 0.1); stroke-width: 10; }
/* stroke comes from the inline attribute (score colour) - do NOT set it here, a
   CSS stroke property overrides the SVG presentation attribute. */
.bs-health-ring__fg { fill: none; stroke-width: 10; transition: stroke-dasharray 0.6s ease; }
.bs-health-score__num { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; font-size: 1.9rem; font-weight: 800; font-family: var(--font-display, inherit); }
.bs-health-grade { font-size: 1.35rem; font-weight: 800; font-family: var(--font-display, inherit); line-height: 1.1; }
.bs-health-grade.is-good { color: #1f9d57; }
.bs-health-grade.is-ok { color: #2f7d45; }
.bs-health-grade.is-mid { color: #c98a1e; }
.bs-health-grade.is-low { color: #c0492f; }
.bs-health-sub { font-size: 0.78rem; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase; color: var(--bs-health-accent, #1f6feb); margin-top: 3px; }
.bs-health-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 2px; }
.bs-health-row { display: flex; align-items: center; gap: 12px; padding: 11px 8px; border-radius: 12px; }
.bs-health-row + .bs-health-row { border-top: 1px solid rgba(31, 22, 17, 0.06); }
.bs-health-row__icon { width: 22px; height: 22px; flex: none; border-radius: 50%; display: flex; align-items: center; justify-content: center; font-size: 0.8rem; font-weight: 800; color: #fff; }
.bs-health-row.is-pass .bs-health-row__icon { background: #1f9d57; }
.bs-health-row.is-warn .bs-health-row__icon { background: #c98a1e; }
.bs-health-row.is-fail .bs-health-row__icon { background: #c0492f; }
.bs-health-row__body { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.bs-health-row__label { font-weight: 700; font-size: 0.95rem; }
.bs-health-row__detail { font-size: 0.8rem; color: var(--ink-faint, #8a7d6f); line-height: 1.35; }
.bs-health-fix { flex: none; border: 0; background: var(--bs-health-accent, #1f1611); color: #fff; font-weight: 700; font-size: 0.82rem; padding: 8px 14px; border-radius: 999px; cursor: pointer; transition: transform 0.12s ease, opacity 0.15s ease; }
.bs-health-fix:hover { opacity: 0.9; } .bs-health-fix:active { transform: scale(0.96); }
.bs-health-foot { margin-top: 16px; text-align: center; font-size: 0.82rem; color: var(--ink-faint, #a39585); }
.bs-health-card.is-loading, .bs-health-card.is-empty { min-height: 180px; display: flex; align-items: center; justify-content: center; }
.bs-health-empty { text-align: center; color: var(--ink-faint, #8a7d6f); font-size: 0.95rem; padding: 0 18px; }
.bs-health-spinner { width: 30px; height: 30px; border-radius: 50%; border: 3px solid rgba(31, 22, 17, 0.14); border-top-color: var(--ink, #1f1611); animation: bs-health-spin 0.7s linear infinite; }
@keyframes bs-health-spin { to { transform: rotate(360deg); } }
