:root {
  /* Hasi design system — light theme. Calmer, more restrained surface
     language than the previous pass: less rounded, less glow, a real type
     scale, and shadows that read as "quiet elevation" rather than "floating
     card." Kept the existing indigo brand accent (it's Hasi's own identity,
     not being replaced) — every other token was reconsidered. */
  --bg: #ffffff;
  --card: #ffffff;
  --card-solid: #ffffff;
  --ink: #1a1c2e;
  --muted: #6b6d80;
  --accent: #2879f5;
  --accent2: #5b9bff;
  --accent3: #34d399;
  --accent4: #22d3ee;
  --accent-dark: #1a5bd1;
  --danger: #d7372c;
  --danger-bg: rgba(215,55,44,0.08);
  --ok-bg: rgba(22,163,74,0.1);
  --ok: #16a34a;
  --warning: #b45309;
  --warning-bg: rgba(180,83,9,0.09);
  --info: #2879f5;
  --info-bg: rgba(40,121,245,0.08);
  --border: #e3e6f5;
  --border-strong: #cdd2ee;
  --pill-bg: #eef0fb;

  /* Radius scale — used deliberately, not uniformly: controls (buttons,
     inputs, chips) get a moderate, confident radius; surfaces (cards,
     modals) get a slightly larger one; true pills are reserved for status
     badges/tags, not primary actions. */
  --radius-xs: 8px;
  --radius-sm: 10px;
  --radius: 14px;
  --radius-lg: 18px;
  --radius-pill: 999px;

  /* Quiet elevation — a hairline border does most of the separation work;
     shadow is a soft, neutral proximity cue, not a colored glow. */
  --shadow-xs: 0 1px 2px rgba(20,22,35,0.04);
  --shadow: 0 1px 2px rgba(20,22,35,0.04), 0 6px 16px rgba(20,22,35,0.06);
  --shadow-lg: 0 2px 6px rgba(20,22,35,0.06), 0 16px 32px rgba(20,22,35,0.10);
  --glass-blur: none;
  --font-serif: "Archivo", -apple-system, BlinkMacSystemFont, sans-serif;
  --font-mono: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
  --grad-vivid: linear-gradient(135deg, var(--accent2), var(--accent));
  --pill-active-bg: var(--accent);
  --pill-active-ink: #ffffff;
  --ease: cubic-bezier(0.22, 1, 0.36, 1);
  --ease-spring: cubic-bezier(0.34, 1.4, 0.64, 1);
  --sp-1: 4px; --sp-2: 8px; --sp-3: 12px; --sp-4: 16px; --sp-5: 24px; --sp-6: 32px;

  /* Type scale — every heading/body/meta size in the app should trace back
     to one of these, not a one-off px value chosen per component. */
  --text-xs: 11.5px;   /* captions, timestamps, fine print */
  --text-sm: 13px;     /* secondary text, helper text, metadata */
  --text-base: 15px;   /* body */
  --text-md: 17px;     /* emphasized body, list-row primary text */
  --text-lg: 20px;     /* section titles (.card h2) */
  --text-xl: 26px;     /* page titles */
  --text-display: 32px;/* rare — the auth screen's own heading only */
}

:root[data-theme="dark"] {
  /* Dark theme — same restrained language, deep indigo/navy canvas. */
  --bg: #0b0c16;
  --card: #171925;
  --card-solid: #171925;
  --ink: #f1f2fa;
  --muted: #9497ad;
  --accent: #4f95ff;
  --accent2: #7db8ff;
  --accent3: #34d399;
  --accent-dark: #2879f5;
  --danger: #f0685f;
  --danger-bg: rgba(240,104,95,0.14);
  --ok-bg: rgba(52,211,153,0.14);
  --ok: #34d399;
  --warning: #e0a458;
  --warning-bg: rgba(224,164,88,0.14);
  --info: #7db8ff;
  --info-bg: rgba(125,184,255,0.12);
  --border: #262838;
  --border-strong: #34374a;
  --pill-bg: #1e2030;
  --shadow-xs: 0 1px 2px rgba(0,0,0,0.3);
  --shadow: 0 1px 2px rgba(0,0,0,0.28), 0 6px 16px rgba(0,0,0,0.32);
  --shadow-lg: 0 2px 6px rgba(0,0,0,0.32), 0 16px 32px rgba(0,0,0,0.42);
  --glass-blur: none;
  --grad-vivid: linear-gradient(135deg, var(--accent2), var(--accent));
  --pill-active-bg: var(--accent);
  --pill-active-ink: #ffffff;
}

/* Colorway (Settings → Appearance) — swaps the accent branding across the
   whole app, including the Customer kiosk screen, so the orb and its glow
   always match whatever colorway/theme the owner picked. "blue" is the
   default and needs no override block since it's just the theme's own
   --accent values. */
/* Every top-level surface the app actually renders into — #appRoot's
   descendants inherit through the normal DOM tree, but #employeePopup,
   #confirmModal, #onboardingScreen, and #liveLockOverlay are SIBLINGS of
   #appRoot (see index.html), not descendants of it, so an override scoped
   only to #appRoot never reaches them — they'd silently fall back to the
   default blue --accent regardless of the colorway chosen. Every real
   colorway-bearing surface must be listed explicitly here; this was the
   actual cause of "parts of the product stay blue in Pink/Black & White." */
html[data-colorway="pink"] #appRoot,
html[data-colorway="pink"] #helpModal,
html[data-colorway="pink"] #authScreen,
html[data-colorway="pink"] #customerScreen,
html[data-colorway="pink"] #employeePopup,
html[data-colorway="pink"] #employeeFab,
html[data-colorway="pink"] #confirmModal,
html[data-colorway="pink"] #onboardingScreen,
html[data-colorway="pink"] #liveLockOverlay {
  --accent: #ec4899;
  --accent2: #f472b6;
  --accent3: #34d399;
  --grad-vivid: linear-gradient(135deg, var(--accent2), var(--accent));
  /* --pill-active-bg (primary button/CTA background) is declared as
     var(--accent) only at :root — a custom property's var() reference
     resolves at its OWN declaration's matched element, not lazily at every
     descendant, so that :root declaration bakes in the default blue
     permanently and never re-resolves against a colorway override further
     down the tree. Re-declaring it here (same pattern as --grad-vivid
     above) is the fix — found live during onboarding theme verification:
     every primary "Continue"/"Start using Hasi" button stayed hardcoded
     blue in Pink even though progress dots and links correctly went pink. */
  --pill-active-bg: var(--accent);
}

/* Crisp true black/white — not the theme's softened ink/muted grays, which
   read as dull for a "black & white" mode. Flat (start=end) gradient so
   buttons render as solid black/white instead of a blended gray. */
html[data-colorway="mono"] #appRoot,
html[data-colorway="mono"] #helpModal,
html[data-colorway="mono"] #authScreen,
html[data-colorway="mono"] #customerScreen,
html[data-colorway="mono"] #employeePopup,
html[data-colorway="mono"] #employeeFab,
html[data-colorway="mono"] #confirmModal,
html[data-colorway="mono"] #onboardingScreen,
html[data-colorway="mono"] #liveLockOverlay {
  --accent: #000000;
  --accent2: #000000;
  --accent3: #000000;
  --grad-vivid: linear-gradient(135deg, #000000, #000000);
  --pill-active-bg: var(--accent);
}
html[data-theme="dark"][data-colorway="mono"] #appRoot,
html[data-theme="dark"][data-colorway="mono"] #helpModal,
html[data-theme="dark"][data-colorway="mono"] #authScreen,
html[data-theme="dark"][data-colorway="mono"] #customerScreen,
html[data-theme="dark"][data-colorway="mono"] #employeePopup,
html[data-theme="dark"][data-colorway="mono"] #employeeFab,
html[data-theme="dark"][data-colorway="mono"] #confirmModal,
html[data-theme="dark"][data-colorway="mono"] #onboardingScreen,
html[data-theme="dark"][data-colorway="mono"] #liveLockOverlay {
  --accent: #ffffff;
  --accent2: #ffffff;
  --accent3: #ffffff;
  --grad-vivid: linear-gradient(135deg, #ffffff, #ffffff);
  --pill-active-bg: var(--accent);
  /* the button text color, not overridden by the block above — without this
     a white accent button would render white text on a white background */
  --pill-active-ink: #000000;
}

* { box-sizing: border-box; }

html, body {
  margin: 0;
  height: 100%;
  background: var(--bg);
  color: var(--ink);
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: 0.001ms !important; animation-iteration-count: 1 !important; transition-duration: 0.001ms !important; }
}

.label-mono {
  font-family: var(--font-mono);
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--accent);
  background: color-mix(in srgb, var(--accent) 12%, transparent);
  display: inline-block;
  padding: 4px 11px;
  border-radius: 999px;
  margin-bottom: 10px;
}

/* Soft color blobs behind every glass panel — what the blur actually
   refracts. Quiet and restrained, not a saturated rainbow field. */
body { position: relative; background: var(--bg); }
body::before {
  content: "";
  position: fixed;
  inset: 0;
  z-index: -1;
  background: #ffffff;
}
:root[data-theme="dark"] body::before {
  background: linear-gradient(135deg, #0b0c16 0%, #141726 50%, #0c0e1a 100%);
}

/* Reusable glass surface: blur + saturate whatever color sits behind it,
   plus a faint top highlight so it reads as curved glass, not flat frosting */
.glass {
  backdrop-filter: var(--glass-blur);
  -webkit-backdrop-filter: var(--glass-blur);
}

#appRoot {
  display: flex;
  flex-direction: column;
  height: 100vh;
  height: 100dvh;
}

/* ---- Top bar ---- */
#topbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 20px 22px 8px;
  flex-shrink: 0;
  max-width: 720px;
  width: 100%;
  margin: 0 auto;
}
#topbar .brand {
  font-family: var(--font-serif);
  font-weight: 800;
  font-size: 19px;
  display: flex;
  align-items: center;
  gap: 9px;
  letter-spacing: -0.02em;
  background: var(--grad-vivid);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}
#topbar .brand .dot {
  width: 20px; height: 20px; border-radius: 50%;
  background: var(--grad-vivid);
  box-shadow: 0 0 14px color-mix(in srgb, var(--accent) 30%, transparent);
}
#topbar .biz-name {
  font-size: 13px;
  color: var(--muted);
  font-weight: 600;
}
#themeToggleBtn {
  width: 32px; height: 32px;
  border-radius: 50%;
  border: 1px solid var(--border);
  background: var(--pill-bg);
  backdrop-filter: var(--glass-blur);
  -webkit-backdrop-filter: var(--glass-blur);
  box-shadow: var(--shadow-xs);
  color: var(--ink);
  display: flex; align-items: center; justify-content: center;
  cursor: pointer;
  flex-shrink: 0;
  transition: transform 0.18s var(--ease), border-color 0.18s var(--ease);
}
#themeToggleBtn:hover { transform: translateY(-1px); border-color: var(--border-strong); }
#themeToggleBtn:active { transform: scale(0.92); }
#themeToggleBtn svg { width: 16px; height: 16px; }

/* ---- Hasi AI Employee: floating launcher + popup ----
   Anchored to the main content column's own right edge (720px, same as
   #topbar/#pageContent), not the raw viewport edge — on a wide desktop
   viewport the content column sits centered with large empty margins on
   both sides, so a launcher pinned to the literal viewport edge reads as a
   random floating button disconnected from the app rather than a feature
   of it. max() falls back to a plain 18px inset once the viewport is
   narrower than the content column (effectively everything below ~756px),
   which is also what keeps it comfortably clear of the bottom nav safe
   area on mobile — never stacked on top of it (bottom nav is ~70px tall
   plus its own safe-area inset; 88px clears that with room to spare). */
#employeeFab {
  position: fixed;
  right: max(18px, calc(50vw - 360px + 22px));
  bottom: calc(88px + env(safe-area-inset-bottom));
  width: 52px; height: 52px;
  border-radius: 50%;
  background: var(--card-solid);
  border: 1px solid var(--border);
  box-shadow: var(--shadow-lg);
  display: flex; align-items: center; justify-content: center;
  cursor: pointer;
  z-index: 40;
  transition: transform 0.2s var(--ease-spring);
}
#employeeFab:hover { transform: translateY(-2px) scale(1.03); }
#employeeFab:active { transform: scale(0.94); }
#employeeFab .dot {
  width: 24px; height: 24px; border-radius: 50%;
  background: var(--grad-vivid);
  box-shadow: 0 0 14px color-mix(in srgb, var(--accent) 40%, transparent);
}

#employeePopup {
  position: fixed;
  right: max(18px, calc(50vw - 360px + 22px));
  bottom: calc(150px + env(safe-area-inset-bottom));
  width: min(360px, calc(100vw - 36px));
  height: min(520px, calc(100vh - 220px));
  background: var(--card-solid);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow-lg);
  z-index: 45;
  flex-direction: column;
  overflow: hidden;
  transition: all 0.25s var(--ease-spring);
}
#employeePopup.expanded {
  right: 18px; left: 18px; top: 18px;
  bottom: calc(88px + env(safe-area-inset-bottom));
  width: auto; height: auto;
  max-width: 640px; margin: 0 auto;
}
.employee-header {
  display: flex; align-items: center; justify-content: space-between;
  padding: 14px 16px; border-bottom: 1px solid var(--border); flex: 0 0 auto;
}
.employee-title { font-weight: 800; font-size: 15px; letter-spacing: -0.01em; }
.employee-header-actions { display: flex; gap: 2px; }
.employee-header-actions button {
  width: 30px; height: 30px; border-radius: 50%; border: none; background: none;
  color: var(--muted); display: flex; align-items: center; justify-content: center; cursor: pointer;
}
.employee-header-actions button:hover { background: var(--pill-bg); color: var(--ink); }
.employee-header-actions svg { width: 16px; height: 16px; }

.employee-mode-toggle {
  display: flex; gap: 4px; padding: 8px 14px; flex: 0 0 auto;
}
.employee-mode-toggle button {
  flex: 1; padding: 7px 0; border-radius: 999px; border: none;
  background: var(--pill-bg); color: var(--muted); font-size: 12px; font-weight: 700; cursor: pointer;
}
.employee-mode-toggle button.active { background: var(--pill-active-bg); color: var(--pill-active-ink); }

.employee-log { flex: 1 1 auto; overflow-y: auto; padding: 10px 14px; display: flex; flex-direction: column; gap: 8px; }
/* Real chat-bubble alignment/coloring, scoped to the popup only — reuses
   the shared .transcript-msg block (also used by Live's own conversation
   view) rather than a parallel bubble system, but the popup is a live chat
   surface (send a message, watch a reply arrive) where side+color carry
   who's-speaking on their own, unlike Live's read-only transcript log
   where the "You"/"Hasi" label pulls real weight — so only here is the
   label hidden and the two roles pulled to opposite sides. */
#employeePopup .transcript-msg { max-width: 84%; margin-bottom: 0; }
#employeePopup .transcript-msg .role { display: none; }
#employeePopup .transcript-msg.user { align-self: flex-end; background: var(--pill-active-bg); color: var(--pill-active-ink); border-color: transparent; }
#employeePopup .transcript-msg.assistant { align-self: flex-start; }
/* renderMarkdownLite()'s only structural output besides <strong>/<br> — kept
   tight so a short bullet list doesn't blow out a narrow chat bubble with
   default browser list indent/spacing. */
#employeePopup .transcript-msg ul { margin: 4px 0; padding-left: 18px; }
#employeePopup .transcript-msg li { margin-bottom: 2px; }
.employee-input-row { display: flex; gap: 8px; padding: 10px 14px; flex: 0 0 auto; }
.employee-input-row input { flex: 1; margin: 0; }
#employeePopup .status-text { padding: 0 14px 10px; }

/* Completed trace — a real record of what Hasi actually did this turn,
   distinct from the transient "Working…" state (which uses
   .employee-working below) so a finished action never still reads as
   in-progress once the reply lands. */
.employee-trace {
  display: flex; flex-direction: column; gap: 3px; margin: -4px 0 10px;
  font-size: 11.5px; color: var(--muted); font-weight: 600;
}
.employee-trace span { display: flex; align-items: center; gap: 6px; }
.employee-trace span::before { content: "✓"; color: var(--ok); font-weight: 800; font-size: 10px; }

/* Working state — Hasi is doing something right now. Three-dot pulse
   instead of static text so "still working" is visually obvious even at a
   glance, without a decorative spinner graphic. */
.employee-working { display: inline-flex; align-items: center; gap: 6px; }
.employee-working .dots { display: inline-flex; gap: 3px; }
.employee-working .dots span {
  width: 4px; height: 4px; border-radius: 50%; background: var(--muted);
  animation: employee-working-pulse 1.1s ease-in-out infinite;
}
.employee-working .dots span:nth-child(2) { animation-delay: 0.15s; }
.employee-working .dots span:nth-child(3) { animation-delay: 0.3s; }
@keyframes employee-working-pulse { 0%, 60%, 100% { opacity: 0.3; } 30% { opacity: 1; } }
@media (prefers-reduced-motion: reduce) {
  .employee-working .dots span { animation: none; opacity: 0.6; }
}

/* A failed turn — display-only, not persisted to history (a request that
   never reached the server has nothing to persist), so it reads as "Hasi
   couldn't finish that" rather than silently vanishing once the status line
   clears. */
.transcript-msg.error-state { background: var(--danger-bg); border-left: 3px solid var(--danger); }
.transcript-msg.error-state .role { color: var(--danger); }

.employee-voice-area {
  flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 6px; padding: 20px;
}
.employee-voice-orb {
  width: 90px; height: 90px; border-radius: 50%;
  background: var(--grad-vivid);
  box-shadow: 0 0 30px color-mix(in srgb, var(--accent) 25%, transparent);
  transition: transform 0.3s var(--ease-spring), box-shadow 0.3s;
  cursor: pointer;
  margin-bottom: 10px;
}
.employee-voice-orb:hover { transform: scale(1.04); }
.employee-voice-orb:active { transform: scale(0.96); }
.employee-voice-orb.active { transform: scale(1.1); box-shadow: 0 0 46px color-mix(in srgb, var(--accent) 45%, transparent); animation: employeeOrbPulse 1.6s ease-in-out infinite; }
.employee-voice-orb.active:hover { transform: scale(1.1); }
@keyframes employeeOrbPulse {
  0%, 100% { transform: scale(1.08); }
  50% { transform: scale(1.16); }
}
#employeeVoiceHint {
  font-size: 18px; font-weight: 800; letter-spacing: -0.01em;
  font-family: var(--font-serif); color: var(--ink);
}
#employeeVoiceSubhint { opacity: 0.6; font-size: 12px; font-weight: 500; }

/* Compact visual-card variant inside the narrow employee popup */
.employee-log .visual-card, #employeeVoiceCard .visual-card {
  margin: 6px 0 12px; box-shadow: none; border-color: var(--border);
}
#employeeVoiceCard { margin-top: 14px; max-height: 240px; overflow-y: auto; }
.employee-log .visual-card-item img, #employeeVoiceCard .visual-card-item img { width: 48px; height: 48px; }
#helpModal {
  position: fixed;
  inset: 0;
  background: rgba(20,20,22,0.35);
  backdrop-filter: blur(4px);
  -webkit-backdrop-filter: blur(4px);
  z-index: 60;
  display: flex;
  align-items: flex-end;
  justify-content: center;
  animation: overlay-in 0.25s var(--ease);
}
@keyframes overlay-in { from { opacity: 0; } to { opacity: 1; } }
:root[data-theme="dark"] #helpModal { background: rgba(0,0,0,0.5); }
#helpModal .sheet {
  background: var(--card);
  border: none;
  border-radius: 24px 24px 0 0;
  box-shadow: var(--shadow-lg);
  padding: 24px 22px calc(22px + env(safe-area-inset-bottom));
  width: 100%;
  max-width: 480px;
  max-height: 80vh;
  overflow-y: auto;
  animation: sheet-in 0.32s var(--ease);
}
@keyframes sheet-in { from { transform: translateY(24px); opacity: 0; } to { transform: translateY(0); opacity: 1; } }
#helpModal .sheet h2 { margin: 0 0 12px; font-size: 19px; font-family: var(--font-serif); font-weight: 800; letter-spacing: -0.01em; }
#helpModal .help-item { margin-bottom: 14px; }
#helpModal .help-item .t { font-weight: 700; font-size: 14px; margin-bottom: 2px; }
#helpModal .help-item .d { font-size: 13px; color: var(--muted); line-height: 1.5; }
#helpModal .close-btn {
  margin-top: 8px;
  width: 100%;
  padding: 12px;
  border-radius: 999px;
  border: 1px solid var(--border);
  background: var(--pill-bg);
  color: var(--ink);
  font-weight: 700;
  cursor: pointer;
  transition: background 0.15s var(--ease);
}
#helpModal .close-btn:hover { background: var(--border); }

/* ---- Confirm modal (yes/no for destructive actions) ---- */
#confirmModal {
  position: fixed;
  inset: 0;
  background: rgba(20,20,22,0.4);
  backdrop-filter: blur(4px);
  -webkit-backdrop-filter: blur(4px);
  z-index: 65;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 20px;
  animation: overlay-in 0.2s var(--ease);
}
:root[data-theme="dark"] #confirmModal { background: rgba(0,0,0,0.55); }
#confirmModal .sheet {
  background: var(--card);
  border: none;
  border-radius: 22px;
  box-shadow: var(--shadow-lg);
  padding: 24px 22px;
  width: 100%;
  max-width: 380px;
  animation: sheet-in 0.25s var(--ease);
  text-align: center;
}
#confirmModal h2 { margin: 0 0 8px; font-size: 17px; font-family: var(--font-serif); font-weight: 800; }
#confirmModal p { margin: 0 0 18px; font-size: 13px; color: var(--muted); line-height: 1.5; }
#confirmModal .confirm-row { display: flex; gap: 10px; }
#confirmModal .confirm-row .btn { flex: 1; margin-top: 0; }

/* ---- Live page ---- */
.live-empty {
  text-align: center;
  padding: 60px 20px;
  color: var(--muted);
}
.live-empty .pulse-dot {
  width: 10px; height: 10px; border-radius: 50%;
  background: var(--muted);
  margin: 0 auto 14px;
  animation: live-blink 1.6s ease-in-out infinite;
}
.live-card {
  border: 1px solid transparent;
}
.live-card.escalated-flash {
  border-color: var(--danger);
  animation: flash-border 1.1s ease-in-out 3;
}
@keyframes flash-border {
  0%, 100% { box-shadow: var(--shadow); }
  50% { box-shadow: 0 0 0 3px rgba(215,55,44,0.18), var(--shadow); }
}
.live-header {
  display: flex; align-items: center; justify-content: space-between;
  margin-bottom: 10px;
}
.live-status {
  display: flex; align-items: center; gap: 7px;
  font-size: 12px; font-weight: 700; color: var(--muted);
  text-transform: uppercase; letter-spacing: 0.04em;
}
.live-status .dot {
  width: 7px; height: 7px; border-radius: 50%;
  background: var(--ok);
  animation: live-blink 1.6s ease-in-out infinite;
}
@keyframes live-blink { 0%,100% { opacity: 1; } 50% { opacity: 0.35; } }
.live-feed {
  max-height: 260px;
  overflow-y: auto;
  margin-top: 10px;
}
.live-customer {
  display: flex; align-items: baseline; justify-content: space-between; gap: 8px;
  margin-bottom: 8px;
}
.live-customer-name { font-family: var(--font-serif); font-weight: 800; font-size: var(--text-md); }
.live-customer-reason { font-size: 11.5px; color: var(--muted); font-weight: 600; text-transform: uppercase; letter-spacing: 0.03em; }

/* ---- Segmented control (Live / Recent) ---- */
.segmented {
  display: flex;
  gap: 3px;
  background: var(--pill-bg);
  backdrop-filter: var(--glass-blur);
  -webkit-backdrop-filter: var(--glass-blur);
  border: 1px solid var(--border);
  box-shadow: var(--shadow-xs);
  border-radius: 999px;
  padding: 3px;
  margin-bottom: 16px;
}
.segmented button {
  flex: 1;
  padding: 8px 12px;
  border: none;
  background: transparent;
  color: var(--muted);
  font-size: 13px;
  font-weight: 700;
  border-radius: 999px;
  cursor: pointer;
  transition: background 0.18s var(--ease), color 0.18s var(--ease), transform 0.18s var(--ease-spring);
}
.segmented button.active {
  color: var(--pill-active-ink);
  background: var(--grad-vivid);
  box-shadow: 0 4px 14px color-mix(in srgb, var(--accent) 32%, transparent);
  transform: scale(1.02);
}

/* ---- Main content ---- */
#pageContent {
  flex: 1;
  overflow-y: auto;
  padding: 10px 20px 20px;
  max-width: 720px;
  width: 100%;
  margin: 0 auto;
}
#pageContent.page-fade { animation: page-in 0.28s var(--ease); }
@keyframes page-in { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: translateY(0); } }

/* ---- Bottom nav — a real tab bar anchored to the edge, not a floating
   pill dock. Active state reads as "this is where you are" (a top accent
   rule + filled icon + accent text) rather than a big gradient blob
   chasing your thumb. Calmer, and reads as a fixed piece of the product
   chrome rather than a decorative overlay. ---- */
/* Shares the exact max-width/centering of #topbar and #pageContent (see
   the min-width:1024px bump below) — all three are one app shell now,
   rather than a centered content column with a full-bleed nav bar
   underneath it that visually reads as two different surfaces. */
#bottomNav {
  display: flex;
  background: var(--card);
  border-top: 1px solid var(--border);
  flex-shrink: 0;
  max-width: 720px;
  width: 100%;
  margin: 0 auto;
  padding: 6px 6px calc(6px + env(safe-area-inset-bottom));
  gap: 2px;
}
#bottomNav a {
  position: relative;
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  padding: 9px 4px 7px;
  text-decoration: none;
  color: var(--muted);
  font-size: var(--text-xs);
  font-weight: 700;
  border-radius: var(--radius-xs);
  transition: color 0.15s var(--ease), background 0.15s var(--ease);
}
#bottomNav a svg { width: 21px; height: 21px; stroke-width: 2; transition: stroke-width 0.15s var(--ease); }
#bottomNav a.active {
  color: var(--accent);
}
#bottomNav a.active svg { stroke-width: 2.4; }
#bottomNav a.active::before {
  content: "";
  position: absolute; top: -6px; left: 50%; transform: translateX(-50%);
  width: 20px; height: 3px; border-radius: 0 0 3px 3px;
  background: var(--accent);
}
#bottomNav a:hover { color: var(--ink); background: var(--pill-bg); }
#bottomNav a.active:hover { color: var(--accent); }
#bottomNav a:active { background: var(--pill-bg); }
#bottomNav a:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }

/* ---- Cards — a grouping surface, not the default container for
   everything. Used deliberately (see .list-row for dense/scannable
   content instead). No hover-lift by default: a card only implies
   interactivity when it's actually a link (a.card), and even then the
   affordance is a quiet border/shadow shift, not a float+glow. No
   per-card entrance choreography either — one calm page-level fade
   (#pageContent.page-fade) is enough; staggering every card's animation
   read as busy rather than premium. ---- */
.card {
  background: var(--card);
  border-radius: var(--radius-lg);
  border: 1px solid var(--border);
  box-shadow: var(--shadow-xs);
  padding: 24px;
  margin-bottom: var(--sp-4);
}
a.card { transition: border-color 0.15s var(--ease), box-shadow 0.15s var(--ease); }
a.card:hover { border-color: var(--border-strong); box-shadow: var(--shadow); }
.card h2 {
  margin: 0 0 6px;
  font-size: var(--text-lg);
  font-weight: 800;
  letter-spacing: -0.02em;
  font-family: var(--font-serif);
}
.card .subtitle {
  color: var(--muted);
  font-size: 14px;
  margin-bottom: 18px;
  line-height: 1.55;
}

/* ---- Skeleton loading state ---- */
.skeleton {
  border-radius: 8px;
  background: linear-gradient(100deg, var(--pill-bg) 30%, var(--border-strong) 50%, var(--pill-bg) 70%);
  background-size: 220% 100%;
  animation: skeleton-shimmer 1.4s ease-in-out infinite;
}
@keyframes skeleton-shimmer { 0% { background-position: 140% 0; } 100% { background-position: -40% 0; } }

/* ---- Settings rows — a simple on/off or single-value control shouldn't
   need a full card with its own heading and subtitle; it should read like a
   real settings row: label, current value, a clear place to tap. ---- */
.settings-row {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: 15px 4px; cursor: pointer;
  border-bottom: 1px solid var(--border);
  transition: background 0.15s var(--ease);
}
.settings-row:last-child { border-bottom: none; }
.settings-row:hover { background: var(--pill-bg); }
.settings-row-label { font-weight: 700; font-size: var(--text-base); }
.settings-row-value { font-size: var(--text-sm); color: var(--muted); margin-top: 2px; }
.settings-row-action { font-size: 13px; font-weight: 700; color: var(--accent); flex-shrink: 0; white-space: nowrap; }

/* ---- Home: page structure ----
   Section headings carry hierarchy so a card isn't the only way to signal
   "this is a group" — lets Needs Attention/Today/Activity read as the
   priority order they are, with the lower-priority setup/plan content
   visually demoted (slightly muted heading, extra top space) so it doesn't
   compete with the first viewport. */
.home-greeting { padding: 4px 2px 18px; }
.home-section { margin-bottom: 22px; }
.home-section-head { display: flex; align-items: center; margin-bottom: 8px; padding: 0 2px; }
.home-section-head h2 {
  font-family: var(--font-mono); font-size: 11px; font-weight: 700;
  letter-spacing: 0.07em; text-transform: uppercase; color: var(--muted);
  margin: 0;
}
.home-section-secondary { margin-top: 30px; padding-top: 22px; border-top: 1px solid var(--border); }
.home-section-secondary .home-section-head h2 { color: var(--muted); }
.home-section-secondary .card + .card { margin-top: 14px; }

/* ---- Profile / stats ---- */
.profile-row {
  display: flex;
  align-items: center;
  gap: 14px;
}
.avatar-ring {
  border-radius: 50%;
  background: var(--grad-vivid);
  padding: 2.5px;
  display: flex; align-items: center; justify-content: center;
  flex-shrink: 0;
}
.avatar {
  width: 66px; height: 66px; border-radius: 50%;
  background: var(--card-solid);
  display: flex; align-items: center; justify-content: center;
  color: var(--ink); font-size: 24px; font-weight: 800;
  flex-shrink: 0;
  overflow: hidden;
  border: 2px solid var(--bg);
}
.avatar img { width: 100%; height: 100%; object-fit: cover; border-radius: 50%; }
.profile-name { font-size: 27px; font-weight: 800; letter-spacing: -0.025em; font-family: var(--font-serif); }
.plan-badge {
  display: inline-block;
  margin-top: 5px;
  padding: 3px 11px;
  border-radius: 999px;
  background: var(--ok-bg);
  color: var(--ok);
  font-size: 12px;
  font-weight: 700;
}

/* ---- Home plan tiles ---- */
/* ---- Plan ladder — a real pricing-tier presentation: consistent card
   shape, a short benefit list per tier (not the full capability catalog),
   one highlighted "most popular" tier to guide the eye, and the current
   tier reading as settled/confirmed rather than just "a selected chip." ---- */
.plan-ladder {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 10px;
  align-items: stretch;
}
.plan-tile {
  position: relative;
  display: flex;
  flex-direction: column;
  border: 1.5px solid var(--border);
  border-radius: var(--radius);
  padding: 18px 14px 14px;
  cursor: pointer;
  background: var(--card);
  transition: border-color 0.15s var(--ease), box-shadow 0.15s var(--ease);
}
.plan-tile:hover { border-color: var(--border-strong); }
.plan-tile:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.plan-tile.recommended { border-color: color-mix(in srgb, var(--accent) 40%, var(--border)); }
.plan-tile.active {
  border-color: var(--accent);
  box-shadow: 0 0 0 2px color-mix(in srgb, var(--accent) 18%, transparent);
}
.plan-tile-flag {
  position: absolute; top: -9px; left: 50%; transform: translateX(-50%);
  background: var(--grad-vivid); color: var(--pill-active-ink);
  font-size: 10px; font-weight: 800; letter-spacing: 0.03em; text-transform: uppercase;
  padding: 3px 10px; border-radius: var(--radius-pill); white-space: nowrap;
}
.plan-tile-top { display: flex; align-items: center; justify-content: center; gap: 6px; margin-bottom: 3px; }
.plan-tile-name { font-family: var(--font-serif); font-weight: 800; font-size: var(--text-md); text-align: center; }
.plan-tile-tagline { font-size: var(--text-xs); color: var(--muted); line-height: 1.4; text-align: center; margin-bottom: 12px; }
.plan-tile-price { font-weight: 700; font-size: var(--text-sm); text-align: center; color: var(--accent); margin-bottom: 10px; }
.plan-tile-bullets { list-style: none; margin: 0 0 14px; padding: 0; flex: 1; }
.plan-tile-bullets li {
  font-size: var(--text-xs); color: var(--ink); line-height: 1.5;
  padding-left: 18px; position: relative; margin-bottom: 6px;
}
.plan-tile-bullets li::before {
  content: "✓"; position: absolute; left: 0; top: 0;
  color: var(--accent); font-weight: 800; font-size: 11px;
}
.plan-tile-cta { margin-top: auto; }
.badge:not(.escalated):not(.ok) { background: var(--pill-bg); color: var(--muted); }

/* ---- Home setup checklist ---- */
.checklist { display: flex; flex-direction: column; gap: 10px; margin-top: 6px; }
.checklist-item {
  display: flex; align-items: center; gap: 10px;
  text-decoration: none;
  color: var(--ink);
  font-size: 13px;
  font-weight: 600;
  transition: opacity 0.15s var(--ease);
}
.checklist-item:hover { opacity: 0.7; }
.checklist-dot {
  width: 19px; height: 19px; border-radius: 50%;
  border: 1.5px solid var(--border-strong);
  flex-shrink: 0;
  display: flex; align-items: center; justify-content: center;
  font-size: 11px; font-weight: 800;
  color: var(--pill-active-ink);
  transition: background 0.2s var(--ease-spring), border-color 0.2s var(--ease);
}
.checklist-item.done { color: var(--muted); text-decoration: line-through; }
.checklist-item.done .checklist-dot { background: var(--ok); border-color: var(--ok); }

.stat-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 10px;
}
.stat-tile {
  background: var(--pill-bg);
  border: 1px solid transparent;
  border-radius: var(--radius-sm);
  padding: 18px 8px;
  text-align: center;
  transition: border-color 0.15s var(--ease);
}
.stat-tile:hover { border-color: var(--border-strong); }
.stat-tile .n {
  font-family: var(--font-serif);
  font-size: 28px; font-weight: 800;
  color: var(--ink);
  letter-spacing: -0.02em;
}
.stat-tile .l {
  font-family: var(--font-mono);
  font-size: 10px; color: var(--muted); margin-top: 4px; font-weight: 600;
  text-transform: uppercase; letter-spacing: 0.06em;
}

/* Full-width primary CTA — same visual language as .btn (radius-sm, quiet
   shadow, no gradient/glow), just block-level for a form's one main action. */
.cta-btn {
  position: relative;
  display: block;
  width: 100%;
  padding: 14px;
  background: var(--pill-active-bg);
  color: var(--pill-active-ink);
  border: 1px solid transparent;
  border-radius: var(--radius-sm);
  font-size: var(--text-base);
  font-weight: 700;
  text-align: center;
  text-decoration: none;
  cursor: pointer;
  box-shadow: var(--shadow-xs);
  transition: background 0.15s var(--ease), box-shadow 0.15s var(--ease), transform 0.1s var(--ease), opacity 0.15s var(--ease);
}
.cta-btn:hover { background: color-mix(in srgb, var(--pill-active-bg) 88%, black 6%); box-shadow: var(--shadow); }
.cta-btn:active { transform: scale(0.99); }
.cta-btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.cta-btn:disabled, .cta-btn[aria-disabled="true"] { opacity: 0.5; cursor: not-allowed; box-shadow: none; }
.cta-btn.loading { color: transparent; pointer-events: none; }
.cta-btn.loading::after {
  content: ""; position: absolute; top: 50%; left: 50%; margin: -8px 0 0 -8px;
  width: 16px; height: 16px;
  border: 2px solid color-mix(in srgb, var(--pill-active-ink) 30%, transparent);
  border-top-color: var(--pill-active-ink); border-radius: 50%;
  animation: btn-spin 0.6s linear infinite;
}

/* ---- Forms ---- */
label { display: block; font-size: 13px; font-weight: 700; margin-bottom: 6px; margin-top: 14px; color: var(--ink); }
input, textarea, select {
  width: 100%;
  padding: 12px 14px;
  border: 1.5px solid var(--border);
  border-radius: var(--radius-sm);
  font-size: var(--text-base);
  font-family: inherit;
  background: var(--card);
  color: var(--ink);
  transition: border-color 0.15s var(--ease), background 0.15s var(--ease), box-shadow 0.15s var(--ease);
}
input::placeholder, textarea::placeholder { color: var(--muted); }
input:focus, textarea:focus, select:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 14%, transparent);
}
textarea { min-height: 180px; resize: vertical; }
/* ---- Buttons — primary / secondary / tertiary / destructive, each with a
   real disabled and loading state. Confident moderate radius, not a pill;
   a single quiet shadow, not a colored glow; hover/active read as a real
   surface responding to touch, not a floating chip. ---- */
.btn {
  position: relative;
  margin-top: 16px;
  padding: 12px 22px;
  background: var(--pill-active-bg);
  color: var(--pill-active-ink);
  border: 1px solid transparent;
  border-radius: var(--radius-sm);
  font-size: var(--text-base);
  font-weight: 700;
  cursor: pointer;
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  transition: background 0.15s var(--ease), border-color 0.15s var(--ease), box-shadow 0.15s var(--ease), transform 0.1s var(--ease), opacity 0.15s var(--ease);
  box-shadow: var(--shadow-xs);
}
.btn:hover { background: color-mix(in srgb, var(--pill-active-bg) 88%, black 6%); box-shadow: var(--shadow); }
.btn:active { transform: scale(0.98); }
.btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.btn.secondary { background: transparent; color: var(--ink); border-color: var(--border-strong); box-shadow: none; }
.btn.secondary:hover { background: var(--pill-bg); border-color: var(--border-strong); }
.btn.tertiary { background: transparent; color: var(--accent); border-color: transparent; box-shadow: none; padding-left: 8px; padding-right: 8px; }
.btn.tertiary:hover { background: var(--info-bg); }
.btn.destructive { background: var(--danger); color: #ffffff; }
.btn.destructive:hover { background: color-mix(in srgb, var(--danger) 88%, black 8%); }
.btn.destructive.secondary { background: transparent; color: var(--danger); border-color: var(--danger-bg); }
.btn.destructive.secondary:hover { background: var(--danger-bg); }
.btn:disabled, .btn[aria-disabled="true"] { opacity: 0.5; cursor: not-allowed; box-shadow: none; transform: none; }
.btn:disabled:hover, .btn[aria-disabled="true"]:hover { background: var(--pill-active-bg); }
.btn.secondary:disabled:hover { background: transparent; }
.btn.loading { color: transparent; pointer-events: none; position: relative; }
.btn.loading::after {
  content: ""; position: absolute; top: 50%; left: 50%; margin: -8px 0 0 -8px;
  width: 16px; height: 16px;
  border: 2px solid color-mix(in srgb, var(--pill-active-ink) 30%, transparent);
  border-top-color: var(--pill-active-ink); border-radius: 50%;
  animation: btn-spin 0.6s linear infinite;
}
.btn.secondary.loading::after { border-color: color-mix(in srgb, var(--ink) 30%, transparent); border-top-color: var(--ink); }
@keyframes btn-spin { to { transform: rotate(360deg); } }
.status-text { margin-left: 10px; font-size: var(--text-sm); color: var(--muted); font-weight: 600; }
.status-text.success { color: var(--ok); animation: badge-pop 0.3s var(--ease-spring); }
.status-text.error { color: var(--danger); }

/* ---- Activity log ---- */
/* ---- List row — the primary pattern for dense/scannable content (recent
   conversations, activity, settings rows) instead of wrapping every item
   in its own card. Hover reads as "this row is interactive" via a real
   surface highlight, not a fade. Negative margin extends the highlight to
   the card's own edges without needing the row to change its own padding. ---- */
.log-item {
  display: flex; justify-content: space-between; align-items: flex-start;
  gap: 10px;
  padding: 13px 8px;
  margin: 0 -8px;
  border-radius: var(--radius-xs);
  border-bottom: 1px solid var(--border);
  cursor: pointer;
  transition: background 0.15s var(--ease);
}
.log-item:hover { background: var(--pill-bg); }
.log-item:last-child { border-bottom: none; }

/* ---- Home: Needs Attention ----
   Severity is shown structurally (left bar + icon-chip tint), not by color
   alone — urgent (escalation/error needs a human now), warning (a connection
   broke), info (a provisional booking or a knowledge gap needs review). */
.attention-list { display: flex; flex-direction: column; max-height: 60vh; overflow-y: auto; }
.attention-item {
  display: flex; align-items: flex-start; gap: 12px;
  padding: 13px 10px 13px 12px;
  margin: 0 -10px;
  border-left: 3px solid var(--border-strong);
  border-radius: 0 var(--radius-xs) var(--radius-xs) 0;
}
.attention-item + .attention-item { margin-top: 6px; }
.attention-item.severity-urgent { border-left-color: var(--danger); background: color-mix(in srgb, var(--danger) 6%, transparent); }
.attention-item.severity-warning { border-left-color: var(--warning); background: color-mix(in srgb, var(--warning) 7%, transparent); }
.attention-item.severity-info { border-left-color: var(--info); background: color-mix(in srgb, var(--info) 6%, transparent); }
.attention-icon {
  font-size: 15px; line-height: 1; flex-shrink: 0;
  width: 26px; height: 26px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  background: var(--pill-bg); margin-top: 1px;
}
.attention-item.severity-urgent .attention-icon { background: color-mix(in srgb, var(--danger) 16%, transparent); }
.attention-item.severity-warning .attention-icon { background: color-mix(in srgb, var(--warning) 18%, transparent); }
.attention-item.severity-info .attention-icon { background: color-mix(in srgb, var(--info) 16%, transparent); }
.attention-body { flex: 1; min-width: 0; }
.attention-what { font-weight: 700; font-size: 14px; }
.attention-why { font-size: 12.5px; color: var(--muted); margin-top: 2px; }
.attention-action { flex-shrink: 0; }

/* Knowledge-gap items read as Hasi asking a question, not a system alert —
   quoted note + a real two-button choice, matching the Teach Hasi modal's
   own actions so "Not now" doesn't require opening it just to dismiss. */
.attention-teach { flex: 1; min-width: 0; }
.attention-teach .attention-what { margin-bottom: 4px; }
.attention-teach blockquote {
  margin: 0 0 10px; padding: 0 0 0 10px;
  border-left: 2px solid var(--border-strong);
  font-size: 13px; font-style: italic; color: var(--ink);
}
.attention-teach .attention-teach-actions { display: flex; gap: 8px; }
.attention-teach .attention-teach-actions .btn { margin-top: 0; width: auto; padding: 7px 14px; font-size: 12.5px; }

#teachHasiAnswer { min-height: 80px; }
.log-time { font-size: 13px; font-weight: 600; }
.log-points { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 7px; }
.point-chip {
  font-size: 11.5px; font-weight: 600; color: var(--muted);
  background: var(--pill-bg);
  padding: 3px 9px; border-radius: var(--radius-xs);
}

/* ---- Home: compact Needs Attention summary (full list moved to a modal —
   see openAttentionModal) ---- */
.attention-summary-count { font-family: var(--font-serif); font-weight: 800; font-size: var(--text-lg); }
.attention-preview { margin-top: 12px; display: flex; flex-direction: column; gap: 7px; }
.attention-preview-item { display: flex; align-items: center; gap: 8px; font-size: 13px; color: var(--muted); }
.attention-preview-item .sev-dot { width: 7px; height: 7px; border-radius: 50%; flex-shrink: 0; }
.attention-preview-item .sev-dot.severity-urgent { background: var(--danger); }
.attention-preview-item .sev-dot.severity-warning { background: var(--warning); }
.attention-preview-item .sev-dot.severity-info { background: var(--info); }
.attention-preview-item span:last-child { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.attention-preview-more { font-size: 12px; color: var(--muted); margin-top: 2px; }

.hasi-work-count { font-family: var(--font-serif); font-weight: 800; font-size: var(--text-xl); line-height: 1; flex-shrink: 0; }
.hasi-work-breakdown { display: flex; flex-wrap: wrap; gap: 4px 10px; margin-top: 4px; font-size: var(--text-sm); color: var(--muted); }

/* ---- Home: Connected business snapshots ---- */
.snapshot-list { display: flex; flex-direction: column; }
.snapshot-row {
  display: flex; align-items: center; gap: 10px;
  padding: 11px 8px; margin: 0 -8px;
  border-radius: var(--radius-xs);
  text-decoration: none; color: inherit;
  transition: background 0.15s var(--ease);
}
.snapshot-row:hover { background: var(--pill-bg); }
.snapshot-icon {
  width: 30px; height: 30px; border-radius: var(--radius-xs);
  background: var(--pill-bg); flex-shrink: 0;
  display: flex; align-items: center; justify-content: center; font-size: 14px;
}
.snapshot-body { flex: 1; min-width: 0; }
.snapshot-label { font-weight: 700; font-size: 13.5px; }
.snapshot-detail { font-size: 12px; color: var(--muted); margin-top: 1px; }
/* ---- Status badges — the one place a true pill shape stays, since it's
   exactly the right shape for a short status tag. Full feedback set:
   success/warning/attention/error/pending, matching the token palette. ---- */
.badge {
  padding: 3px 10px; border-radius: var(--radius-pill); font-size: var(--text-xs); font-weight: 800;
  letter-spacing: 0.01em;
}
.badge.escalated { background: var(--danger-bg); color: var(--danger); animation: badge-pop 0.35s var(--ease-spring); }
.badge.ok { background: var(--ok-bg); color: var(--ok); }
.badge.warning { background: var(--warning-bg); color: var(--warning); }
.badge.pending { background: var(--info-bg); color: var(--info); }
@keyframes badge-pop { from { transform: scale(0.75); opacity: 0; } to { transform: scale(1); opacity: 1; } }
.empty-note { color: var(--muted); font-size: var(--text-sm); padding: 8px 0; line-height: 1.5; }
.recommend-reason {
  background: var(--pill-bg); color: var(--ink); border-radius: var(--radius-sm);
  padding: 12px 14px; font-size: 13px; line-height: 1.5;
}

.transcript-msg { margin-bottom: 10px; padding: 9px 12px; border-radius: var(--radius-sm); font-size: 14px; line-height: 1.4; }
.transcript-msg.user { background: var(--pill-bg); border: 1px solid var(--border); }
.transcript-msg.assistant { background: var(--pill-bg); }
.transcript-msg.flagged { border-left: 3px solid var(--danger); }
.transcript-msg .role { display: block; font-size: 11px; color: var(--muted); margin-bottom: 2px; font-weight: 700; }

/* ---- PIN dot entry (Settings + kiosk lock) ---- */
.pin-entry-wrap { margin-top: 14px; }
.pin-dots {
  display: flex; gap: 16px; justify-content: center;
  margin: 18px 0;
}
.pin-dots .d {
  width: 16px; height: 16px; border-radius: 50%;
  border: 2px solid var(--border-strong);
  transition: all 0.18s var(--ease-spring);
}
.pin-dots .d.filled { background: var(--ink); border-color: var(--ink); }
.pin-dots.dark .d.filled { background: var(--accent); border-color: var(--accent); box-shadow: 0 0 10px color-mix(in srgb, var(--accent) 50%, transparent); }
.pin-pad {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 12px;
  max-width: 260px;
  margin: 0 auto;
}
.pin-pad button {
  aspect-ratio: 1;
  border-radius: 50%;
  border: 1.5px solid var(--border);
  background: var(--pill-bg);
  backdrop-filter: var(--glass-blur);
  -webkit-backdrop-filter: var(--glass-blur);
  color: var(--ink);
  font-size: 19px;
  font-weight: 700;
  cursor: pointer;
  transition: transform 0.12s var(--ease), background 0.12s var(--ease);
}
.pin-pad button:hover { background: var(--border); }
.pin-pad button:active { transform: scale(0.93); }
.pin-pad.dark button { background: rgba(255,255,255,0.08); border-color: rgba(255,255,255,0.18); color: white; }
.pin-pad.dark button:hover { background: rgba(255,255,255,0.14); }
.pin-error { color: var(--danger); text-align: center; font-size: 13px; min-height: 18px; margin-top: 10px; font-weight: 600; }
.pin-error.dark { color: #ff9b9b; }
.pin-success {
  display: flex; align-items: center; gap: 8px;
  color: var(--ok); font-weight: 700; font-size: 14px;
  background: var(--ok-bg); padding: 10px 14px; border-radius: var(--radius-sm); margin-top: 14px;
  animation: badge-pop 0.3s var(--ease-spring);
}

/* ---- Customer / kiosk screen ---- */
/* Tinted with the active colorway's own accent (color-mix, not a fixed
   blue) so this screen matches whatever the owner picked in Settings →
   Appearance, the same as every other screen in the app. */
#customerScreen {
  position: fixed;
  inset: 0;
  background:
    radial-gradient(ellipse 650px 500px at 15% 10%, color-mix(in srgb, var(--accent) 15%, transparent), transparent 60%),
    radial-gradient(ellipse 600px 480px at 90% 20%, color-mix(in srgb, var(--accent2) 14%, transparent), transparent 58%),
    radial-gradient(ellipse 700px 550px at 25% 95%, color-mix(in srgb, var(--accent3) 12%, transparent), transparent 58%),
    #eef1f5;
  color: var(--ink);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  z-index: 50;
}
:root[data-theme="dark"] #customerScreen {
  background:
    radial-gradient(ellipse 600px 500px at 20% 15%, color-mix(in srgb, var(--accent) 40%, transparent), transparent 60%),
    radial-gradient(ellipse 700px 550px at 82% 85%, color-mix(in srgb, var(--accent2) 32%, transparent), transparent 60%),
    radial-gradient(ellipse 900px 700px at 50% 50%, #0d1326 0%, #04060c 75%);
  color: white;
}
#customerScreen .biz-label {
  position: absolute;
  top: max(20px, env(safe-area-inset-top));
  left: 0; right: 0;
  text-align: center;
  font-family: var(--font-mono);
  font-size: 13px;
  opacity: 0.5;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  font-weight: 600;
}
#lockBtn {
  position: absolute;
  top: max(16px, env(safe-area-inset-top));
  right: 16px;
  width: 40px; height: 40px;
  border-radius: 50%;
  background: var(--pill-bg);
  backdrop-filter: var(--glass-blur);
  -webkit-backdrop-filter: var(--glass-blur);
  box-shadow: var(--shadow-xs);
  border: 1px solid var(--border);
  color: var(--ink);
  display: flex; align-items: center; justify-content: center;
  cursor: pointer;
  transition: transform 0.18s var(--ease);
}
#lockBtn:hover { transform: translateY(-1px); }
:root[data-theme="dark"] #lockBtn { background: rgba(255,255,255,0.08); border-color: rgba(255,255,255,0.12); color: white; }

/* Particle-sphere AI orb — the visual centerpiece. A glowing, colorway-
   tinted sphere textured with a fine dot pattern (soft-masked at the edges
   so it reads as a cloud of points rather than a flat disc), with motion
   that communicates real state (idle/listening/thinking/speaking). */
.ai-core {
  position: relative;
  width: 230px; height: 230px;
  display: flex; align-items: center; justify-content: center;
  cursor: pointer;
}
.ai-core .glow {
  position: absolute; inset: -44px;
  border-radius: 50%;
  background: radial-gradient(circle, color-mix(in srgb, var(--accent) 38%, transparent), color-mix(in srgb, var(--accent3) 18%, transparent) 55%, transparent 72%);
  filter: blur(10px);
  transition: opacity 0.4s var(--ease);
  animation: glow-breathe 4.5s ease-in-out infinite;
}
@keyframes glow-breathe {
  0%, 100% { transform: scale(1); }
  50% { transform: scale(1.07); }
}
.ai-core .orb-sphere {
  position: absolute; inset: 0;
  border-radius: 50%;
  overflow: hidden;
  background: radial-gradient(circle at 34% 28%, color-mix(in srgb, var(--accent2) 65%, white) 0%, var(--accent) 55%, var(--accent3) 100%);
  box-shadow: var(--shadow-lg), inset 0 0 26px rgba(255,255,255,0.28);
  transition: transform 0.3s var(--ease);
  z-index: 1;
}
:root[data-theme="dark"] .ai-core .orb-sphere {
  box-shadow: 0 0 60px color-mix(in srgb, var(--accent) 45%, transparent), inset 0 0 22px rgba(255,255,255,0.14);
}
.ai-core .orb-dots {
  position: absolute; inset: -10%;
  background-image: radial-gradient(circle, rgba(255,255,255,0.92) 1.3px, transparent 1.7px);
  background-size: 9px 9px;
  -webkit-mask-image: radial-gradient(circle at 50% 50%, black 0%, black 48%, transparent 74%);
  mask-image: radial-gradient(circle at 50% 50%, black 0%, black 48%, transparent 74%);
  animation: orb-drift 16s linear infinite;
}
@keyframes orb-drift { from { background-position: 0 0; } to { background-position: 90px 60px; } }

.ai-core.idle .glow { opacity: 0.45; }
.ai-core.idle .orb-sphere { transform: scale(0.96); }
.ai-core.idle .orb-dots { animation-duration: 22s; opacity: 0.7; }

.ai-core.listening .glow { opacity: 1; }
.ai-core.listening .orb-sphere { transform: scale(1.05); }
.ai-core.listening .orb-dots { animation-duration: 6s; }

.ai-core.thinking .glow { opacity: 0.85; }
.ai-core.thinking .orb-dots { animation-duration: 2.5s; animation-timing-function: linear; }
.ai-core.thinking .orb-sphere { animation: orb-pulse 1s ease-in-out infinite; }

.ai-core.speaking .glow { opacity: 1; }
.ai-core.speaking .orb-sphere { animation: orb-pulse 0.5s ease-in-out infinite; }
.ai-core.speaking .orb-dots { animation-duration: 4s; }

@keyframes orb-pulse { 0%, 100% { transform: scale(1.02); } 50% { transform: scale(1.08); } }

#custHint {
  margin-top: 32px;
  font-size: 30px;
  font-weight: 800;
  letter-spacing: -0.02em;
  font-family: var(--font-serif);
  color: var(--ink);
}
:root[data-theme="dark"] #custHint {
  background: linear-gradient(135deg, #ffffff, #bae6fd);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}
#custSubhint { margin-top: 8px; opacity: 0.55; font-size: 14px; font-weight: 500; }
#custCaption {
  position: absolute;
  bottom: 56px;
  left: 24px;
  right: 24px;
  font-size: 17px;
  line-height: 1.5;
  min-height: 24px;
}
#custCaption .who { display: block; opacity: 0.5; font-size: 12px; margin-bottom: 4px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.04em; font-family: var(--font-mono); }

/* ---- Dynamic Visual Presentation ---- */
#custVisualCard {
  position: absolute;
  top: 24px;
  left: 24px;
  right: 24px;
  max-width: 480px;
  margin: 0 auto;
  max-height: 40vh;
  overflow-y: auto;
}
.visual-card {
  background: var(--card-solid);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow-lg);
  padding: 16px;
  text-align: left;
}
.visual-card-title { font-weight: 800; font-size: 16px; margin-bottom: 10px; font-family: var(--font-serif); }
.visual-card-items { display: flex; flex-direction: column; gap: 12px; }
.visual-card-item { display: flex; gap: 12px; align-items: flex-start; }
.visual-card-item img { width: 64px; height: 64px; object-fit: cover; border-radius: var(--radius-sm); flex: 0 0 auto; }
.visual-card-item-body { flex: 1; min-width: 0; }
.visual-card-item-name { font-weight: 700; font-size: 14px; }
.visual-card-item-meta { font-size: 12px; color: var(--accent); font-weight: 700; margin-top: 2px; }
.visual-card-item-desc { font-size: 12px; color: var(--muted); margin-top: 2px; }

.unsupported-note {
  max-width: 320px;
  opacity: 0.6;
  font-size: 13px;
  margin-top: 16px;
}

/* ---- Kiosk document-signing overlay ---- */
#signOverlay {
  position: absolute;
  inset: 0;
  z-index: 55;
  align-items: center;
  justify-content: center;
  background: rgba(0,0,0,0.45);
  padding: 24px;
}
.sign-sheet {
  background: var(--card-solid);
  color: var(--ink);
  border-radius: 20px;
  box-shadow: var(--shadow-lg);
  padding: 28px;
  width: 100%;
  max-width: 480px;
  max-height: 85vh;
  display: flex;
  flex-direction: column;
  text-align: left;
}
.sign-sheet h2 { margin: 0 0 12px; font-size: 19px; font-family: var(--font-serif); font-weight: 800; }
.sign-body {
  overflow-y: auto;
  flex: 1;
  min-height: 80px;
  max-height: 260px;
  white-space: pre-wrap;
  font-size: 14px;
  line-height: 1.6;
  color: var(--muted);
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 14px;
  margin-bottom: 14px;
}
.sign-label { font-size: 12px; font-weight: 700; color: var(--muted); margin-bottom: 6px; }
.sign-canvas {
  width: 100%;
  height: 140px;
  border-radius: 12px;
  border: 1.5px dashed var(--border-strong);
  background: #ffffff;
  touch-action: none;
  cursor: crosshair;
}
.sign-actions { display: flex; gap: 10px; margin-top: 16px; }
.sign-actions .btn { flex: 1; }

/* ---- Auth (sign in / sign up) ---- */
#authScreen {
  position: fixed;
  inset: 0;
  background: transparent;
  color: var(--ink);
  display: flex;
  align-items: safe center;
  justify-content: center;
  padding: 20px;
  z-index: 70;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
}
/* `safe center` keeps short forms vertically centered, but falls back to
   start-alignment instead of clipping once content (e.g. the full signup
   form: password rules + two security questions + social buttons) is
   taller than the viewport — the classic "flex-centered overflow is
   unreachable" bug. Real vertical breathing room top and bottom so the
   first/last field never sits flush against the edge when scrolled fully. */
#authScreen .card { margin: 20px 0; }
#authScreen .card { animation: page-in 0.35s var(--ease) backwards; }
.auth-card { padding: 30px 26px; }
.auth-heading {
  margin: 0 0 4px;
  font-family: var(--font-serif);
  font-size: 28px;
  font-weight: 800;
  letter-spacing: -0.02em;
}
.password-field { position: relative; }
.password-field input { padding-right: 42px; }
.password-eye {
  position: absolute;
  top: 50%; right: 6px;
  transform: translateY(-50%);
  width: 30px; height: 30px;
  border: none;
  background: transparent;
  color: var(--muted);
  display: flex; align-items: center; justify-content: center;
  cursor: pointer;
  border-radius: 50%;
}
.password-eye svg { width: 18px; height: 18px; }
.password-eye.active { color: var(--ink); }

.auth-divider {
  display: flex;
  align-items: center;
  gap: 12px;
  margin: 22px 0 16px;
  color: var(--muted);
  font-size: 12px;
  font-weight: 600;
}
.auth-divider::before, .auth-divider::after {
  content: "";
  flex: 1;
  height: 1px;
  background: var(--border);
}

.auth-social-row { display: flex; gap: 10px; align-items: center; }
.auth-social-btn {
  flex: 1;
  display: flex; align-items: center; justify-content: center; gap: 8px;
  margin-top: 0;
}
/* Google's own button can only ever show one of Google's 4 fixed strings
   ("Sign in with Google", etc.) — never Hasi's own wording ("Google",
   "Connect") — so getting BOTH exact Hasi text AND Google's real, reliable
   click handling means layering: a normal, visibly-styled decorative
   button underneath carries the real label, and Google's actual button
   (its own iframe) sits directly on top, sized to match, at near-zero
   opacity — so a real click always lands on Google's real, working button,
   never on a fake one or a `.prompt()` popup with its own failure modes.
   The user never sees two buttons; there is only ever one interactive
   element in this stack. */
.google-btn-wrap { position: relative; flex: 1; display: flex; }
.google-btn-overlay {
  position: absolute;
  inset: 0;
  opacity: 0.01;
  overflow: hidden;
  display: flex;
  align-items: center;
  justify-content: center;
}
/* Only an ACTUALLY unavailable provider (the disabled attribute is only
   ever set when the backend reports it isn't configured) should look
   dimmed/unclickable — a configured, working provider must look exactly
   like any other real button, never like a decorative placeholder. */
.auth-social-btn:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

.auth-switch {
  text-align: center;
  margin-top: 20px;
  font-size: 13px;
  color: var(--muted);
  font-weight: 600;
}
.auth-switch a { color: var(--ink); font-weight: 800; text-decoration: none; margin-left: 4px; }

/* ---- Circular training image thumbnails ---- */
#imageGrid img {
  border-radius: 50% !important;
}

.input-row {
  display: flex;
  gap: 6px;
  flex-wrap: wrap;
}
.input-row input { flex: 1; min-width: 160px; }
.input-row .btn { flex-shrink: 0; }

/* ---- Responsive: small phones ---- */
@media (max-width: 380px) {
  .stat-grid { gap: 8px; }
  .stat-tile { padding: 12px 6px; }
  .stat-tile .n { font-size: 20px; }
  .ai-core { width: 190px; height: 190px; }
  #custHint { font-size: 25px; }
}
/* Plan ladder needs real room for each tier's bullet list — stack well
   before the general phone breakpoint above, rather than squeezing three
   columns of feature text into ~110px each. */
@media (max-width: 560px) {
  .plan-ladder { grid-template-columns: 1fr; gap: 12px; }
  .plan-tile-flag { position: static; transform: none; align-self: center; margin: 0 0 6px; }
  .plan-tile-top { justify-content: center; }
}

/* ---- Responsive: tablets and desktops ---- */
@media (min-width: 720px) {
  #pageContent { padding: 18px 24px 32px; }
  .stat-grid, .plan-ladder { gap: 14px; }
  #bottomNav a { font-size: 12px; }
}
@media (min-width: 1024px) {
  #pageContent { max-width: 780px; }
  #topbar { max-width: 780px; }
  #bottomNav { max-width: 780px; }
  .ai-core { width: 260px; height: 260px; }
  #custHint { font-size: 36px; }
}

/* ---- Admin console: its own full-page operations shell, deliberately
   distinct from the mobile-first customer app (no bottom nav, no customer
   topbar underneath — see render()'s isAdminRoute branch). Reuses theme
   variables throughout, same as the rest of the app, so it follows
   light/dark/colorway the same way the customer product does. ---- */
#pageContent:has(.admin-shell) { max-width: none; padding: 0; }
.admin-shell { display: flex; flex-direction: column; min-height: 100vh; }
.admin-header {
  display: flex; align-items: center; justify-content: space-between; gap: 14px;
  padding: 12px 18px; border-bottom: 1px solid var(--border); background: var(--card-solid);
  flex-wrap: wrap;
}
.admin-header .brand { display: flex; align-items: center; gap: 8px; font-weight: 800; font-size: 15px; }
.admin-header .brand .dot { width: 8px; height: 8px; border-radius: 50%; background: var(--accent); }
.admin-header .brand small { font-weight: 600; color: var(--muted); font-size: 11px; text-transform: uppercase; letter-spacing: .06em; margin-left: 4px; }
.admin-global-search { flex: 1; max-width: 420px; min-width: 160px; position: relative; }
.admin-global-search input { width: 100%; margin: 0; }
.admin-global-results {
  position: absolute; top: calc(100% + 6px); left: 0; right: 0; background: var(--card-solid);
  border: 1px solid var(--border); border-radius: 10px; box-shadow: 0 8px 24px rgba(0,0,0,.18);
  max-height: 340px; overflow-y: auto; z-index: 50;
}
.admin-global-results .grp-label { font-size: 10px; text-transform: uppercase; letter-spacing: .06em; color: var(--muted); padding: 8px 12px 2px; }
.admin-global-results .grp-item { padding: 7px 12px; cursor: pointer; font-size: 13px; }
.admin-global-results .grp-item:hover { background: var(--pill-bg); }
.admin-header .who { font-size: 12.5px; color: var(--muted); white-space: nowrap; }

.admin-shell-body { display: flex; flex-direction: column; flex: 1; }
.admin-sidebar {
  display: flex; overflow-x: auto; gap: 4px; padding: 10px 14px;
  border-bottom: 1px solid var(--border); background: var(--card-solid);
}
.admin-nav-item {
  flex: 0 0 auto; display: inline-flex; align-items: center; gap: 6px;
  padding: 8px 12px; border-radius: 999px; font-size: 13px; font-weight: 700;
  color: var(--muted); text-decoration: none; white-space: nowrap; cursor: pointer;
}
.admin-nav-item.active { background: var(--accent); color: #fff; }
.admin-nav-item .badge-dot { width: 7px; height: 7px; border-radius: 50%; background: var(--danger); }
.admin-content { padding: 16px; }
.admin-search { display: flex; gap: 8px; margin-bottom: 14px; }
.admin-search input { flex: 1; margin: 0; }
.admin-table { width: 100%; border-collapse: collapse; font-size: 13px; }
.admin-table th { text-align: left; color: var(--muted); font-weight: 700; padding: 8px 10px; border-bottom: 1px solid var(--border); white-space: nowrap; }
.admin-table td { padding: 10px; border-bottom: 1px solid var(--border); vertical-align: top; }
.admin-table tr:last-child td { border-bottom: none; }
.admin-table tr.clickable { cursor: pointer; }
.admin-table tr.clickable:hover { background: var(--pill-bg); }
.admin-back-link {
  border: none; background: none; color: var(--muted); font-size: 13px; font-weight: 700;
  cursor: pointer; display: inline-flex; align-items: center; gap: 4px; padding: 0; margin-bottom: 10px;
}

/* Compact "needs attention" summary widget, same idea as the customer Home
   page's compact alert pattern — a count + short preview, not a wall of
   raw problem rows. Expands to the full list on click. */
.admin-attn-widget {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: 14px 16px; border-radius: 12px; cursor: pointer;
  background: var(--pill-bg); border: 1px solid var(--border); margin-bottom: 10px;
}
.admin-attn-widget.zero { opacity: .7; cursor: default; }
.admin-attn-widget .count { font-size: 22px; font-weight: 800; }
.admin-attn-widget .preview { font-size: 12px; color: var(--muted); text-align: right; }

.admin-tabs { display: flex; gap: 4px; overflow-x: auto; border-bottom: 1px solid var(--border); margin-bottom: 14px; }
.admin-tab {
  flex: 0 0 auto; padding: 9px 13px; font-size: 13px; font-weight: 700; color: var(--muted);
  border: none; background: none; cursor: pointer; border-bottom: 2px solid transparent; white-space: nowrap;
}
.admin-tab.active { color: var(--accent); border-bottom-color: var(--accent); }

.admin-health-badge { display: inline-flex; align-items: center; gap: 5px; padding: 3px 9px; border-radius: 999px; font-size: 11px; font-weight: 700; }
.admin-health-badge.healthy { background: var(--pill-bg); color: var(--ok, #2f6b46); }
.admin-health-badge.attention { background: rgba(230,160,40,.15); color: #a56a10; }
.admin-health-badge.degraded { background: rgba(200,60,40,.14); color: var(--danger); }
.admin-health-badge.suspended { background: rgba(120,120,120,.16); color: var(--muted); }

.admin-provider-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: 10px; }
.admin-provider-card {
  border: 1px solid var(--border); border-radius: 12px; padding: 14px; cursor: pointer; background: var(--card-solid);
}
.admin-provider-card:hover { border-color: var(--accent); }
.admin-provider-card .n { font-size: 22px; font-weight: 800; }
.admin-provider-card .l { font-size: 12px; color: var(--muted); margin-top: 2px; }

@media (min-width: 900px) {
  .admin-shell-body { flex-direction: row; }
  .admin-sidebar { flex-direction: column; width: 200px; flex: 0 0 200px; border-bottom: none; border-right: 1px solid var(--border); overflow-x: visible; }
  .admin-content { flex: 1; padding: 22px 26px; min-width: 0; overflow-x: hidden; }
}

/* ---- Onboarding wizard ---- */
#onboardingScreen {
  position: fixed;
  inset: 0;
  background: var(--bg);
  color: var(--ink);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 20px;
  z-index: 70;
  overflow-y: auto;
}
.onboarding-card { max-width: 460px; width: 100%; padding: 30px 26px; animation: page-in 0.35s var(--ease) backwards; }
.onboarding-progress { display: flex; gap: 6px; margin-bottom: 18px; }
.onboarding-dot { flex: 1; height: 4px; border-radius: 2px; background: var(--border); transition: background 0.2s var(--ease); }
.onboarding-dot.active { background: var(--accent); }
.onboarding-dot.done { background: var(--accent2); }
.onboarding-actions { display: flex; align-items: center; justify-content: space-between; margin-top: 20px; gap: 8px; }
.onboarding-capabilities { display: flex; flex-direction: column; gap: 8px; }
.onboarding-capability-chip {
  display: flex; align-items: center; gap: 10px;
  padding: 12px 14px; border-radius: var(--radius-sm); border: 1px solid var(--border);
  cursor: pointer; font-size: 14px; font-weight: 600;
  transition: border-color 0.15s var(--ease), background 0.15s var(--ease);
}
.onboarding-capability-chip:has(input:checked) { border-color: var(--accent); background: var(--pill-bg); }
.onboarding-capability-chip input { width: auto; margin: 0; }
.onboarding-block { margin-bottom: 12px; }
.onboarding-block-title { font-weight: 700; font-size: 14px; margin-bottom: 2px; }

/* Account page section headers + info popovers */
.account-section-title { display: flex; align-items: center; gap: 6px; margin-bottom: 6px; }
.account-section-title h2 { margin-bottom: 0; }
.info-icon-btn {
  display: inline-flex; align-items: center; justify-content: center;
  width: 18px; height: 18px; border-radius: 50%;
  border: 1px solid var(--border); background: none; color: var(--muted);
  font-size: 11px; font-weight: 700; line-height: 1; cursor: pointer; padding: 0; flex-shrink: 0;
}
.info-icon-btn:hover { border-color: var(--accent); color: var(--accent); }
.account-status-pill { font-size: 12px; font-weight: 700; padding: 3px 9px; border-radius: 20px; }
.account-status-pill.connected { background: var(--pill-bg); color: var(--accent); }
.account-status-pill.not-connected { background: var(--border); color: var(--muted); }

/* ---- Account: information architecture ----
   Real grouping (Business / Hasi Knowledge / Hasi Behavior / Customer
   Experience / Connections / Documents / Reference Materials) so the page
   reads as seven focused areas instead of one long scroll of forms. Cards
   and their contents/handlers are untouched — only grouped and given a
   quick-jump entry point. */
.account-jumpnav {
  display: flex; gap: 6px; overflow-x: auto; padding: 2px 2px 14px;
  margin-bottom: 6px; -webkit-overflow-scrolling: touch;
}
.account-jumpnav a {
  flex-shrink: 0; text-decoration: none; color: var(--muted);
  font-size: 12.5px; font-weight: 600; white-space: nowrap;
  padding: 7px 13px; border-radius: var(--radius-pill);
  background: var(--pill-bg); border: 1px solid transparent;
  transition: color 0.15s var(--ease), border-color 0.15s var(--ease);
}
.account-jumpnav a:hover { color: var(--ink); border-color: var(--border-strong); }
.account-group { margin-bottom: 26px; scroll-margin-top: 14px; }
.account-group-head { padding: 0 2px 8px; }
.account-group-head h2 {
  font-family: var(--font-serif); font-size: var(--text-lg); font-weight: 800;
  margin: 0 0 2px;
}
.account-group-head p { margin: 0; font-size: 12.5px; color: var(--muted); }
.account-group .card + .card { margin-top: 14px; }

/* ---- Integrations catalog ---- */
.catalog-cat-row { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 12px; }
.catalog-cat-btn {
  font-family: var(--font-body); font-size: 12.5px; font-weight: 600;
  padding: 7px 13px; border-radius: var(--radius-pill);
  border: 1px solid var(--border); background: var(--card);
  color: var(--muted); cursor: pointer;
  transition: border-color 0.15s var(--ease), color 0.15s var(--ease), background 0.15s var(--ease);
}
.catalog-cat-btn:hover { border-color: var(--border-strong); color: var(--ink); }
.catalog-cat-btn.active { background: var(--accent); border-color: var(--accent); color: var(--pill-active-ink); }
.catalog-group-head {
  font-family: var(--font-mono); font-size: 11px; font-weight: 700;
  letter-spacing: 0.06em; text-transform: uppercase; color: var(--muted);
  margin: 22px 4px 8px;
}
.catalog-group-head:first-child { margin-top: 4px; }

/* Visually hidden but reachable by screen readers/keyboard focus — for
   labels on inputs whose visible placeholder isn't a reliable substitute. */
.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0,0,0,0); white-space: nowrap; border: 0;
}

/* Live page exit-PIN lock — a front-desk device left on Live shouldn't let
   a customer casually wander into account/billing settings. Reuses the
   same .pin-dots/.pin-pad markup and /api/pin/* backend as the kiosk PIN,
   just in its own overlay so leaving Live never disturbs Live's own live
   polling/timers underneath it. */
#liveLockOverlay {
  position: fixed; inset: 0; z-index: 60;
  background: var(--bg);
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  text-align: center; padding: 20px;
}
