/* Meandr Tier 0 — a calm, inviting wayfinding UI for a voice/text local tour guide.
   Priorities: large readable text (outdoor mobile use), high contrast, big touch targets,
   minimal chrome. No framework, no build step.

   Brand idea — "meandr": wandering, getting pleasantly lost, serendipitous discovery.
   Direction "DUSK WANDER": a twilight-INDIGO primary (calm, trustworthy — the evening sky
   you wander a new city under) with a warm sunset-CORAL accent (the spark of discovery, the
   place you arrive at) on soft dusk-haze neutrals. The signature motif is the meandering
   ROUTE — a winding line toward a destination — not a compass. See DESIGN-SYSTEM.md.

   Authored with the visual-designer method: hierarchy first, 60-30-10 colour (haze 60 /
   indigo 30 / coral 10), 8-point spacing, a 1.25 modular type scale, WCAG 2.1 AA throughout. */

:root {
  /* ============================================================================
     CONVERSATION LAYER — legacy alias names kept (app.js + the rules below reference
     them) but re-pointed at the Meandr brand tokens, so the whole Tier 0 app speaks
     ONE visual language. The guide view stays large-text, high-contrast and calm.
     ============================================================================ */
  --bg: var(--haze);                   /* soft dusk-haze field                     */
  --surface: var(--surface-1);         /* white                                    */
  --ink: var(--ink-strong);            /* near-black ink (15:1 on haze)            */
  --ink-soft: var(--ink-soft-tok);     /* secondary text (9.3:1 on white)          */
  --me-bg: var(--me-bubble);           /* visitor's words: warm coral mist         */
  --me-ink: var(--me-bubble-ink);      /* ≥14:1 on coral mist                      */
  --them-bg: var(--guide-bubble);      /* the guide's voice: soft indigo mist      */
  --them-ink: var(--guide-bubble-ink); /* ≥14:1 on indigo mist                     */
  --accent: var(--primary);            /* INDIGO primary — actions, listening dot  */
  --accent-ink: var(--on-primary);     /* white (6.3:1 on accent)                  */
  --accent-strong: var(--primary-strong);
  --warn: var(--notice);               /* wayfinding/help notice (5.0:1 on white)  */
  --warn-bg: #fdf0db;                  /* soft amber notice fill                    */
  --line: var(--line-soft);            /* decorative hairline (dividers)           */
  --line-strong: var(--line-control);  /* visible control borders (3.7:1)          */
  --focus: var(--focus-ring);          /* INDIGO focus (7.9:1 on white)            */
  font-size: 22px;          /* base — everything scales from here */

  /* ============================================================================
     MEANDR DESIGN SYSTEM — shared brand tokens (whole Tier 0 web app). Single source
     of truth for BOTH surfaces: the admin/config screens (sign-in gate + settings)
     AND the visitor conversation view, whose alias names above re-point here.
     All pairings verified for WCAG 2.1 AA — ratios noted per token.
     ============================================================================ */

  /* --- Brand: INDIGO tonal scale (the twilight sky over a new city) --- */
  --indigo-50:  #eef0fe;   /* tints, guide bubble, halo wash               */
  --indigo-100: #e0e3fc;   /* soft fills, focus glow                       */
  --indigo-200: #c4c9f8;   /* borders on tinted surfaces                   */
  --indigo-300: #9aa2f0;   /* decorative only (2.5:1 — not for text)       */
  --indigo-400: #6f78ea;   /* decorative / large non-text (3.3:1)          */
  --indigo-500: #5b54e0;   /* large text / UI on white    (4.9:1)          */
  --indigo-600: #4f46e5;   /* PRIMARY — buttons, brand    (6.29:1)         */
  --indigo-700: #4338ca;   /* primary hover, links, focus (7.91:1)         */
  --indigo-800: #312e81;   /* headings on light           (11.4:1)         */
  --indigo-900: #1e1b4b;   /* deepest ink / shadow tint   (15.8:1)         */

  /* --- Accent: CORAL tonal scale (the sunset, the destination you reach) --- */
  --coral-100: #ffe9e3;   /* soft warm fills, visitor bubble               */
  --coral-200: #ffc9bb;   /* tinted borders                                */
  --coral-300: #ff9f86;   /* decorative / large non-text (2.4:1)           */
  --coral-400: #fb7a59;   /* pin / icon accent, large    (3.0:1)           */
  --coral-500: #e64a32;   /* large text / icon on white  (3.9:1)           */
  --coral-600: #cc3a2f;   /* accent text/icon on white   (5.01:1)          */
  --coral-700: #a82d24;   /* accent hover                (6.9:1)           */

  /* --- Semantic roles (admin / shared) --- */
  --primary:        var(--indigo-600);
  --primary-strong: var(--indigo-700);
  --primary-soft:   var(--indigo-100);
  --primary-tint:   var(--indigo-50);
  --on-primary:     #ffffff;            /* 6.29:1 on --primary             */
  --brand-heading:  var(--indigo-800);
  --brand-link:     var(--indigo-700);
  --accent-brand:   var(--coral-600);   /* 10% warm accent (pins, badges)  */
  --accent-brand-strong: var(--coral-700);

  /* --- Dusk-haze neutrals --- */
  --haze:         #f3f3fb;              /* shared soft dusk-haze field      */
  --surface-1:    #ffffff;
  --surface-2:    #f8f8fe;              /* faint cool white                 */
  --ink-strong:   #1c1b2e;             /* near-black ink   (15.8:1)         */
  --ink-soft-tok: #45455c;             /* secondary text   (9.35:1)         */
  --ink-muted:    #59596f;             /* hints on white   (6.84:1)         */
  --line-soft:    #e4e4f0;             /* hairline (card edge, decorative)  */
  --line-control: #82839c;             /* input borders   (3.69:1 — passes 1.4.11) */

  /* --- Semantic status (all AA on white; each hue distinct from brand) --- */
  --ok:     #1f7a52;   /* green  5.3:1  */
  --notice: #8a5a12;   /* amber  5.0:1 — caution, NOT the coral accent */
  --danger: #b3261e;   /* red    6.5:1  */

  /* --- Typography ---
     Pairing: a confident humanist SANS for the wordmark, headings, body & UI (modern,
     friendly, app-native, zero network cost via the system stack), with an editorial
     SERIF reserved ONLY for place names on POI cards — so a recommended place reads with
     a distinct, atlas-like character. Contrast through weight & scale, not decoration. */
  --font-ui: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  --font-brand: var(--font-ui);   /* wordmark + headings: same sans, set heavy & tight */
  --font-place: "Iowan Old Style", "Palatino Linotype", Palatino, Georgia, "Times New Roman", serif;
  --fs-xs: 0.8rem;   --fs-sm: 0.95rem; --fs-md: 1.05rem;
  --fs-lg: 1.3rem;   --fs-xl: 1.6rem;  --fs-2xl: 2rem;
  --lh-tight: 1.2;   --lh-body: 1.5;
  --fw-regular: 400; --fw-medium: 600; --fw-bold: 700; --fw-black: 800;
  --tracking-brand: -0.01em;       /* tight tracking gives the sans wordmark its identity */

  /* --- Spacing scale (8-point grid; 4px sub-grid for fine offsets) --- */
  --space-1: 0.25rem; --space-2: 0.5rem; --space-3: 0.75rem;
  --space-4: 1rem;    --space-5: 1.5rem; --space-6: 2rem;

  /* --- Radius (soft, rounded — winding rather than sharp) --- */
  --radius-sm: 10px; --radius-md: 14px; --radius-lg: 18px;
  --radius-xl: 24px; --radius-pill: 999px;

  /* --- Elevation (soft, indigo-tinted — rgba of --indigo-900 = 30,27,75) --- */
  --elev-1: 0 1px 2px rgba(30,27,75,0.06), 0 2px 6px rgba(30,27,75,0.06);
  --elev-2: 0 4px 14px rgba(30,27,75,0.10);
  --elev-3: 0 14px 40px rgba(30,27,75,0.18);

  /* --- Focus + motion --- */
  --focus-ring: var(--indigo-700);     /* 7.91:1 — well above 3:1         */
  --ease: cubic-bezier(0.2, 0.7, 0.2, 1);
  --dur: 160ms;

  /* ============================================================================
     CONVERSATION-VIEW TUNING — the visitor view is the SAME Meandr brand as the
     config surface, tuned for at-a-glance use on a phone outdoors: bigger type,
     generous spacing, gentle motion, high contrast, low clutter. All pairings AA.
     The two voices split across the brand: the GUIDE speaks in calm indigo, YOU
     answer in warm coral.
     ============================================================================ */
  --guide-bubble:        var(--indigo-50);   /* the guide's voice — soft indigo mist */
  --guide-bubble-ink:    var(--ink-strong);  /* ≥14:1 on indigo mist               */
  --me-bubble:           var(--coral-100);   /* visitor's words — warm coral mist   */
  --me-bubble-ink:       var(--ink-strong);  /* ≥14:1 on coral mist                 */
  --companion-accent:        var(--indigo-600);/* listening dot, primary actions    */
  --companion-accent-strong: var(--indigo-700);/* hover / active                    */
  --companion-ink-soft:  var(--ink-soft-tok);
  /* Indigo glow used by the ambient listening pulse (rgba of --indigo-600). */
  --companion-pulse: 79, 70, 229;

  /* --- Admin alias names (kept for the config surface rules below) --- */
  --admin-bg:        var(--haze);
  --admin-surface:   var(--surface-1);
  --admin-surface-2: var(--surface-2);
  --admin-ink:       var(--ink-strong);
  --admin-ink-soft:  var(--ink-soft-tok);
  --admin-ink-muted: var(--ink-muted);
  --admin-line:      var(--line-soft);
  --admin-line-2:    var(--line-control);
}

* { box-sizing: border-box; }

/* Author-level hide: beats the layout `display` set on flex elements (.voice-indicator, .actions
   children) so the `hidden` attribute reliably hides the mode-driven controls. */
[hidden] { display: none !important; }

html, body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--font-ui);
  line-height: 1.5;
}

body {
  min-height: 100vh;
  display: flex;
  flex-direction: column;
}

.visually-hidden {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

.skip {
  position: absolute; left: -999px; top: 0;
  background: var(--accent); color: var(--accent-ink);
  padding: 0.6rem 1rem; z-index: 10; border-radius: 0 0 8px 0;
}
.skip:focus { left: 0; }

/* ---- Top bar ---- */
.topbar {
  display: flex; align-items: center; justify-content: space-between;
  gap: 1rem; padding: 0.9rem 1.2rem;
  background: var(--surface); border-bottom: 2px solid var(--line);
}
/* Brand: the Meandr route mark beside the wordmark. Decorative (aria-hidden) —
   it carries the wayfinding feel, not information. */
.topbar-brand { display: flex; align-items: center; gap: var(--space-3); min-width: 0; }
.brand-mark { width: 40px; height: 40px; flex: 0 0 auto; display: block; }
.title { margin: 0; font-family: var(--font-brand); font-size: 1.7rem; font-weight: var(--fw-black);
  letter-spacing: var(--tracking-brand); color: var(--brand-heading);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.icon-btn {
  font-size: 1.05rem; padding: 0.7rem 1.1rem;
  min-height: 56px; border: 2px solid var(--line-strong); border-radius: var(--radius-md);
  background: var(--surface); color: var(--ink-soft); cursor: pointer;
  transition: background var(--dur) var(--ease), border-color var(--dur) var(--ease), color var(--dur) var(--ease);
}
.icon-btn:hover { background: var(--primary-tint); border-color: var(--primary); color: var(--primary-strong); }
.icon-btn:focus-visible { outline: 4px solid var(--focus); outline-offset: 3px; }

/* ---- Conversation stage ---- */
.stage {
  flex: 1; width: 100%; max-width: 820px; margin: 0 auto;
  padding: 1.2rem; display: flex; flex-direction: column; gap: 1rem;
}

.transcript {
  flex: 1; min-height: 40vh; overflow-y: auto;
  display: flex; flex-direction: column; gap: 1rem;
  padding: 0.4rem;
}

.hint { color: var(--ink-soft); font-size: 1.2rem; text-align: center; margin: auto;
  max-width: 36ch; line-height: var(--lh-body); }

.bubble {
  max-width: 90%; padding: 1rem 1.2rem; border-radius: var(--radius-lg);
  font-size: 1.35rem; line-height: var(--lh-body);
  white-space: pre-wrap; word-wrap: break-word;
  box-shadow: var(--elev-1);
}
/* Speaker label: explicit soft-ink color (not opacity) so it stays AA on both
   the indigo-mist and coral-mist bubble fills. */
.bubble .who { display: block; font-size: 0.85rem; font-weight: 700;
  text-transform: uppercase; letter-spacing: 0.6px;
  color: var(--companion-ink-soft); margin-bottom: 0.25rem; }

.from-them { align-self: flex-start; background: var(--them-bg); color: var(--them-ink);
  border-bottom-left-radius: var(--radius-sm); }
.from-me { align-self: flex-end; background: var(--me-bg); color: var(--me-ink);
  border-bottom-right-radius: var(--radius-sm); }

/* Safety/help notice — a calm, distinct AMBER card (semantic --notice, neither the indigo
   brand nor the coral accent), so a caution can never be mistaken for a normal reply. */
.bubble.safety {
  align-self: stretch; max-width: 100%;
  background: var(--warn-bg); color: var(--warn);
  border: 2px solid var(--warn); border-radius: var(--radius-md);
  box-shadow: none;
}
.bubble.safety .who { color: var(--warn); }

/* ---- POI / recommendation card ----
   Component style for a place the guide points you to ("off the beaten path near you").
   Available for server/markup-rendered recommendations; the warm CORAL pin marks the
   destination so a place visually reads differently from the guide's prose. Anatomy:
   title (serif place name), meta row (coral marker), body (body ink). Left coral rule =
   the wayfinding marker; the round ◆ marker echoes the route's destination dot. */
.poi-card {
  align-self: flex-start; max-width: 90%;
  background: var(--surface); color: var(--ink);
  border: 1px solid var(--line);
  border-left: 4px solid var(--accent-brand);
  border-radius: var(--radius-md);
  box-shadow: var(--elev-1);
  padding: var(--space-4) var(--space-5);
  display: flex; flex-direction: column; gap: var(--space-2);
}
.poi-card .poi-title {
  margin: 0; font-family: var(--font-place); font-size: var(--fs-lg);
  line-height: var(--lh-tight); font-weight: var(--fw-bold); color: var(--brand-heading);
}
.poi-card .poi-meta {
  display: inline-flex; align-items: center; gap: var(--space-2);
  font-size: var(--fs-sm); font-weight: var(--fw-medium); color: var(--accent-brand);
}
.poi-card .poi-meta::before { content: "●"; font-size: 0.7em; line-height: 1; }
.poi-card .poi-body { margin: 0; font-size: var(--fs-md); line-height: var(--lh-body); color: var(--ink); }

.status { min-height: 1.6rem; color: var(--ink-soft); font-size: 1.05rem; text-align: center; }
.status.error { color: var(--danger); font-weight: 700; }

/* ---- Composer (the always-available text box) ---- */
.composer { display: flex; gap: 0.7rem; align-items: stretch; flex-wrap: wrap; }

.text-input {
  flex: 1 1 60%; min-width: 12ch;
  font-size: 1.4rem; padding: 1rem 1.1rem;
  border: 3px solid var(--line-strong); border-radius: var(--radius-md);
  background: var(--surface); color: var(--ink);
  transition: border-color var(--dur) var(--ease), box-shadow var(--dur) var(--ease);
}
.text-input::placeholder { color: var(--admin-ink-muted); }
.text-input:focus { outline: 4px solid var(--focus); outline-offset: 2px;
  border-color: var(--primary); box-shadow: 0 0 0 3px var(--primary-soft); }

.btn {
  font-size: 1.3rem; font-weight: 700; cursor: pointer;
  min-height: 64px; padding: 0.8rem 1.4rem;
  border-radius: var(--radius-md); border: 3px solid transparent;
}
.btn:focus-visible { outline: 4px solid var(--focus); outline-offset: 3px; }

.btn-send { background: var(--accent); color: var(--accent-ink); }
.btn-send:not([disabled]):hover { background: var(--accent-strong); }
/* Tap-to-talk (voice mode): a calm indigo-outlined button that fills in while recording an utterance. */
.btn-mic { background: var(--surface); color: var(--accent); border-color: var(--accent);
  flex: 1; min-height: 72px; font-size: 1.5rem; }
.btn-mic:not([disabled]):hover { background: var(--primary-tint); }
.btn-mic[aria-pressed="true"] { background: var(--accent); color: var(--accent-ink); border-color: var(--accent); }
.btn-mic[aria-pressed="true"]:not([disabled]):hover { background: var(--accent-strong); }
.btn-ghost { background: var(--surface); color: var(--ink); border-color: var(--line-strong); }
.btn-ghost:hover { background: var(--primary-tint); border-color: var(--primary); }

.btn[disabled] { opacity: 0.5; cursor: not-allowed; }

.actions { display: flex; gap: 0.7rem; }

/* ---- Mode toggle: TEXT ⇄ VOICE (segmented control) ----
   A clearly visible, easy-to-switch pair. The active segment fills with brand indigo; AA is
   --accent-ink on --accent (6.3:1) when active, and --ink-soft on the white track (9.3:1) when not. */
.mode-toggle {
  display: inline-flex; align-self: center; gap: 0;
  background: var(--surface); border: 2px solid var(--line-strong);
  border-radius: var(--radius-pill); padding: 4px; box-shadow: var(--elev-1);
}
.seg-btn {
  font-size: 1.15rem; font-weight: var(--fw-bold); cursor: pointer;
  min-height: 52px; padding: 0.5rem 1.6rem;
  border: none; background: transparent; color: var(--ink-soft);
  border-radius: var(--radius-pill);
  transition: background var(--dur) var(--ease), color var(--dur) var(--ease);
}
.seg-btn:hover { color: var(--primary-strong); }
.seg-btn[aria-pressed="true"] { background: var(--accent); color: var(--accent-ink); }
.seg-btn[aria-pressed="true"]:hover { background: var(--accent-strong); color: var(--accent-ink); }
.seg-btn:focus-visible { outline: 4px solid var(--focus); outline-offset: 3px; }
@media (prefers-reduced-motion: reduce) { .seg-btn { transition: none; } }

.mic-note {
  margin: 0; padding: 0.8rem 1rem; font-size: 1.05rem;
  color: var(--ink-soft); background: var(--surface);
  border: 2px dashed var(--line); border-radius: 12px;
}

/* ---- Settings dialog (admin/config management surface) ---- */
.settings {
  border: none; border-radius: var(--radius-xl); padding: 0; max-width: 560px; width: 92%;
  background: var(--admin-surface); color: var(--admin-ink); box-shadow: var(--elev-3);
}
.settings::backdrop { background: rgba(30, 27, 75, 0.45); }
.settings-form { padding: var(--space-6); display: flex; flex-direction: column; gap: var(--space-2); }

/* Header: the route mark beside the title to carry the brand into the panel. */
.settings-head { display: flex; align-items: center; gap: var(--space-3); margin-bottom: var(--space-3); }
.settings-head .logo-mark { width: 40px; height: 40px; }
.settings-form h2 {
  margin: 0; font-family: var(--font-brand); font-size: var(--fs-xl); line-height: var(--lh-tight);
  font-weight: var(--fw-black); letter-spacing: var(--tracking-brand); color: var(--brand-heading);
}
.settings-form label {
  font-size: var(--fs-md); font-weight: var(--fw-bold); color: var(--admin-ink);
  margin-top: var(--space-4);
}
.field-hint {
  margin: var(--space-1) 0 0; font-size: var(--fs-sm); font-weight: var(--fw-regular);
  color: var(--admin-ink-muted); line-height: var(--lh-body);
}
.settings-form input, .settings-form select {
  font-size: var(--fs-lg); padding: 0.75rem 0.85rem; margin-top: var(--space-2);
  border: 2px solid var(--admin-line-2); border-radius: var(--radius-md);
  background: var(--admin-surface); color: var(--admin-ink);
  transition: border-color var(--dur) var(--ease), box-shadow var(--dur) var(--ease);
}
.settings-form input:focus, .settings-form select:focus {
  outline: none; border-color: var(--primary);
  box-shadow: 0 0 0 3px var(--primary-soft);
}
.settings-actions { display: flex; gap: var(--space-3); margin-top: var(--space-6); }
.settings-actions .btn { flex: 1; }

/* ---- App shell + OPTIONAL traveller sign-in (Clerk) ---- */
/* #app-root holds the whole guide UI; it stays a flex column so the stage layout is unchanged. The
   guide is NEVER hidden behind sign-in — signing in only unlocks the saved profile + itinerary. */
#app-root { flex: 1; display: flex; flex-direction: column; min-height: 0; }

.topbar-actions { display: flex; align-items: center; gap: 0.8rem; }
.user-button { display: inline-flex; align-items: center; min-height: 40px; }
.user-button:empty { display: none; }

/* Auth chrome shows ONLY when Clerk is configured (html.clerk-on). "Sign in" when signed out;
   "My trip" + the Clerk user button once signed in. Default-hidden so the live site (Clerk
   unconfigured) shows no auth controls at all. */
.auth-signin-btn, .auth-account-btn { display: none; }
html.clerk-on.signed-out .auth-signin-btn { display: inline-flex; }
html.clerk-on.signed-in .auth-account-btn { display: inline-flex; }

/* The sign-in + account modals reuse the .settings <dialog> shell; these center the brand header. */
.signin-modal .settings-form, .signin-form { text-align: center; }
.signin-head { display: flex; flex-direction: column; align-items: center; margin-bottom: var(--space-4); }
.signin-mount { display: flex; justify-content: center; min-height: 3rem; }
.account-subhead {
  margin: var(--space-6) 0 var(--space-2); font-family: var(--font-brand);
  font-size: var(--fs-lg); color: var(--brand-heading); font-weight: var(--fw-bold);
  letter-spacing: var(--tracking-brand);
  border-top: 1px solid var(--line); padding-top: var(--space-4);
}

/* Saved itinerary list inside the "My trip" modal. */
.itin-list { list-style: none; margin: var(--space-2) 0; padding: 0; display: flex; flex-direction: column; gap: var(--space-2); }
.itin-empty { color: var(--ink-muted); font-size: var(--fs-sm); }
.itin-item {
  display: flex; align-items: center; justify-content: space-between; gap: var(--space-3);
  background: var(--surface-2); border: 1px solid var(--line);
  border-radius: var(--radius-md); padding: var(--space-2) var(--space-3);
}
.itin-label { font-size: var(--fs-sm); color: var(--ink); }
.itin-remove { flex: 0 0 auto; min-height: 36px; padding: 0 var(--space-3); font-size: var(--fs-xs); }
.itin-add { display: flex; gap: var(--space-2); margin-top: var(--space-3); }
.itin-add input { flex: 1; }

/* Logo + halo. The route mark rests on a faint indigo wash so it reads as a crafted brand
   tile and the edge stays gentle against the card. */
.logo-halo {
  width: 116px; height: 116px; margin: 0 auto var(--space-4);
  display: grid; place-items: center; border-radius: var(--radius-pill);
  background: radial-gradient(closest-side, var(--indigo-50) 0%, rgba(238,240,254,0.55) 62%, rgba(238,240,254,0) 100%);
}
.logo-mark { width: 76px; height: 76px; display: block; }

.auth-title {
  margin: 0 0 var(--space-2); font-family: var(--font-brand); font-size: var(--fs-xl);
  line-height: var(--lh-tight); font-weight: var(--fw-black); color: var(--brand-heading);
  letter-spacing: var(--tracking-brand);
}
.auth-sub { margin: 0 0 var(--space-5); color: var(--admin-ink-soft); font-size: var(--fs-md); }
#sign-in { display: flex; justify-content: center; }

/* Quiet reassurance line — clarifies that sign-in is optional. */
.auth-foot {
  margin: var(--space-5) 0 0; padding-top: var(--space-4);
  border-top: 1px solid var(--admin-line);
  color: var(--admin-ink-muted); font-size: var(--fs-sm); line-height: var(--lh-body);
}
.auth-error { color: var(--danger); font-weight: var(--fw-bold); }

/* Best-effort cosmetic theming for the Clerk-mounted widget (purely visual; the gate
   works regardless of whether these .cl-* hooks match the loaded Clerk version). */
#sign-in .cl-formButtonPrimary { background: var(--primary); }
#sign-in .cl-formButtonPrimary:hover { background: var(--primary-strong); }
#sign-in a, #sign-in .cl-footerActionLink { color: var(--brand-link); }

/* ---- Primary action button (admin surfaces) ---- */
.btn-primary {
  background: var(--primary); color: var(--on-primary); border-color: transparent;
  transition: background var(--dur) var(--ease);
}
.btn-primary:hover { background: var(--primary-strong); }
/* White gap + indigo ring stays visible on both the button and the page. */
.btn-primary:focus-visible {
  outline: none;
  box-shadow: 0 0 0 3px var(--admin-surface), 0 0 0 6px var(--focus-ring);
}

/* Respect users who prefer less motion. */
@media (prefers-reduced-motion: reduce) {
  * { scroll-behavior: auto !important; }
  .btn-primary, .settings-form input, .settings-form select,
  .icon-btn, .text-input { transition: none; }
}

/* ---- Voice-mode status pill (tap-to-talk state) ----
   Reflects the live tap-to-talk state: a soft pulsing dot + a plain-language label. */
.voice-indicator {
  display: flex; align-items: center; gap: 0.7rem;
  padding: 0.7rem 1.1rem; border-radius: var(--radius-pill);
  background: var(--primary-tint); border: 2px solid var(--indigo-200);
  color: var(--companion-ink-soft); font-size: 1.15rem; font-weight: var(--fw-medium);
  align-self: center;
}
.voice-indicator .vi-dot {
  width: 16px; height: 16px; border-radius: 50%;
  background: var(--accent); flex: 0 0 auto;
}
/* Listening (resting): the dot breathes gently in brand indigo. */
.voice-indicator[data-state="listening"] {
  border-color: var(--accent); color: var(--accent-strong);
}
.voice-indicator[data-state="listening"] .vi-dot {
  animation: vi-pulse 1.8s var(--ease) infinite;
}
/* Speaking: invite interruption (this is the stop-and-listen state). */
.voice-indicator[data-state="speaking"] { border-color: var(--accent); color: var(--accent-strong); }
.voice-indicator[data-state="speaking"] .vi-dot { animation: vi-pulse 1.1s var(--ease) infinite; }
/* Thinking: steady, no pulse — a calm, muted dot. */
.voice-indicator[data-state="thinking"] .vi-dot { background: var(--companion-ink-soft); animation: none; }
/* Muted / inactive: the mic is NOT yet live for the session. Grayed dot, muted text, neutral
   border, no pulse: it must clearly read as NOT listening.
   AA: text #45455c ≥ 9.3:1 on the near-white fill; border passes 1.4.11 (non-text). */
.voice-indicator[data-state="muted"] {
  background: var(--admin-surface-2);
  border-color: var(--admin-line-2);
  color: var(--companion-ink-soft);
}
.voice-indicator[data-state="muted"] .vi-dot {
  background: var(--admin-ink-muted); animation: none; opacity: 0.85;
}

@keyframes vi-pulse {
  0%   { box-shadow: 0 0 0 0 rgba(var(--companion-pulse), 0.45); }
  70%  { box-shadow: 0 0 0 12px rgba(var(--companion-pulse), 0); }
  100% { box-shadow: 0 0 0 0 rgba(var(--companion-pulse), 0); }
}
@media (prefers-reduced-motion: reduce) {
  .voice-indicator .vi-dot { animation: none !important; }
}

/* ---- SHARE LOCATION control ----
   An explicit, opt-in card to share GPS or type a Milan area so the guide knows what's near you.
   Calm indigo brand; the live sharing dot uses the coral accent (the "destination" you've reached).
   All pairings AA: status/note text on the soft card, indigo-filled primary action. */
.location {
  display: flex; flex-direction: column; gap: var(--space-3);
  align-self: stretch; width: 100%;
  background: var(--surface); border: 2px solid var(--line-strong);
  border-radius: var(--radius-lg); box-shadow: var(--elev-1);
  padding: var(--space-3) var(--space-4);
}

/* Status line — ON/OFF + the resolved area name. */
.loc-status { display: flex; align-items: center; gap: var(--space-3); min-width: 0; }
.loc-status .loc-dot {
  width: 14px; height: 14px; flex: 0 0 auto; border-radius: 50%;
  background: var(--admin-ink-muted); opacity: 0.85;        /* OFF: a muted, clearly-not-live dot */
}
.loc-status .loc-text { font-size: 1.1rem; font-weight: var(--fw-medium); color: var(--ink-soft);
  overflow: hidden; text-overflow: ellipsis; }
/* ON: a warm coral "you're here" dot that breathes gently; bolder ink for the live state. */
.loc-status[data-sharing="on"] .loc-dot { background: var(--accent-brand); opacity: 1;
  animation: loc-pulse 2s var(--ease) infinite; }
.loc-status[data-sharing="on"] .loc-text { color: var(--ink); }

@keyframes loc-pulse {
  0%   { box-shadow: 0 0 0 0 rgba(204, 58, 47, 0.4); }
  70%  { box-shadow: 0 0 0 10px rgba(204, 58, 47, 0); }
  100% { box-shadow: 0 0 0 0 rgba(204, 58, 47, 0); }
}
@media (prefers-reduced-motion: reduce) { .loc-status .loc-dot { animation: none !important; } }

/* Action row — compact controls (smaller than the big composer buttons). */
.loc-actions { display: flex; flex-wrap: wrap; gap: var(--space-2); }
.loc-actions .btn { min-height: 52px; font-size: 1.1rem; padding: 0.6rem 1.2rem; }
/* Primary share action: indigo-filled, like Send. */
.btn-loc { background: var(--accent); color: var(--accent-ink); border-color: transparent; }
.btn-loc:not([disabled]):hover { background: var(--accent-strong); }

/* Manual fallback form: input + Set on one row, hint below. */
.loc-manual { display: flex; flex-wrap: wrap; gap: var(--space-2); align-items: stretch; }
.loc-manual .text-input { flex: 1 1 60%; min-width: 12ch; font-size: 1.2rem; padding: 0.7rem 0.9rem; }
.loc-manual .btn-send { min-height: 52px; font-size: 1.1rem; padding: 0.6rem 1.2rem; }
.loc-manual .field-hint { flex-basis: 100%; margin: 0; color: var(--ink-muted); }

/* Note line — friendly denial / nearest-spot message. Neutral by default, danger on error. */
.loc-note { margin: 0; font-size: 1rem; color: var(--ink-soft); line-height: var(--lh-body); }
.loc-note.error { color: var(--danger); font-weight: var(--fw-bold); }

@media (max-width: 520px) {
  .loc-actions .btn { flex: 1 1 100%; }
  .loc-manual .text-input { flex-basis: 100%; }
  .loc-manual .btn-send { flex: 1 1 100%; }
}

/* ---- Degraded voice (mobile / no live STT): make the TEXT BOX the obvious primary input ---- */
/* When live speech-to-text isn't available, testers on phones must still see typing front-and-centre.
   Emphasize the input, give Send full weight, and let the mic note read as a clear instruction. */
.voice-degraded .text-input {
  flex-basis: 100%;
  font-size: 1.5rem;
  border-width: 3px; border-color: var(--accent);
  box-shadow: 0 0 0 3px rgba(var(--companion-pulse), 0.14);
}
.voice-degraded .composer { gap: 0.6rem; }
.voice-degraded .btn-send { flex: 1 1 100%; min-height: 68px; font-size: 1.4rem; }
.voice-degraded .mic-note {
  border-style: solid; border-color: var(--accent);
  color: var(--ink); background: var(--surface); font-weight: 600;
}

/* Larger phones / small screens: stack the composer. */
@media (max-width: 520px) {
  :root { font-size: 20px; }
  .text-input { flex-basis: 100%; }
  .btn-send { flex: 1; }
}

/* ---- Admin ⇄ Visitor mode gate ----
   VISITOR mode is the default and unlocked; admin controls are hidden until a correct PIN unlocks
   admin for this session only. The mode button itself is the gate and stays visible/keyboard-reachable
   so an operator can unlock; everything marked .admin-only is revealed only in admin mode. */
.admin-only { display: none; }
body.admin-mode .admin-only { display: inline-flex; }

/* In admin mode the gate reads as an active, lit control (so the operator can see they're in admin
   and exit). AA: --on-primary on --primary is 6.29:1. */
body.admin-mode .mode-btn {
  background: var(--primary); color: var(--on-primary); border-color: var(--primary);
}
body.admin-mode .mode-btn:hover { background: var(--primary-strong); border-color: var(--primary-strong); }

/* ---- Setup wizard + PIN modal ---- (reuse the .settings dialog shell + brand tokens) */
.settings textarea {
  font-size: var(--fs-lg); padding: 0.75rem 0.85rem; margin-top: var(--space-2);
  border: 2px solid var(--admin-line-2); border-radius: var(--radius-md);
  background: var(--admin-surface); color: var(--admin-ink);
  font-family: inherit; line-height: var(--lh-body); resize: vertical; width: 100%;
  transition: border-color var(--dur) var(--ease), box-shadow var(--dur) var(--ease);
}
.settings textarea:focus {
  outline: none; border-color: var(--primary); box-shadow: 0 0 0 3px var(--primary-soft);
}
.setup-progress { margin-top: 0; font-weight: var(--fw-medium); color: var(--admin-ink-soft); }
.setup-step { display: flex; flex-direction: column; }
.setup-intake-lead { margin-top: 0; }

/* Guided intake conversation (setup): a compact chat inside the wizard. Reuses the
   conversation bubble styles but sized for the dialog. */
.intake-log {
  margin-top: var(--space-3);
  max-height: 38vh; min-height: 8rem; overflow-y: auto;
  display: flex; flex-direction: column; gap: var(--space-3);
  padding: var(--space-3);
  background: var(--admin-surface-2); border: 1px solid var(--admin-line); border-radius: var(--radius-md);
}
.intake-log .bubble { max-width: 100%; font-size: var(--fs-md); padding: 0.7rem 0.9rem; box-shadow: none; }
.intake-log:empty { display: none; }
.intake-input-row { display: flex; gap: var(--space-2); align-items: stretch; margin-top: var(--space-3); }
.intake-input-row .text-input { flex: 1 1 auto; font-size: var(--fs-md); margin-top: 0; }
.intake-send { flex: 0 0 auto; min-height: 0; }
/* Errors/alerts in setup + PIN: semantic danger (6.5:1 on white), never brand indigo/coral. */
.setup-err { color: var(--danger); font-weight: var(--fw-bold); }
.pin-modal { max-width: 420px; }

@media (prefers-reduced-motion: reduce) {
  .settings textarea { transition: none; }
}
