/* =========================================================
   Slab Brain — Visits app styles
   Built on sb-design-system.css (load that FIRST).
   All colour/spacing/type comes from design tokens so the
   whole app re-themes per tenant via the Hub `theme` block.
   ========================================================= */

/* ── Backward-compat aliases ───────────────────────────────
   Older inline styles / JS reference these legacy var names.
   Map them onto the design system so nothing breaks. */
:root {
  --bg:        var(--color-bg);
  --card:      var(--color-surface-raised);
  --text:      var(--color-text-primary);
  --muted:     var(--color-text-secondary);
  --border:    var(--color-border);
  --border-2:  var(--color-border-strong);
  --accent:    var(--color-accent);
  --accent-2:  var(--color-accent);
  --accent-soft: var(--color-accent-subtle);
  --shadow:    var(--shadow-lg);
  --shadow-sm: var(--shadow-sm);
  --r-lg: var(--radius-lg);
  --r-md: var(--radius-md);
  --r-sm: var(--radius-sm);
}

/* ── Page shell ──────────────────────────────────────────── */
body.page {
  min-height: 100vh;
  min-height: 100dvh;
  background: var(--color-bg);
  color: var(--color-text-primary);
}

/* =========================================================
   SIMPLE PAGES — editorial layout helpers (.v-*)
   Used by start / checkin / waiver / repeat / resume /
   repeat_confirm / done / add. These pages use the design
   system .sb-* component classes plus these layout helpers.
   ========================================================= */

.v-shell {
  min-height: 100vh;
  min-height: 100dvh;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: flex-start;
  padding: var(--space-8) var(--space-4) var(--space-16);
}

.v-shell--center { justify-content: center; }

.v-col {
  width: 100%;
  max-width: 480px;
  display: flex;
  flex-direction: column;
  gap: var(--space-5);
}

.v-col--wide { max-width: 640px; }

/* Brand header (logo + company name) */
.v-brand {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: var(--space-3);
  margin-bottom: var(--space-2);
}

.v-brand__logo {
  height: 56px;
  width: auto;
  max-width: 220px;
  object-fit: contain;
}

.v-brand__name {
  font-family: var(--font-display);
  font-size: var(--text-d-sm);
  font-weight: 400;
  color: var(--color-text-primary);
  line-height: 1.2;
}

.v-brand__sub {
  font-size: var(--text-ui-xs);
  font-weight: 500;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--color-text-tertiary);
}

/* Editorial headings on simple pages */
.v-kicker {
  font-size: var(--text-ui-xs);
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--color-accent);
}

.v-title {
  font-family: var(--font-display);
  font-size: var(--text-d-md);
  font-weight: 400;
  line-height: 1.15;
  color: var(--color-text-primary);
}

.v-lead {
  font-size: var(--text-ui-lg);
  color: var(--color-text-secondary);
  line-height: 1.55;
}

/* Start page choice cards */
.v-choice {
  display: flex;
  align-items: center;
  gap: var(--space-4);
  width: 100%;
  padding: var(--space-5) var(--space-6);
  background: var(--color-surface-raised);
  border: var(--border-standard);
  border-radius: var(--radius-lg);
  text-decoration: none;
  color: var(--color-text-primary);
  transition: border-color var(--t-base), transform var(--t-base), box-shadow var(--t-base);
}

.v-choice:hover {
  border-color: var(--color-accent);
  transform: translateY(-2px);
  box-shadow: var(--shadow-md);
}

.v-choice--primary {
  background: var(--color-accent);
  color: var(--color-accent-text);
  border-color: transparent;
}

.v-choice--primary:hover { opacity: 0.92; border-color: transparent; }

.v-choice__body { display: flex; flex-direction: column; gap: 2px; }
.v-choice__title { font-size: var(--text-ui-lg); font-weight: 600; }
.v-choice__sub { font-size: var(--text-ui-md); opacity: 0.75; }
.v-choice__arrow { margin-left: auto; font-size: 20px; opacity: 0.5; }

/* Footer note / tips */
.v-note {
  text-align: center;
  font-size: var(--text-ui-sm);
  color: var(--color-text-tertiary);
}

.v-pills {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  justify-content: center;
}

/* Success mark (replaces ✅ emoji) */
.v-check {
  width: 64px;
  height: 64px;
  margin: 0 auto;
  border-radius: var(--radius-full);
  background: var(--color-success-subtle);
  color: var(--color-success);
  display: flex;
  align-items: center;
  justify-content: center;
}
.v-check svg { width: 32px; height: 32px; }

/* Waiver document */
.v-waiver-text {
  white-space: pre-wrap;
  font-size: var(--text-ui-md);
  line-height: 1.65;
  color: var(--color-text-secondary);
  background: var(--color-surface);
  border: var(--border-hairline);
  border-radius: var(--radius-md);
  padding: var(--space-5);
  max-height: 60vh;
  overflow-y: auto;
}

/* Match / pick cards (repeat_confirm, resume) */
.v-match {
  display: block;
  width: 100%;
  text-align: left;
  padding: var(--space-4) var(--space-5);
  background: var(--color-surface-raised);
  border: var(--border-standard);
  border-radius: var(--radius-lg);
  cursor: pointer;
  transition: border-color var(--t-base), box-shadow var(--t-base);
}
.v-match:hover { border-color: var(--color-accent); box-shadow: var(--shadow-sm); }
.v-match__name { font-size: var(--text-ui-lg); font-weight: 600; color: var(--color-text-primary); }
.v-match__meta { font-size: var(--text-ui-sm); color: var(--color-text-secondary); margin-top: 4px; }
.v-match__date { font-size: var(--text-ui-sm); color: var(--color-text-tertiary); margin-top: 3px; }

/* =========================================================
   LEGACY CLASS VOCABULARY — used by visit.html + admin.html
   and their JavaScript. Re-expressed via design tokens.
   Class names are preserved so JS keeps working.
   ========================================================= */

/* Containers */
.sheet {
  width: 100%;
  max-width: 980px;
  margin: 0 auto;
  padding: var(--space-6) var(--space-4) 120px;
}

.card {
  background: var(--color-surface);
  border: var(--border-hairline);
  border-radius: var(--radius-lg);
  padding: var(--space-6);
  box-shadow: var(--shadow-sm);
}
.card.center { text-align: center; }

.sheetHeader {
  display: flex;
  justify-content: space-between;
  gap: var(--space-4);
  padding-bottom: var(--space-5);
  padding-right: 56px; /* keeps .brand clear of the fixed .tutFab (44px + gutter) */
  border-bottom: var(--border-hairline);
}

/* Typography */
.title {
  font-family: var(--font-display);
  font-size: var(--text-d-sm);
  font-weight: 400;
  line-height: 1.2;
  color: var(--color-text-primary);
}

.brand {
  font-family: var(--font-display);
  font-size: var(--text-d-sm);
  font-weight: 400;
  color: var(--color-text-primary);
}

.kicker {
  display: inline-flex;
  align-items: center;
  font-size: var(--text-ui-xs);
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--color-accent);
}

.small {
  font-size: var(--text-ui-md);
  color: var(--color-text-secondary);
  line-height: 1.5;
}

.meta {
  margin-top: var(--space-3);
  display: flex;
  flex-direction: column;
  gap: 2px;
  font-size: var(--text-ui-md);
  color: var(--color-text-secondary);
}
.meta b { color: var(--color-text-primary); font-weight: 500; }

.metaRow {
  margin-top: var(--space-3);
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2);
}

.miniMuted { font-size: var(--text-ui-sm); color: var(--color-text-tertiary); }
.miniMuted b { color: var(--color-text-secondary); font-weight: 500; }

.miniLink {
  display: inline-block;
  background: none;
  border: none;
  padding: 0;
  margin-top: 4px;
  margin-right: var(--space-3);
  font-size: var(--text-ui-sm);
  font-weight: 500;
  color: var(--color-accent);
  cursor: pointer;
  text-decoration: none;
}
.miniLink:hover { text-decoration: underline; }

/* Mood Board / Visualize This — pill buttons, not plain text links, so they
   read as tappable actions rather than fine print (esp. on mobile). */
.aiActionBtn {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  margin: 6px 8px 0 0;
  padding: 6px 12px;
  border-radius: var(--radius-full);
  border: 1px solid var(--color-accent);
  background: var(--color-accent-subtle);
  color: var(--color-accent);
  font-size: var(--text-ui-sm);
  font-weight: 600;
  line-height: 1.2;
  white-space: nowrap;
  cursor: pointer;
  transition: background .15s, color .15s, transform .1s;
}
.aiActionBtn:hover { background: var(--color-accent); color: var(--color-accent-text); }
.aiActionBtn:active { transform: scale(0.97); }

@media (max-width: 760px) {
  .aiActionBtn {
    padding: 10px 16px;
    margin: 8px 8px 0 0;
    font-size: var(--text-ui-md);
    font-weight: 700;
    min-height: 42px;
  }
}

.inlineLink {
  color: var(--color-accent);
  font-weight: 500;
  text-decoration: none;
}
.inlineLink:hover { text-decoration: underline; }

/* Buttons */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  height: 44px;
  padding: 0 var(--space-5);
  border-radius: var(--radius-md);
  background: var(--color-surface-raised);
  color: var(--color-text-primary);
  border: var(--border-standard);
  font-family: var(--font-ui);
  font-size: var(--text-ui-md);
  font-weight: 500;
  line-height: 1;
  text-decoration: none;
  cursor: pointer;
  transition: opacity var(--t-base), transform var(--t-fast), background var(--t-base), border-color var(--t-base);
}
.btn:hover { background: var(--color-surface); }
.btn:active { transform: translateY(1px); }
.btn:disabled, .btn[aria-disabled="true"] { opacity: 0.4; cursor: not-allowed; pointer-events: none; }

.btn.primary {
  background: var(--color-accent);
  color: var(--color-accent-text);
  border-color: transparent;
}
.btn.primary:hover { opacity: 0.9; background: var(--color-accent); }

.btn.big { height: 52px; padding: 0 var(--space-6); font-size: var(--text-ui-lg); }

.btn-scan {
  background: var(--color-text-primary);
  color: var(--color-bg);
  border-color: transparent;
}
.btn-scan:hover { opacity: 0.9; background: var(--color-text-primary); }

.btn-secondary { background: transparent; }
.btnPrint { }

/* Text-style button used in tables (Edit / Remove) */
.link {
  background: none;
  border: none;
  padding: 0;
  font-family: var(--font-ui);
  font-size: var(--text-ui-md);
  font-weight: 500;
  color: var(--color-accent);
  cursor: pointer;
  text-decoration: none;
}
.link:hover { text-decoration: underline; }
.link:disabled, .link[aria-disabled="true"] { opacity: 0.4; cursor: not-allowed; text-decoration: none; }

/* Forms */
.inp, .input {
  width: 100%;
  height: 44px;
  padding: 0 var(--space-4);
  background: var(--color-surface-raised);
  border: var(--border-standard);
  border-radius: var(--radius-md);
  font-family: var(--font-ui);
  font-size: var(--text-ui-lg);
  color: var(--color-text-primary);
  transition: border-color var(--t-base);
}
.inp:focus, .input:focus { outline: none; border: var(--border-focus); }
.inp::placeholder, .input::placeholder { color: var(--color-text-tertiary); }

textarea.inp, textarea.input { height: auto; min-height: 90px; padding: var(--space-3) var(--space-4); resize: vertical; line-height: 1.5; }
select.inp, select.input { cursor: pointer; }

.lbl {
  display: block;
  margin-top: var(--space-3);
  margin-bottom: var(--space-1);
  font-size: var(--text-ui-sm);
  font-weight: 500;
  color: var(--color-text-secondary);
}

.chk {
  display: flex;
  align-items: flex-start;
  gap: var(--space-2);
  font-size: var(--text-ui-md);
  color: var(--color-text-secondary);
  cursor: pointer;
}
.chk input { margin-top: 2px; width: 18px; height: 18px; accent-color: var(--color-accent); flex-shrink: 0; }

.grid2 {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-3);
  margin-top: var(--space-4);
}
@media (max-width: 480px) { .grid2 { grid-template-columns: 1fr; } }

.btnRow { display: flex; flex-wrap: wrap; gap: var(--space-3); margin-top: var(--space-4); }

.form { display: block; }

.waiverBox {
  padding: var(--space-4);
  background: var(--color-surface);
  border: var(--border-hairline);
  border-radius: var(--radius-md);
}
.waiverText {
  white-space: pre-wrap;
  font-family: var(--font-ui);
  font-size: var(--text-ui-md);
  line-height: 1.65;
  color: var(--color-text-secondary);
  margin-top: var(--space-3);
}

/* Alerts */
.alert {
  display: flex;
  align-items: flex-start;
  gap: var(--space-2);
  padding: var(--space-3) var(--space-4);
  background: var(--color-danger-subtle);
  border: 1px solid var(--color-danger);
  border-radius: var(--radius-md);
  font-size: var(--text-ui-md);
  color: var(--color-danger);
}

.divider { border: none; border-top: var(--border-hairline); margin: var(--space-4) 0; height: 0; }

/* Pills / badges */
.pill, .statPill {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  padding: 4px var(--space-3);
  border-radius: var(--radius-full);
  background: var(--color-surface);
  border: var(--border-hairline);
  font-size: var(--text-ui-sm);
  font-weight: 500;
  color: var(--color-text-secondary);
  white-space: nowrap;
}
.pill b, .statPill b { color: var(--color-text-primary); font-weight: 600; }

/* Room chip (where a selected material is going) — on stone rows/cards. */
.roomChip {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  padding: 3px var(--space-3);
  border-radius: var(--radius-full);
  background: var(--color-accent-subtle);
  border: var(--border-hairline);
  font-size: var(--text-ui-sm);
  font-weight: 600;
  color: var(--color-text-primary);
  white-space: nowrap;
  align-self: flex-start;
}

.statNote { font-size: var(--text-ui-sm); color: var(--color-text-tertiary); flex: 1 1 200px; }

.badge {
  display: inline-flex;
  align-items: center;
  padding: 3px var(--space-2);
  border-radius: var(--radius-sm);
  background: var(--color-accent-subtle);
  color: var(--color-accent);
  font-size: var(--text-ui-xs);
  font-weight: 600;
  letter-spacing: 0.02em;
  white-space: nowrap;
}

.pillSpecial, .specialPill {
  display: inline-flex;
  align-items: center;
  padding: 3px var(--space-2);
  border-radius: var(--radius-sm);
  background: var(--color-warning-subtle);
  color: var(--color-warning);
  font-size: var(--text-ui-xs);
  font-weight: 600;
  letter-spacing: 0.04em;
}
.pillMuted {
  display: inline-flex;
  align-items: center;
  padding: 3px var(--space-2);
  border-radius: var(--radius-sm);
  background: var(--color-surface);
  color: var(--color-text-tertiary);
  font-size: var(--text-ui-xs);
  font-weight: 500;
}

/* Selections table (desktop) */
.tableWrap {
  margin-top: var(--space-5);
  border: var(--border-hairline);
  border-radius: var(--radius-lg);
  /* overflow-x:auto (not overflow:hidden) scrolls a wide table instead of clipping.
     overflow-y:hidden preserves border-radius corners. The visits table has 10 columns
     and Count + Email are rightmost (first to cut off). Phones (≤760px) show a card
     list instead. Measured (headless Chromium, real stylesheet): .sheet{max-width:980px}
     minus card/accBody padding caps this wrap at ~864px at ANY viewport (checked to
     1920) — it does NOT grow on a bigger monitor. Intrinsic width varies with row
     content and realistic rows measured ~1072px, so this scrolls on desktop too. That
     is the fix working, not a regression: the same content previously CLIPPED. Do NOT add min-width: .tableWrap
     is used 8× in admin.html (5× inside 560px modals); unscoped min-width forces those
     tables to scroll unnecessarily at every viewport (regression). Re-measure if content
     grows; do not assume desktop has room. */
  overflow-x: auto;
  overflow-y: hidden;
  -webkit-overflow-scrolling: touch;
  background: var(--color-surface-raised);
}

.table { width: 100%; border-collapse: collapse; font-size: var(--text-ui-md); }
.table thead th {
  font-size: var(--text-ui-xs);
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--color-text-tertiary);
  text-align: left;
  padding: var(--space-3) var(--space-4);
  border-bottom: var(--border-standard);
  background: var(--color-surface);
}
.table tbody td {
  padding: var(--space-4);
  border-bottom: var(--border-hairline);
  vertical-align: top;
  color: var(--color-text-primary);
}
.table tbody tr:last-child td { border-bottom: none; }
.table .tdRight { text-align: right; white-space: nowrap; }
.table .empty {
  text-align: center;
  color: var(--color-text-tertiary);
  padding: var(--space-10) var(--space-4);
  font-size: var(--text-ui-md);
}

.nameCell { display: flex; gap: var(--space-3); align-items: flex-start; }
.nameStack { min-width: 0; }
.nameText { font-size: var(--text-ui-lg); font-weight: 600; color: var(--color-text-primary); }
.notesCell { display: flex; flex-direction: column; gap: var(--space-1); }
.notesText { color: var(--color-text-secondary); white-space: pre-wrap; }
.lotCell { white-space: nowrap; }
.lotPill {
  display: inline-flex;
  align-items: center;
  padding: 4px var(--space-3);
  border-radius: var(--radius-full);
  background: var(--color-surface);
  border: var(--border-hairline);
  font-size: var(--text-ui-sm);
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  color: var(--color-text-primary);
}

/* Thumbnails */
.lotThumb {
  width: 56px;
  height: 56px;
  border-radius: var(--radius-md);
  object-fit: cover;
  background: var(--color-surface);
  flex-shrink: 0;
  cursor: zoom-in;
}
.lotThumb--card { width: 64px; height: 64px; }
.lotThumb--empty { background: var(--color-surface); border: var(--border-hairline); cursor: default; }

/* Mobile stone cards */
.mobileList { display: none; margin-top: var(--space-5); flex-direction: column; gap: var(--space-3); }
.stoneCard {
  background: var(--color-surface-raised);
  border: var(--border-hairline);
  border-radius: var(--radius-lg);
  padding: var(--space-4);
  box-shadow: var(--shadow-sm);
}
.stoneCard.isSpecial { border-color: var(--color-warning); }
.stoneTop { display: flex; align-items: flex-start; justify-content: space-between; gap: var(--space-3); }
.stoneLeft { display: flex; gap: var(--space-3); align-items: flex-start; min-width: 0; }
.stoneTitleWrap { min-width: 0; }
.stoneTitle { font-size: var(--text-ui-lg); font-weight: 600; color: var(--color-text-primary); }
.stoneSub { font-size: var(--text-ui-sm); color: var(--color-text-tertiary); }
.stoneNotes { margin-top: var(--space-3); font-size: var(--text-ui-md); color: var(--color-text-secondary); white-space: pre-wrap; }
.stoneActions { margin-top: var(--space-3); display: flex; justify-content: flex-end; gap: var(--space-4); align-items: center; }

.table tr.isSpecial td { background: var(--color-warning-subtle); }

/* Just-added highlight */
.justAdded { animation: vJustAdded 1.2s ease; }
@keyframes vJustAdded {
  0% { background: var(--color-accent-subtle); }
  100% { background: transparent; }
}
.fadeOut { transition: background 1s ease; background: transparent !important; }

/* Toolbar / actions */
.actions { margin-top: var(--space-5); }
.toolbar { display: flex; flex-wrap: wrap; gap: var(--space-2); align-items: center; }
.scanWell.toolbarScan { margin-left: auto; }

/* Sticky bottom bar */
.stickyBar {
  position: fixed;
  left: 0; right: 0; bottom: 0;
  z-index: var(--z-overlay);
  background: color-mix(in srgb, var(--color-bg) 92%, transparent);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  border-top: var(--border-hairline);
  padding: var(--space-3) var(--space-4);
  padding-bottom: calc(var(--space-3) + env(safe-area-inset-bottom));
}
.stickyInner {
  max-width: 980px;
  margin: 0 auto;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
}
.stickyMeta { font-size: var(--text-ui-md); color: var(--color-text-primary); }
.stickyMeta b { font-weight: 600; }
.stickyHint { font-size: var(--text-ui-sm); color: var(--color-text-tertiary); }
.stickyActions { display: flex; gap: var(--space-2); align-items: center; }
.stickyFinishForm { margin: 0; }

/* Lock card */
.lockCard {
  background: var(--color-warning-subtle);
  border: 1px solid var(--color-warning);
  border-radius: var(--radius-lg);
  padding: var(--space-5);
}
.lockCard--inline { margin-top: var(--space-5); }
.lockTitle { font-size: var(--text-ui-lg); font-weight: 600; color: var(--color-text-primary); }
.lockText { margin-top: var(--space-2); font-size: var(--text-ui-md); color: var(--color-text-secondary); }
.lockActions { margin-top: var(--space-4); display: flex; flex-wrap: wrap; gap: var(--space-3); }

/* History accordion */
.accordion { margin-top: var(--space-3); display: flex; flex-direction: column; gap: var(--space-2); }
.accItem { border: var(--border-hairline); border-radius: var(--radius-md); overflow: hidden; background: var(--color-surface-raised); }
.accSummary {
  display: flex; align-items: center; justify-content: space-between; gap: var(--space-3);
  padding: var(--space-3) var(--space-4); cursor: pointer; list-style: none;
}
.accSummary::-webkit-details-marker { display: none; }
.accLeft { display: flex; flex-direction: column; gap: 2px; }
.accBody { padding: 0 var(--space-4) var(--space-4); border-top: var(--border-hairline); }

/* Item cards / stacks (resume) */
.stack { display: flex; flex-direction: column; gap: var(--space-3); margin-top: var(--space-3); }
.itemCard { border: var(--border-hairline); border-radius: var(--radius-md); padding: var(--space-4); background: var(--color-surface-raised); }
.itemRow { font-size: var(--text-ui-md); color: var(--color-text-secondary); }
.itemRow b { color: var(--color-text-primary); font-weight: 500; }

/* Confirm block (add) */
.confirm {
  margin-top: var(--space-4);
  padding: var(--space-4);
  background: var(--color-surface);
  border: var(--border-hairline);
  border-radius: var(--radius-md);
  font-size: var(--text-ui-md);
}

/* =========================================================
   MODALS — .modal / .modalCard (aria-hidden controlled by JS)
   ========================================================= */
/* The OVERLAY is the scroll container (not the card). Combined with a column
   flex + `margin:auto` on the card, this centers the card when it fits and
   top-anchors it when it's taller than the viewport — so the card top (and its
   × button) is ALWAYS reachable by scrolling. This fixes the iOS Safari bug
   where a center-aligned tall modal had its top clipped off-screen with no way
   to scroll up to close it. Do NOT put overflow/max-height back on .modalCard
   or align-items:center back on .modal — that reintroduces the clip. */
.modal {
  position: fixed;
  inset: 0;
  z-index: var(--z-modal);
  display: none;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  overscroll-behavior: contain;
  padding: var(--space-4);
  background: var(--color-overlay);
  backdrop-filter: blur(4px);
  -webkit-backdrop-filter: blur(4px);
}
.modal[aria-hidden="false"] { display: flex; flex-direction: column; }

.modalCard {
  position: relative;
  width: 100%;
  max-width: 560px;
  margin: auto;            /* centers when it fits; collapses to top on overflow (no clip) */
  background: var(--color-surface-raised);
  border: var(--border-hairline);
  border-radius: var(--radius-2xl);
  box-shadow: var(--shadow-xl);
  padding: var(--space-6);
  animation: vModalIn 0.2s ease-out;
}
@keyframes vModalIn { from { opacity: 0; transform: translateY(12px); } to { opacity: 1; transform: translateY(0); } }

.modalTitle {
  font-family: var(--font-display);
  font-size: var(--text-d-sm);
  font-weight: 400;
  color: var(--color-text-primary);
}
.modalHeader { display: flex; align-items: flex-start; justify-content: space-between; gap: var(--space-3); }
.modalBackdrop { position: absolute; inset: 0; }

@media (max-width: 560px) {
  .modal { padding: 0; }
  .modalCard {
    max-width: 100%;
    margin: auto 0 0;      /* bottom-sheet feel; still top-reachable when tall */
    border-radius: var(--radius-2xl) var(--radius-2xl) 0 0;
  }
}

/* =========================================================
   VISIT OPEN GATE — one-tap splash on external/fresh-tab opens
   (arms the back-trap before the customer can fumble Back)
   ========================================================= */
.visitOpenGate {
  position: fixed;
  inset: 0;
  z-index: calc(var(--z-modal) + 10);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--space-6);
  background: var(--color-bg);
}
.visitOpenGate[hidden] { display: none; }
.visitOpenGate__card {
  text-align: center;
  max-width: 380px;
  width: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-3);
}
.visitOpenGate__logo { height: 56px; width: auto; object-fit: contain; margin-bottom: var(--space-2); }
.visitOpenGate__title {
  font-family: var(--font-display);
  font-size: var(--text-d-md);
  color: var(--color-text-primary);
}
.visitOpenGate__sub { color: var(--color-text-secondary); font-size: var(--text-ui-lg); }
.visitOpenGate__btn { margin-top: var(--space-4); min-width: 220px; }

/* =========================================================
   ACCORDION SECTIONS — native <details class="acc"> (admin)
   ========================================================= */
.acc { }
.acc > summary {
  list-style: none;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  font-family: var(--font-display);
  font-size: 18px;
  font-weight: 400;
  color: var(--color-text-primary);
  user-select: none;
  -webkit-user-select: none;
}
.acc > summary::-webkit-details-marker { display: none; }
.acc > summary::after {
  content: "\25B8";              /* ▸ */
  font-size: 13px;
  line-height: 1;
  color: var(--color-text-tertiary);
  transition: transform 0.18s ease;
  flex-shrink: 0;
}
.acc[open] > summary::after { transform: rotate(90deg); }
.acc > summary:focus-visible { outline: 2px solid var(--color-accent); outline-offset: 2px; border-radius: 4px; }
.accBody { margin-top: 14px; }

/* Finish review modal (JS-generated rows) */
.finishRow { display: flex; gap: var(--space-3); align-items: flex-start; }
.finishThumb { width: 72px; height: 72px; border-radius: var(--radius-md); object-fit: cover; background: var(--color-surface); }
.finishThumbEmpty { width: 72px; height: 72px; border-radius: var(--radius-md); background: var(--color-surface); border: var(--border-hairline); }
.finishInfo { min-width: 0; flex: 1; }
.finishTitle { font-size: var(--text-ui-lg); font-weight: 600; color: var(--color-text-primary); display: flex; align-items: center; gap: var(--space-2); flex-wrap: wrap; }
.finishMeta { display: flex; flex-wrap: wrap; gap: var(--space-2); margin-top: var(--space-2); }
/* .finishRoomChips is a single <span> child of .finishMeta holding 0+ room
   .pill elements (JS-generated). display:contents removes the wrapper from
   the flex box so the pills become direct flex items and inherit .finishMeta's
   gap themselves — otherwise the gap only applies around the wrapper and the
   pills inside it render flush together. */
.finishRoomChips { display: contents; }
.finishNotes { margin-top: var(--space-2); font-size: var(--text-ui-md); color: var(--color-text-secondary); }
.finishActions { margin-top: var(--space-3); display: flex; gap: var(--space-2); }
.finishDivider { border-top: var(--border-hairline); margin: var(--space-4) 0; }

/* Inventory modal tabs */
.invTabs { display: flex; gap: var(--space-2); margin-top: var(--space-3); border-bottom: 1px solid var(--color-border); }
.invTab {
  background: none; border: none; border-bottom: 2px solid transparent;
  padding: 8px 14px; font-family: var(--font-ui); font-size: var(--text-ui-md);
  font-weight: 600; color: var(--color-text-tertiary); cursor: pointer;
  margin-bottom: -1px; transition: color 0.15s, border-color 0.15s;
}
.invTab:hover { color: var(--color-text-primary); }
.invTab--active { color: var(--color-accent); border-bottom-color: var(--color-accent); }
.invNlqHint { font-size: var(--text-ui-sm); color: var(--color-text-secondary); }

/* Visit concierge chat */
.conciergeLog {
  display: flex; flex-direction: column; gap: var(--space-3);
  max-height: 46vh; overflow-y: auto; padding: var(--space-3) 0;
}
.starterPrompts { display: flex; flex-wrap: wrap; gap: var(--space-2); margin-top: var(--space-3); }
.starterPrompt {
  padding: 6px 12px; border: 1px solid var(--color-border);
  border-radius: var(--radius-full); background: var(--color-surface);
  font-size: var(--text-ui-sm); color: var(--color-text-secondary);
  cursor: pointer; font-family: var(--font-ui);
}
.starterPrompt:hover { background: var(--color-surface-raised); border-color: var(--color-accent); color: var(--color-accent); }
.conciergeEmpty { text-align: center; padding: var(--space-6) 0; color: var(--color-text-tertiary); font-size: var(--text-ui-md); }
.conciergeInputRow { display: flex; gap: var(--space-2); margin-top: var(--space-3); }
.conciergeInput { flex: 1; }

/* Ask AI chat bubbles */
.askBubble { font-size: var(--text-ui-md); line-height: 1.5; word-break: break-word; }
.askBubble--user {
  align-self: flex-end; max-width: 85%;
  background: var(--color-text-primary); color: var(--color-surface-raised);
  border-radius: 14px 14px 4px 14px; padding: 10px 14px;
}
.askBubble--assistant {
  align-self: flex-start; max-width: 90%;
  background: var(--color-surface);
  border-radius: 14px 14px 14px 4px; padding: 10px 14px;
}
.askBubble__caution { margin-top: 6px; color: var(--color-danger); }
.askBubble ul { margin: 4px 0; padding-left: 20px; }
.askBubble li { margin-bottom: 2px; }
.askBubble strong { font-weight: 700; }

/* Inventory browser cards */
.invCard {
  border: 1px solid var(--color-border);
  border-radius: 12px; overflow: hidden;
  display: flex; flex-direction: column;
  background: var(--color-surface-raised);
}
.invCard--special { border-color: var(--color-warning); }
.invCard__thumb { width: 100%; height: 110px; object-fit: cover; display: block; }
.invCard__photo-empty {
  width: 100%; height: 110px;
  background: var(--color-surface);
  display: flex; align-items: center; justify-content: center;
  font-size: 11px; color: var(--color-text-tertiary);
}
.invCard__body { padding: 8px; flex: 1; display: flex; flex-direction: column; }
.invCard__name { font-size: 12px; font-weight: 800; line-height: 1.25; color: var(--color-text-primary); }
.invCard__lot { font-size: 11px; color: var(--color-text-tertiary); margin-top: 2px; }
.invCard__meta { font-size: 11px; color: var(--color-text-secondary); margin-top: 2px; }
.invCard__special-pill {
  margin-top: 4px; display: inline-block;
  padding: 2px 7px; border-radius: 999px;
  background: var(--color-warning-subtle); color: var(--color-warning);
  border: 1px solid var(--color-warning); font-size: 10px; font-weight: 800;
}
.invAddBtn {
  width: 100%; padding: 8px; border: none;
  border-top: 1px solid var(--color-border);
  background: var(--color-text-primary); color: var(--color-surface-raised);
  font-family: var(--font-ui); font-weight: 700; font-size: 12px; cursor: pointer;
}
.invAddBtn:hover:not(:disabled) { opacity: 0.85; }
.invAddBtn--added {
  background: var(--color-surface); color: var(--color-text-tertiary); cursor: default;
}

.askTyping { display: inline-flex; gap: 4px; align-items: center; }
.askTyping span {
  width: 6px; height: 6px; border-radius: 50%;
  background: var(--color-text-tertiary);
  animation: vTyping 1.2s infinite ease-in-out;
}
.askTyping span:nth-child(2) { animation-delay: 0.2s; }
.askTyping span:nth-child(3) { animation-delay: 0.4s; }
@keyframes vTyping { 0%, 60%, 100% { opacity: 0.3; transform: translateY(0); } 30% { opacity: 1; transform: translateY(-3px); } }

/* Toast */
.toast {
  position: fixed;
  left: 50%;
  bottom: 96px;
  transform: translateX(-50%);
  z-index: var(--z-toast);
  max-width: 90vw;
  padding: var(--space-3) var(--space-5);
  background: var(--color-text-primary);
  color: var(--color-bg);
  border-radius: var(--radius-full);
  font-size: var(--text-ui-md);
  font-weight: 500;
  box-shadow: var(--shadow-lg);
}

/* =========================================================
   LOADING OVERLAY (controlled by loading.js via aria-hidden)
   ========================================================= */
.loadingOverlay {
  position: fixed;
  inset: 0;
  z-index: var(--z-toast);
  display: none;
  align-items: center;
  justify-content: center;
  background: color-mix(in srgb, var(--color-bg) 80%, transparent);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
}
.loadingOverlay[aria-hidden="false"] { display: flex; }
.loadingCenter { display: flex; flex-direction: column; align-items: center; gap: var(--space-4); }
.logoSpinner {
  width: 88px; height: 88px;
  display: flex; align-items: center; justify-content: center;
  border-radius: var(--radius-full);
  border: 2px solid var(--color-border);
  border-top-color: var(--color-accent);
  animation: vSpin 0.9s linear infinite;
}
.loadingLogo { width: 52px; height: 52px; object-fit: contain; border-radius: var(--radius-md); }
@keyframes vSpin { to { transform: rotate(360deg); } }
.loadingText { text-align: center; }
.loadingTitle { font-size: var(--text-ui-lg); font-weight: 600; color: var(--color-text-primary); }
.loadingSub { font-size: var(--text-ui-sm); color: var(--color-text-secondary); margin-top: 2px; }

/* =========================================================
   FINISH — project-type chips
   ========================================================= */
.projectChips { display: flex; flex-wrap: wrap; gap: var(--space-2); margin-top: var(--space-2); }
.projectChip {
  padding: 6px 14px;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-full);
  background: var(--color-surface);
  font-family: var(--font-ui);
  font-size: var(--text-ui-sm);
  color: var(--color-text-secondary);
  cursor: pointer;
  transition: border-color 0.15s, color 0.15s, background 0.15s;
}
.projectChip:hover { border-color: var(--color-accent); color: var(--color-accent); }
.projectChip--on {
  border-color: var(--color-accent);
  background: var(--color-accent-subtle, var(--color-surface-raised));
  color: var(--color-accent);
  font-weight: 600;
}

/* =========================================================
   COMPARE — pick list + side-by-side grid
   ========================================================= */
.cmpPickList { display: flex; flex-direction: column; gap: var(--space-2); }
.cmpPickRow {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-2) var(--space-3);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  background: var(--color-surface);
  cursor: pointer;
}
.cmpPickRow--on { border-color: var(--color-accent); background: var(--color-surface-raised); }
.cmpPickThumb {
  width: 48px; height: 48px;
  object-fit: cover;
  border-radius: var(--radius-sm);
  border: 1px solid var(--color-border);
  flex-shrink: 0;
}
.cmpPickThumb--empty { background: var(--color-surface-raised); }
.cmpPickName {
  font-family: var(--font-ui);
  font-size: var(--text-ui-md);
  font-weight: 600;
  color: var(--color-text-primary);
}
.cmpGrid {
  display: grid;
  grid-template-columns: 88px repeat(var(--cmp-cols, 2), 1fr);
  gap: 1px;
  background: var(--color-border);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  overflow: hidden;
}
.cmpLabel, .cmpCell { background: var(--color-surface); padding: var(--space-3); }
.cmpLabel {
  font-family: var(--font-ui);
  font-size: var(--text-ui-xs);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--color-text-tertiary);
  display: flex;
  align-items: center;
}
.cmpCell {
  font-family: var(--font-ui);
  font-size: var(--text-ui-sm);
  color: var(--color-text-primary);
}
.cmpHead { text-align: center; }
.cmpImg {
  width: 100%;
  aspect-ratio: 4 / 3;
  object-fit: cover;
  border-radius: var(--radius-sm);
  border: 1px solid var(--color-border);
}
.cmpImg--empty { background: var(--color-surface-raised); display: block; }
.cmpName {
  margin-top: var(--space-2);
  font-family: var(--font-ui);
  font-size: var(--text-ui-md);
  font-weight: 600;
  color: var(--color-text-primary);
}

/* =========================================================
   ADMIN LIVE FLOOR — cards + elapsed urgency badges
   ========================================================= */
.liveCard {
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  padding: var(--space-3);
  cursor: pointer;
  transition: border-color 0.15s, box-shadow 0.15s;
}
.liveCard:hover {
  border-color: var(--color-accent);
  box-shadow: var(--shadow-sm);
}
.liveCardName {
  font-family: var(--font-ui);
  font-size: var(--text-ui-md);
  font-weight: 600;
  color: var(--color-text-primary);
}
.liveCardBadges { display: flex; flex-wrap: wrap; gap: var(--space-1); margin-top: var(--space-2); }
.liveCardMeta {
  font-family: var(--font-ui);
  font-size: var(--text-ui-sm);
  color: var(--color-text-secondary);
  margin-top: var(--space-1);
}
.liveBadge {
  display: inline-block;
  padding: 2px 8px;
  border-radius: var(--radius-full);
  border: 1px solid var(--color-border);
  background: var(--color-surface-raised);
  font-family: var(--font-ui);
  font-size: var(--text-ui-xs);
  color: var(--color-text-secondary);
  white-space: nowrap;
}
.liveBadge--ok    { background: var(--color-success-subtle); color: var(--color-success); border-color: var(--color-success); }
.liveBadge--warn  { background: var(--color-warning-subtle); color: var(--color-warning); border-color: var(--color-warning); }
.liveBadge--late  { background: var(--color-danger-subtle);  color: var(--color-danger);  border-color: var(--color-danger); }

/* =========================================================
   TAGS QUICK ASSIGN — inline scan → assign flow
   ========================================================= */
.qaToast {
  padding: var(--space-2) var(--space-3);
  border: 1px solid var(--color-success);
  border-radius: var(--radius-md);
  background: var(--color-success-subtle);
  color: var(--color-success);
  font-family: var(--font-ui);
  font-size: var(--text-ui-sm);
  font-weight: 600;
}
.qaToast--error {
  border-color: var(--color-danger);
  background: var(--color-danger-subtle);
  color: var(--color-danger);
}
.qaResult {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  width: 100%;
  padding: var(--space-2) var(--space-3);
  margin-bottom: var(--space-2);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  background: var(--color-surface);
  cursor: pointer;
  font-family: var(--font-ui);
}
.qaResult:hover { border-color: var(--color-accent); }
.qaResult:disabled { opacity: 0.5; cursor: wait; }
.qaResult__img {
  width: 44px; height: 44px;
  object-fit: cover;
  border-radius: var(--radius-sm);
  border: 1px solid var(--color-border);
  flex-shrink: 0;
}
.qaResult__img--empty { background: var(--color-surface-raised); }
.qaResult__name {
  font-size: var(--text-ui-md);
  font-weight: 600;
  color: var(--color-text-primary);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* =========================================================
   ADMIN ANALYTICS — CSS bar chart + top stones
   ========================================================= */
.chartBars {
  display: flex;
  align-items: flex-end;
  gap: 3px;
  height: 150px;
  padding: var(--space-2) 0 0;
}
.chartCol {
  flex: 1 1 0;
  min-width: 0;
  height: 100%;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  align-items: center;
}
.chartBar {
  width: 100%;
  min-height: 2px;
  background: var(--color-accent);
  border-radius: 3px 3px 0 0;
  opacity: 0.85;
  transition: opacity 0.15s;
}
.chartCol:hover .chartBar { opacity: 1; }
.chartLabel {
  margin-top: 4px;
  height: 14px;
  font-family: var(--font-ui);
  font-size: 9px;
  color: var(--color-text-tertiary);
  white-space: nowrap;
  overflow: visible;
}
.topStones { display: flex; flex-direction: column; gap: var(--space-2); }
.topStoneRow {
  display: grid;
  grid-template-columns: minmax(90px, 40%) 1fr 32px;
  gap: var(--space-2);
  align-items: center;
}
.topStoneName {
  font-family: var(--font-ui);
  font-size: var(--text-ui-sm);
  color: var(--color-text-primary);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.topStoneTrack {
  height: 8px;
  background: var(--color-surface-raised);
  border-radius: var(--radius-full);
  overflow: hidden;
}
.topStoneBar { height: 100%; background: var(--color-accent); border-radius: var(--radius-full); }
.topStoneCount {
  font-family: var(--font-ui);
  font-size: var(--text-ui-sm);
  font-weight: 600;
  color: var(--color-text-secondary);
  text-align: right;
}

/* Check-in: returning-customer prompt */
.welcomeBack {
  margin-top: var(--space-2);
  padding: var(--space-2) var(--space-3);
  border: 1px solid var(--color-accent);
  border-radius: var(--radius-md);
  background: var(--color-surface-raised);
  font-family: var(--font-ui);
  font-size: var(--text-ui-sm);
  color: var(--color-text-primary);
}

/* =========================================================
   FABRICATOR / DESIGNER / CONTRACTOR — directory typeahead
   ========================================================= */
.fabField { position: relative; }

.fabMenu {
  position: absolute;
  top: calc(100% + 4px);
  left: 0;
  right: 0;
  z-index: 40;
  max-height: 264px;
  overflow-y: auto;
  background: var(--color-surface-raised);
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-lg);
  padding: var(--space-1);
}
.fabMenu[hidden] { display: none; }

.fabItem {
  display: block;
  width: 100%;
  text-align: left;
  padding: var(--space-2) var(--space-3);
  border: 0;
  border-radius: var(--radius-sm);
  background: transparent;
  cursor: pointer;
  font-family: var(--font-ui);
  color: var(--color-text-primary);
}
.fabItem:hover,
.fabItem.is-active { background: var(--color-accent-subtle); }

.fabItem__name { font-size: var(--text-ui-sm); font-weight: 600; }
.fabItem__meta {
  display: block;
  margin-top: 1px;
  font-size: var(--text-ui-sm);
  color: var(--color-text-tertiary);
}

/* Action rows: "Not sure / walk-in" and "Use as entered" */
.fabItem--action { color: var(--color-text-secondary); }
.fabItem--action .fabItem__name { font-weight: 500; }
.fabMenu__sep { height: 1px; margin: var(--space-1) 0; background: var(--color-border); }

.fabChosen {
  margin-top: var(--space-2);
  font-family: var(--font-ui);
  font-size: var(--text-ui-sm);
  color: var(--color-text-secondary);
}
.fabChosen[hidden] { display: none; }
.fabChosen strong { color: var(--color-text-primary); }
.fabChosen--walkin { color: var(--color-text-tertiary); }

.fabNudge {
  margin-top: var(--space-2);
  font-family: var(--font-ui);
  font-size: var(--text-ui-sm);
  color: var(--color-danger);
}
.fabNudge[hidden] { display: none; }

/* Results dropdown for the "Edit my info" fabricator typeahead — same visual
   treatment as .fabMenu above, scoped separately since it lives in the
   contact modal (raised z-index; see #contactModal). */
.fabResults {
  position: absolute;
  top: calc(100% + 4px);
  left: 0;
  right: 0;
  z-index: 10;
  max-height: 264px;
  overflow-y: auto;
  background: var(--color-surface-raised);
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-lg);
  padding: var(--space-1);
}
.fabResults[hidden] { display: none; }

/* =========================================================
   FINISH MODAL — "Your details" summary
   ========================================================= */
.finishDetails {
  background: var(--color-surface-raised);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  padding: var(--space-3);
}
.finishDetails #finishDetailsBody { color: var(--color-text-secondary); }
.finishDetails #finishDetailsBody div { margin-top: 2px; }
.finishDetails #finishDetailsBody div:first-child { margin-top: 0; }

/* =========================================================
   PUBLIC WISHLIST — read-only share page
   ========================================================= */
.pubGrid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
  gap: var(--space-4);
}
.pubCard {
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  overflow: hidden;
  display: flex;
  flex-direction: column;
}
.pubCard__img {
  display: block;
  width: 100%;
  aspect-ratio: 4 / 3;
  object-fit: cover;
  background: var(--color-surface-raised);
}
.pubCard__img--empty { border-bottom: 1px solid var(--color-border); }
.pubCard__body {
  padding: var(--space-4);
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}
.pubCard__title {
  font-family: var(--font-display);
  font-size: var(--text-ui-xl);
  color: var(--color-text-primary);
  line-height: 1.2;
}
.pubCard__lot {
  font-family: var(--font-ui);
  font-size: var(--text-ui-sm);
  color: var(--color-text-secondary);
  font-weight: 600;
}
.pubCard__meta { display: flex; flex-wrap: wrap; gap: var(--space-1); }
.pubBadge {
  display: inline-block;
  padding: 2px 8px;
  border-radius: var(--radius-full);
  border: 1px solid var(--color-border);
  background: var(--color-surface-raised);
  font-family: var(--font-ui);
  font-size: var(--text-ui-xs);
  color: var(--color-text-secondary);
  white-space: nowrap;
}
.pubBadge--special {
  border-color: var(--color-accent);
  color: var(--color-accent);
  background: transparent;
}
.pubCard__notes {
  font-family: var(--font-ui);
  font-size: var(--text-ui-sm);
  color: var(--color-text-secondary);
  font-style: italic;
}

/* =========================================================
   ENTRY SECURITY — lock screen + rotating-QR display
   ========================================================= */
.lockedIcon {
  width: 64px; height: 64px;
  margin: 0 auto;
  display: flex; align-items: center; justify-content: center;
  border-radius: var(--radius-full);
  background: var(--color-surface-raised);
  border: 1px solid var(--color-border);
  color: var(--color-accent);
}

.entryDisplay {
  min-height: 100vh;
  min-height: 100dvh;
  display: flex; align-items: center; justify-content: center;
  padding: var(--space-6);
  background: var(--color-bg);
}
.entryDisplay__inner {
  display: flex; flex-direction: column; align-items: center;
  text-align: center;
  max-width: 560px;
}
.entryDisplay__logo {
  height: 72px; object-fit: contain;
  border-radius: var(--radius-md);
}
.entryDisplay__name {
  margin-top: var(--space-3);
  font-family: var(--font-display);
  font-size: var(--text-d-sm);
  color: var(--color-text-primary);
}
.entryDisplay__title {
  margin-top: var(--space-6);
  font-family: var(--font-display);
  font-size: var(--text-d-xl);
  color: var(--color-text-primary);
  line-height: 1.1;
}
.entryDisplay__sub {
  margin-top: var(--space-3);
  font-family: var(--font-ui);
  font-size: var(--text-ui-lg);
  color: var(--color-text-secondary);
  max-width: 420px;
}
.entryDisplay__qrWrap {
  margin-top: var(--space-6);
  padding: var(--space-5);
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-md);
}
.entryDisplay__qr {
  display: block;
  width: min(58vmin, 380px);
  height: min(58vmin, 380px);
}
.entryDisplay__hint {
  margin-top: var(--space-5);
  font-family: var(--font-ui);
  font-size: var(--text-ui-sm);
  color: var(--color-text-tertiary);
}

/* =========================================================
   RESPONSIVE — table on desktop, cards on mobile
   ========================================================= */
@media (max-width: 760px) {
  .tableWrap { display: none; }
  /* Detail + modal tables in admin stay visible — they scroll horizontally */
  .adminDetailTable { display: block !important; overflow-x: auto; }
  /* Pages with no .mobileList card fallback (e.g. the tag dashboard) opt into
     a horizontally-scrolling table instead of vanishing on phones. */
  .tableWrap--scroll { display: block; overflow-x: auto; }
  .mobileList { display: flex; }
  .sheetHeader { flex-direction: column; }
  .scanWell.toolbarScan { margin-left: 0; width: 100%; }
  .toolbar .btn { flex: 1 1 auto; }
  .adminHeaderActions { flex-direction: column; align-items: flex-start; }
  .analyticsTiles { grid-template-columns: repeat(auto-fit, minmax(100px, 1fr)); }
  .analyticsGrid { grid-template-columns: 1fr !important; }
}

/* =========================================================
   ADMIN — header layout
   ========================================================= */
.adminHeaderActions {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
}
.adminHeaderGroup {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
}

/* =========================================================
   ADMIN — stat tiles (today's stats)
   ========================================================= */
.statGrid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: 10px;
}
.statTile {
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  padding: 14px 12px;
  text-align: center;
  background: var(--color-surface-raised);
}
.statTileLabel {
  font-family: var(--font-ui);
  font-size: var(--text-ui-sm);
  color: var(--color-text-secondary);
}
.statTileVal {
  font-family: var(--font-ui);
  font-size: 30px;
  font-weight: 600;
  color: var(--color-text-primary);
  margin: 4px 0 0;
}

/* =========================================================
   ADMIN — analytics tiles + grid
   ========================================================= */
.analyticsTiles {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
  gap: 10px;
  margin-bottom: 16px;
}
.analyticsTile {
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  padding: 10px 12px;
  text-align: center;
  background: var(--color-surface-raised);
}
.analyticsTileVal {
  font-family: var(--font-ui);
  font-size: 22px;
  font-weight: 600;
  color: var(--color-accent);
  line-height: 1.2;
}
.analyticsTileLabel {
  font-family: var(--font-ui);
  font-size: var(--text-ui-sm);
  color: var(--color-text-secondary);
  margin-top: 2px;
}
.analyticsGrid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 20px;
}
.analyticsPanel {
  min-width: 0;
}
/* Make the day chart taller */
.analyticsPanel .chartBars { height: 180px; }

/* =========================================================
   ADMIN — New vs Repeat chart
   ========================================================= */
.newRepeatRow {
  display: grid;
  grid-template-columns: 52px 1fr 70px;
  gap: var(--space-2);
  align-items: center;
  margin-bottom: 8px;
}
.newRepeatLabel {
  font-family: var(--font-ui);
  font-size: var(--text-ui-sm);
  color: var(--color-text-primary);
  font-weight: 500;
}
.newRepeatTrack {
  height: 10px;
  background: var(--color-surface-raised);
  border-radius: var(--radius-full);
  overflow: hidden;
}
.newRepeatBar {
  height: 100%;
  border-radius: var(--radius-full);
  transition: width 0.4s ease;
}
.newRepeatNew { background: var(--color-accent); }
.newRepeatRepeat { background: var(--color-success, #22c55e); }
.newRepeatCount {
  font-family: var(--font-ui);
  font-size: var(--text-ui-sm);
  font-weight: 600;
  color: var(--color-text-secondary);
  text-align: right;
}

/* =========================================================
   ADMIN — sortable table headers
   ========================================================= */
.sortTh {
  cursor: pointer;
  user-select: none;
  white-space: nowrap;
}
.sortTh:hover { color: var(--color-accent); }
.sortTh::after { content: " ⇅"; opacity: 0.35; font-size: 0.8em; }
.sortTh.sortDesc::after { content: " ▼"; opacity: 0.7; }
.sortTh.sortAsc::after  { content: " ▲"; opacity: 0.7; }

/* =========================================================
   ADMIN — mobile visit / customer cards
   ========================================================= */
.adminVisitCard {
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  padding: 12px 14px;
  background: var(--color-surface-raised);
  cursor: pointer;
  transition: background 0.12s, border-color 0.12s;
}
.adminVisitCard:hover,
.adminVisitCard.isSelected {
  border-color: var(--color-accent);
  background: var(--color-surface-active, var(--color-surface-raised));
}
.adminVisitCardTop {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  margin-bottom: 4px;
}
.adminVisitCardName {
  font-family: var(--font-ui);
  font-size: var(--text-ui);
  font-weight: 600;
  color: var(--color-text-primary);
}
.adminVisitCardMeta {
  font-family: var(--font-ui);
  font-size: var(--text-ui-sm);
  color: var(--color-text-secondary);
  margin-top: 2px;
}

/* =========================================================
   ADMIN — danger button
   ========================================================= */
.btn-danger {
  background: var(--color-danger) !important;
  color: #fff !important;
  border-color: var(--color-danger) !important;
}
.btn-danger:hover { opacity: 0.88; }

/* =========================================================
   ADMIN — visit notes textarea
   ========================================================= */
.adminNotes {
  font-size: var(--text-ui-sm);
  font-family: inherit;
  line-height: 1.5;
  padding: 8px;
  min-height: 64px;
}

/* =========================================================
   ADMIN — trend arrows on analytics tiles
   ========================================================= */
.trendUp   { font-size: .72rem; color: var(--color-success, #16a34a); font-variant-numeric: tabular-nums; margin-top: 2px; }
.trendDown { font-size: .72rem; color: var(--color-danger); font-variant-numeric: tabular-nums; margin-top: 2px; }
.trendFlat { font-size: .72rem; color: var(--color-text-tertiary); margin-top: 2px; }

/* =========================================================
   ADMIN — conversion funnel
   ========================================================= */
.funnelRow  { display: flex; align-items: flex-start; gap: 8px; flex-wrap: wrap; }
.funnelStep { display: flex; flex-direction: column; align-items: center; min-width: 80px; flex: 1; }
.funnelCount {
  font-size: 1.8rem; font-weight: 700; color: var(--color-accent);
  line-height: 1; font-variant-numeric: tabular-nums;
}
.funnelLabel { font-size: .75rem; color: var(--color-text-secondary); margin-top: 3px; text-align: center; }
.funnelPct   { font-size: .72rem; color: var(--color-text-tertiary); margin-top: 2px; }
.funnelDrop  { font-size: .7rem; color: var(--color-danger); margin-top: 2px; }
.funnelArrow { font-size: 1.2rem; color: var(--color-text-tertiary); align-self: flex-start; margin-top: 14px; }

/* =========================================================
   ADMIN — hourly distribution chart
   ========================================================= */
.hourlyChart { display: flex; align-items: flex-end; gap: 1px; height: 80px; }
.hourlyCol   { display: flex; flex-direction: column; align-items: center; flex: 1; height: 100%; }
.hourlyBar   {
  flex: 1; width: 100%; background: var(--color-accent);
  opacity: .55; border-radius: 2px 2px 0 0; min-height: 2px; transition: opacity .1s;
}
.hourlyCol:hover .hourlyBar { opacity: 1; }
.hourlyLabel { font-size: .52rem; color: var(--color-text-tertiary); white-space: nowrap; margin-top: 2px; line-height: 1; }

/* =========================================================
   ADMIN — rep performance table
   ========================================================= */
.repTable { width: 100%; border-collapse: collapse; font-size: .8rem; font-variant-numeric: tabular-nums; }
.repTable th {
  text-align: left; padding: 4px 6px; color: var(--color-text-tertiary);
  font-weight: 500; border-bottom: 1px solid var(--color-border); white-space: nowrap;
}
.repTable td { padding: 4px 6px; border-bottom: 1px solid var(--color-border-subtle, var(--color-border)); }
.repTable tr:last-child td { border-bottom: none; }

/* =========================================================
   ADMIN — live floor inline rep assignment
   ========================================================= */
.liveCardRepRow { display: flex; align-items: center; gap: 5px; margin-top: 8px; }

/* =========================================================
   ADMIN — quick-filter preset row
   ========================================================= */
.presetsRow {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}
.presetBtn {
  font-size: var(--text-ui-sm);
  padding: 4px 12px;
  height: auto;
  border-radius: var(--radius-full);
}
.presetBtn.isSelected {
  background: var(--color-accent) !important;
  color: var(--color-on-accent, #fff) !important;
  border-color: var(--color-accent) !important;
}

/* =========================================================
   ADMIN — clickable stat tiles
   ========================================================= */
.statTileClickable {
  cursor: pointer;
  transition: border-color 0.12s, background 0.12s;
}
.statTileClickable:hover {
  border-color: var(--color-accent);
  background: var(--color-surface-active, var(--color-surface-raised));
}
.statTileClickable:hover .statTileVal {
  color: var(--color-accent);
}

/* =========================================================
   ADMIN — visit duration sub-text in table
   ========================================================= */
.visitTimestamp { line-height: 1.3; }
.visitDuration {
  font-size: 0.72rem;
  color: var(--color-text-tertiary);
  margin-top: 1px;
}

/* =========================================================
   ADMIN — visit timeline (Tier 4)
   ========================================================= */
.visitTimeline {
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding-left: 4px;
  border-left: 2px solid var(--color-border);
  margin-left: 8px;
}
.timelineEvent {
  display: flex;
  align-items: baseline;
  gap: 6px;
  font-size: 0.78rem;
  line-height: 1.4;
}
.timelineIcon {
  font-size: 0.65rem;
  color: var(--color-text-tertiary);
  flex-shrink: 0;
  width: 10px;
}
.timelineEvent--checkin .timelineIcon { color: var(--color-accent); }
.timelineEvent--finish  .timelineIcon { color: var(--color-success, #16a34a); }
.timelineEvent--stone   .timelineIcon { color: var(--color-text-secondary); }
.timelineLabel {
  flex: 1;
  color: var(--color-text-primary);
}
.timelineTs {
  color: var(--color-text-tertiary);
  font-size: 0.72rem;
  flex-shrink: 0;
  white-space: nowrap;
}

/* =========================================================
   ADMIN — bulk actions bar (Tier 4)
   ========================================================= */
.bulkBar {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
  padding: 8px 12px !important;
  background: var(--color-surface-raised) !important;
  border-color: var(--color-accent) !important;
}

/* =========================================================
   ADMIN — customer profile stats (Tier 4)
   ========================================================= */
.custStatRow {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}
.custStat {
  display: flex;
  flex-direction: column;
  align-items: center;
  min-width: 64px;
  padding: 6px 12px;
  background: var(--color-surface-raised);
  border: 1px solid var(--color-border);
  border-radius: 8px;
}
.custStatLabel {
  font-size: 0.68rem;
  color: var(--color-text-tertiary);
  text-transform: uppercase;
  letter-spacing: .04em;
}
.custStatVal {
  font-size: 1rem;
  font-weight: 600;
  color: var(--color-text-primary);
  margin-top: 2px;
}

/* =========================================================
   ADMIN — saved view buttons (Tier 4)
   ========================================================= */
.savedViewBtn {
  display: inline-flex;
  align-items: center;
}
.savedViewBtn .savedViewDel:hover {
  opacity: 1 !important;
}

/* =========================================================
   ADMIN — Stone Affinity panel
   ========================================================= */
.affinityLift {
  display: inline-block;
  font-variant-numeric: tabular-nums;
  font-weight: 600;
  color: var(--color-text-secondary);
}
.affinityLift.affinityLiftMed {
  color: var(--color-accent);
}
.affinityLift.affinityLiftHigh {
  color: var(--color-success, #16a34a);
}
.affinityRelatedGrid {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 4px;
}
.affinityRelatedRow {
  display: flex;
  align-items: center;
  gap: 6px;
}
.affinityRelatedMeta {
  font-size: .78rem;
  opacity: .65;
}
.sb-chip-subtle {
  background: var(--color-surface-raised);
  color: var(--color-text-secondary);
  border: 1px solid var(--color-border);
}

/* Mood Board modal */
.mbBody { max-height: 64vh; overflow-y: auto; }

.mbHero {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  margin-bottom: var(--space-4);
}
.mbHeroImg {
  width: 72px;
  height: 72px;
  border-radius: var(--radius-md);
  object-fit: cover;
  border: 1px solid var(--color-border);
  flex-shrink: 0;
}
.mbHeroImg--empty {
  background: var(--color-surface);
}
.mbHeroName { font-size: var(--text-ui-lg); font-weight: 600; color: var(--color-text-primary); }

.mbSection { margin-bottom: var(--space-5); }
.mbLabel {
  font-size: var(--text-ui-xs);
  font-weight: 700;
  letter-spacing: .04em;
  text-transform: uppercase;
  color: var(--color-text-tertiary);
  margin-bottom: var(--space-2);
}

.mbSwatchRow { display: flex; flex-wrap: wrap; gap: var(--space-3); }
.mbSwatch { display: flex; flex-direction: column; align-items: center; gap: 4px; width: 68px; }
.mbSwatchColor {
  width: 44px;
  height: 44px;
  border-radius: var(--radius-full);
  border: 1px solid var(--color-border);
  box-shadow: var(--shadow-sm);
}
.mbSwatchLabel {
  font-size: var(--text-ui-xs);
  color: var(--color-text-secondary);
  text-align: center;
  line-height: 1.25;
}

.mbTagRow { display: flex; flex-wrap: wrap; gap: var(--space-2); }

.mbPairGrid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-3);
}
.mbPairItem {
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  padding: var(--space-2) var(--space-3);
}
.mbPairKey {
  font-size: var(--text-ui-xs);
  color: var(--color-text-tertiary);
  text-transform: uppercase;
  letter-spacing: .03em;
}
.mbPairVal { font-size: var(--text-ui-sm); color: var(--color-text-primary); margin-top: 2px; }

.mbNarrative {
  font-size: var(--text-ui-md);
  line-height: 1.6;
  color: var(--color-text-primary);
  font-style: italic;
}

.mbCareList { margin: 0; padding-left: 18px; }
.mbCareList li { font-size: var(--text-ui-sm); color: var(--color-text-secondary); margin-bottom: 4px; }

.mbSkeleton { display: flex; flex-direction: column; gap: var(--space-4); }
.mbSkeletonRow { display: flex; gap: var(--space-3); }
.mbSkeletonBlock {
  border-radius: var(--radius-md);
  background: linear-gradient(90deg, var(--color-surface) 25%, var(--color-surface-raised) 50%, var(--color-surface) 75%);
  background-size: 200% 100%;
  animation: mbShimmer 1.4s ease-in-out infinite;
}
@keyframes mbShimmer {
  0% { background-position: 200% 0; }
  100% { background-position: -200% 0; }
}

.mbError {
  background: var(--color-danger-subtle);
  color: var(--color-danger);
  border-radius: var(--radius-md);
  padding: var(--space-3);
  font-size: var(--text-ui-sm);
}

/* Visualize This modal */
.vzBody { max-height: 68vh; overflow-y: auto; }

.vzRoomGrid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: var(--space-2);
}
@media (max-width: 520px) {
  .vzRoomGrid { grid-template-columns: repeat(3, 1fr); }
}

.vzRoomCard {
  position: relative;
  border: 2px solid transparent;
  border-radius: var(--radius-md);
  padding: 0;
  cursor: pointer;
  overflow: hidden;
  background: var(--color-surface);
  transition: border-color .15s, box-shadow .15s;
}
.vzRoomCard img { width: 100%; aspect-ratio: 4/3; object-fit: cover; display: block; }
.vzRoomCard:hover { border-color: var(--color-border-strong); box-shadow: var(--shadow-sm); }
.vzRoomCard.selected { border-color: var(--color-accent); box-shadow: 0 0 0 3px var(--color-accent-subtle); }

.vzRoomCount {
  position: absolute;
  top: 4px; right: 4px;
  padding: 2px 6px;
  border-radius: var(--radius-full);
  font-size: var(--text-ui-xs);
  font-weight: 700;
  color: #fff;
  background: rgba(0,0,0,.55);
  line-height: 1.4;
  pointer-events: none;
}
.vzRoomLabel {
  position: absolute;
  bottom: 0; left: 0; right: 0;
  padding: 4px 5px 5px;
  font-size: var(--text-ui-xs);
  font-weight: 700;
  color: #fff;
  background: linear-gradient(transparent, rgba(0,0,0,.65));
  text-align: center;
  line-height: 1.2;
}

.vzRoomSkeleton {
  border-radius: var(--radius-md);
  aspect-ratio: 4/3;
  background: linear-gradient(90deg, var(--color-surface) 25%, var(--color-surface-raised) 50%, var(--color-surface) 75%);
  background-size: 200% 100%;
  animation: mbShimmer 1.4s ease-in-out infinite;
}

.vzUploadDivider {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  margin: var(--space-4) 0 var(--space-2);
  color: var(--color-text-tertiary);
  font-size: var(--text-ui-xs);
  letter-spacing: .04em;
  text-transform: uppercase;
}
.vzUploadDivider::before, .vzUploadDivider::after { content: ''; flex: 1; height: 1px; background: var(--color-border); }

.vzUploadBtn {
  display: flex;
  flex-direction: column;
  gap: 2px;
  width: 100%;
  padding: var(--space-3);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  background: var(--color-surface-raised);
  color: var(--color-text-primary);
  cursor: pointer;
  text-align: left;
  transition: border-color .15s;
}
.vzUploadBtn:hover { border-color: var(--color-accent); }
.vzUploadTitle { font-size: var(--text-ui-md); font-weight: 600; }
.vzUploadSub { font-size: var(--text-ui-sm); color: var(--color-text-secondary); }

.vzUploadPreview {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  margin-top: var(--space-2);
  padding: var(--space-2) var(--space-3);
  background: var(--color-success-subtle);
  border: 1px solid var(--color-success);
  border-radius: var(--radius-md);
}
.vzUploadThumb {
  width: 64px;
  height: 48px;
  object-fit: cover;
  border-radius: var(--radius-sm);
  flex-shrink: 0;
}

.vzColorSection { margin-bottom: var(--space-3); }
.vzColorField { display: flex; flex-direction: column; gap: 4px; font-size: var(--text-ui-sm); }
.vzColorField--check { flex-direction: row; align-items: center; gap: var(--space-2); margin-top: var(--space-2); }

.vzSwatchRow { display: flex; flex-wrap: wrap; gap: var(--space-2); margin-top: var(--space-2); }
.vzSwatchBtn {
  width: 30px;
  height: 30px;
  border-radius: var(--radius-sm);
  border: 2px solid var(--color-border);
  cursor: pointer;
  transition: transform .12s, border-color .12s;
  box-shadow: var(--shadow-sm);
  flex-shrink: 0;
  padding: 0;
  position: relative;
  overflow: hidden;
}
.vzSwatchBtn:hover { transform: scale(1.12); }
.vzSwatchBtn.selected { border-color: var(--color-accent); box-shadow: 0 0 0 3px var(--color-accent-subtle); }
.vzSwatchBtn--none {
  background: var(--color-surface);
  color: var(--color-text-tertiary);
  font-size: var(--text-ui-sm);
  display: flex;
  align-items: center;
  justify-content: center;
}
.vzSwatchBtn--custom { display: block; }
.vzSwatchBtn--custom input[type="color"] {
  width: 100%;
  height: 100%;
  padding: 0;
  border: none;
  background: none;
  cursor: pointer;
}

.vzResultImg {
  width: 100%;
  border-radius: var(--radius-md);
  border: 1px solid var(--color-border);
}

.vzPickerOverlay {
  display: none;
  position: fixed;
  inset: 0;
  z-index: 1100;
  background: rgba(0,0,0,.55);
  align-items: center;
  justify-content: center;
  padding: var(--space-4);
}
.vzPickerOverlay.open { display: flex; }

.vzPickerPanel {
  background: var(--color-surface-raised);
  border-radius: var(--radius-lg);
  width: 100%;
  max-width: 480px;
  max-height: 80vh;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  box-shadow: var(--shadow-lg);
}
.vzPickerHead {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: var(--space-4) var(--space-4) var(--space-3);
  border-bottom: 1px solid var(--color-border);
  flex-shrink: 0;
}
.vzPickerTitleText { font-size: var(--text-ui-lg); font-weight: 700; color: var(--color-text-primary); }

.vzPickerGrid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: var(--space-2);
  padding: var(--space-3);
  overflow-y: auto;
}
.vzPickerItem {
  position: relative;
  border: 2px solid transparent;
  border-radius: var(--radius-sm);
  padding: 0;
  cursor: pointer;
  overflow: hidden;
  background: var(--color-surface);
}
.vzPickerItem img { width: 100%; aspect-ratio: 4/3; object-fit: cover; display: block; }
.vzPickerItem.selected { border-color: var(--color-accent); box-shadow: 0 0 0 3px var(--color-accent-subtle); }

/* Print — clean sheet for the visit summary */
@media print {
  .stickyBar, .toolbar, .actions, .loadingOverlay, .modal, .toast, #syncPill { display: none !important; }
  .sheet { padding-bottom: var(--space-6); }
  body.page { background: #fff; }
}

/* ── Tutorial ("?" help) ──────────────────────────────────────────────────────
   Fixed TOP-right by necessity: .stickyBar owns bottom:0 full-width and the
   brainbot bubble owns a bottom corner (right:20px default, left:20px when the
   tenant configures position:'bottom-left'). Top-right is the only corner free
   for every tenant. z-index sits at --z-overlay (100), under .modal
   (--z-modal, 200) and under .visitOpenGate (--z-modal + 10). */
.tutFab {
  position: fixed;
  top: calc(var(--space-4) + env(safe-area-inset-top));
  right: calc(var(--space-4) + env(safe-area-inset-right));
  z-index: var(--z-overlay);
  width: 44px;
  height: 44px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: var(--radius-full);
  border: var(--border-hairline);
  background: var(--color-surface-raised);
  color: var(--color-text-primary);
  font-family: inherit;
  font-size: var(--text-ui-lg);
  font-weight: 600;
  line-height: 1;
  cursor: pointer;
  box-shadow: var(--shadow-lg);
}
.tutFab:hover { background: var(--color-surface); }

/* Tutorial modal content */
.tutGroup { margin-top: var(--space-5); }
.tutGroup:first-child { margin-top: 0; }
.tutGroupTitle {
  font-size: var(--text-ui-xs);
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--color-text-tertiary);
  margin-bottom: var(--space-2);
}
.tutRow {
  display: flex;
  gap: var(--space-3);
  align-items: flex-start;
  padding: var(--space-3) 0;
  border-top: var(--border-hairline);
}
/* First row of each group has the group title above it, not a rule. */
.tutGroupTitle + .tutRow { border-top: none; }
.tutIcon {
  flex: 0 0 28px;
  font-size: var(--text-ui-xl);
  line-height: 1.2;
  text-align: center;
}
.tutName {
  font-size: var(--text-ui-md);
  font-weight: 600;
  color: var(--color-text-primary);
}
.tutDesc {
  font-size: var(--text-ui-sm);
  color: var(--color-text-secondary);
  margin-top: 2px;
}

/* Fly-back-to-the-button close. JS sets --fly-x/--fly-y from
   getBoundingClientRect() as the vector from the card's centre to the "?"
   button's centre; scale() is centre-origin, so the shrinking card lands on
   the button. Only ever applied to #tutorialCard. */
.modalCard--fly {
  animation: none; /* cancel vModalIn so it cannot fight the fly */
  transition: transform 0.26s cubic-bezier(0.4, 0, 1, 1), opacity 0.26s ease-in;
  transform: translate(var(--fly-x, 0px), var(--fly-y, 0px)) scale(0.05);
  transform-origin: center center;
  opacity: 0;
}

/* First reduced-motion handling in this file. Scoped to the tutorial so it
   does not silently change every other modal's entrance. */
@media (prefers-reduced-motion: reduce) {
  #tutorialCard { animation: none; }
  .modalCard--fly { transition: opacity 0.12s linear; transform: none; }
}

/* ── Favorite heart ───────────────────────────────────────────────────────── */
.favBtn {
  border: var(--border-hairline);
  background: var(--color-surface-raised);
  color: var(--color-text-tertiary);
  border-radius: var(--radius-full);
  width: 36px;
  height: 36px;
  font-family: inherit;
  font-size: var(--text-ui-lg);
  line-height: 1;
  cursor: pointer;
}
.favBtn[aria-pressed="true"] { color: var(--color-danger); border-color: var(--color-danger); }
.favBtn:disabled { opacity: .45; cursor: default; }

/* ── Room chips (multi-room) ──────────────────────────────────────────────── */
.roomChips { display: flex; flex-wrap: wrap; gap: var(--space-2); margin-bottom: var(--space-2); }
.roomChip--editable { display: inline-flex; align-items: center; gap: var(--space-1); }
.roomChip__x {
  border: none;
  background: transparent;
  color: inherit;
  font-family: inherit;
  font-size: var(--text-ui-xs);
  cursor: pointer;
  padding: 0 2px;
}

/* ── Repeat-visit project picker (repeat_confirm) ─────────────────────────────
   Shown only when we found previous SPS projects for the customer's EXACT
   contact. "+ New project" is preselected — see the template comment for why. */
.projPick { display: flex; flex-direction: column; gap: var(--space-2); }
.projOpt {
  display: flex;
  align-items: flex-start;
  gap: var(--space-3);
  padding: var(--space-3);
  border: var(--border-hairline);
  border-radius: var(--radius-lg);
  background: var(--color-surface-raised);
  cursor: pointer;
}
.projOpt:hover { background: var(--color-surface); }
.projOpt:has(input:checked) { border-color: var(--color-accent); }
.projOpt input { margin-top: 3px; flex: 0 0 auto; }
.projOpt__body { display: flex; flex-direction: column; min-width: 0; }
.projOpt__name {
  font-size: var(--text-ui-md);
  font-weight: 600;
  color: var(--color-text-primary);
}
.projOpt__meta {
  font-size: var(--text-ui-sm);
  color: var(--color-text-secondary);
  margin-top: 2px;
}

/* The [hidden] attribute is only `display:none` from the UA stylesheet, so ANY
   component `display:` rule silently beats it — .sb-field sets `display:flex`, which
   left a "hidden" field fully visible on screen while el.hidden reported true. Restore
   the attribute's meaning for the design-system field wrapper. Specificity 0,2,0 beats
   .sb-field's 0,1,0, so no !important is needed. */
.sb-field[hidden] { display: none; }
