/* ==========================================================================
 * Landing Sales Chat — public-website widget
 * Plan 2026-05-17_landing_sales_chat_batches.md, Batch 4.
 *
 * A fully isolated, purely additive overlay mounted ONCE in
 * includes/public_footer.php so it rides every public page. It owns its
 * own `#lsc-root` and every selector is `.lsc-*` (landing-sales-chat) so
 * it can NEVER collide with the onboarding support chat (`.scc-*` /
 * `#scc-root`, which it is deliberately suppressed beside on /onboarding/)
 * nor with the landing WhatsApp FAB (`.wa-fab`) — it coexists with the
 * FAB by sitting as the lowest corner control and lifting the FAB above
 * its launcher (a reversible inline margin the JS owns; public.css /
 * `.wa-fab` stay byte-unchanged). See syncDock in landing-chat.js.
 *
 * Mobile-first (375 → 820 → 1440): bottom sheet on phones, right
 * side-sheet (RTL → left) on tablet/desktop. RTL + locally-hosted Cairo
 * for Arabic, Latin digits (enforced in the JS). Design-token driven so
 * it inherits light/dark from theme_a/tokens.css via the public
 * gz_theme_preference → html[data-theme] pattern; every token also has a
 * safe literal fallback so the widget renders correctly even on a public
 * page that does not ship the token sheet (e.g. the customer portal).
 *
 * The widget boots `hidden` and only reveals itself once the API reports
 * `available:true` — invisible until the owner flips
 * landing_chat_settings.enabled (Batch 7). The agent NEVER flips it.
 * ========================================================================== */

/* Locally-hosted Cairo — re-declared (idempotent with public.css) so the
   widget is self-contained on any public page. No CDN, ever
   (feedback_arabic_cairo_font). */
@font-face {
  font-family: 'Cairo';
  src: url('/assets/fonts/cairo/cairo-400.ttf') format('truetype');
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: 'Cairo';
  src: url('/assets/fonts/cairo/cairo-700.ttf') format('truetype');
  font-weight: 700;
  font-style: normal;
  font-display: swap;
}

#lsc-root.lsc-root {
  position: fixed;
  /* Bottom-end corner. The chat launcher is the LOWEST corner control;
     the widget lifts the WhatsApp FAB above it (see syncDock in
     landing-chat.js) so the visitor reads WhatsApp on top and the chat
     launcher beneath it, never overlapping. The platform cookie banner is
     cleared identically to the FAB.
     2026-05-23 — the lift chain (--lsc-cta-lift JS-measured, fallback to
     body-level --gz-fab-stack-lift mirror, fallback to 0) lives HERE in
     the per-widget file so the cascade actually applies. (When the chain
     lived in _chat_widget_shared.css §2 it was defeated by source order:
     shared loaded first, this rule loaded second with same specificity,
     so this rule won — without the chain — and the FAB landed on the
     sticky CTA every mobile load.) */
  inset-block-end: calc(
    max(16px, env(safe-area-inset-bottom, 0px))
    + var(--ui-cookie-banner-height, 0px)
    + var(--lsc-cta-lift, var(--gz-fab-stack-lift, 0px))
  );
  inset-inline-end: max(16px, env(safe-area-inset-right, 0px));
  z-index: 1200; /* the widget owns its overlays; the FAB sits clear above */
  font-family: var(--font-sans, ui-sans-serif, system-ui, -apple-system,
    "Segoe UI", Roboto, Arial, sans-serif);
}

@media (max-width: 640px) {
  #lsc-root.lsc-root {
    inset-block-end: calc(
      max(18px, env(safe-area-inset-bottom, 0px))
      + var(--ui-cookie-banner-height, 0px)
      + var(--lsc-cta-lift, var(--gz-fab-stack-lift, 0px))
    );
  }
}

html[lang='ar'] #lsc-root.lsc-root,
#lsc-root.lsc-root[dir='rtl'] {
  font-family: 'Cairo', 'Tahoma', 'Arial', sans-serif;
}

#lsc-root.lsc-root[hidden] {
  display: none !important;
}

/* ── Floating launcher ─────────────────────────────────────────────── */

.lsc-launcher {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  max-width: min(78vw, 320px);
  padding: 12px 18px;
  border: 0;
  border-radius: 999px;
  background: var(--primary-strong, #c14a00);
  color: var(--primary-contrast, #ffffff);
  font: inherit;
  font-weight: 700;
  font-size: 0.95rem;
  line-height: 1.2;
  cursor: pointer;
  box-shadow: 0 14px 34px rgba(var(--primary-strong-rgb, 193, 74, 0), 0.42);
  transition: transform 120ms ease, box-shadow 120ms ease;
}

.lsc-launcher:hover {
  transform: translateY(-2px);
  box-shadow: 0 18px 40px rgba(var(--primary-strong-rgb, 193, 74, 0), 0.5);
}

.lsc-launcher:focus-visible {
  outline: none;
  box-shadow: var(--focus-ring, 0 0 0 3px rgba(193, 74, 0, 0.4)),
    0 14px 34px rgba(var(--primary-strong-rgb, 193, 74, 0), 0.42);
}

.lsc-launcher__icon {
  flex: 0 0 auto;
  width: 22px;
  height: 22px;
  display: grid;
  place-items: center;
}

.lsc-launcher__icon svg {
  width: 100%;
  height: 100%;
  display: block;
}

.lsc-launcher__text {
  display: inline-block;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Unread dot: the assistant replied while the sheet was closed. */
.lsc-launcher__badge {
  flex: 0 0 auto;
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: var(--success, #22c55e);
  box-shadow: 0 0 0 3px rgba(var(--success-rgb, 34, 197, 94), 0.35);
  display: none;
}

#lsc-root.lsc-root[data-unread='1'] .lsc-launcher__badge {
  display: inline-block;
}

/* ── Backdrop + sheet ──────────────────────────────────────────────── */

.lsc-backdrop {
  position: fixed;
  inset: 0;
  background: rgba(10, 12, 20, 0.5);
  opacity: 0;
  pointer-events: none;
  transition: opacity 200ms ease;
  z-index: 1200;
}

#lsc-root.lsc-root[data-open='1'] .lsc-backdrop {
  opacity: 1;
  pointer-events: auto;
}

.lsc-sheet {
  position: fixed;
  inset-inline: 0;
  inset-block-end: 0;
  max-height: 92dvh;
  display: flex;
  flex-direction: column;
  background: var(--surface, #ffffff);
  color: var(--text, #0b1220);
  border-start-start-radius: 22px;
  border-start-end-radius: 22px;
  box-shadow: 0 -24px 60px rgba(15, 23, 42, 0.28);
  transform: translateY(102%);
  transition: transform 320ms ease;
  z-index: 1200;
  will-change: transform;
}

#lsc-root.lsc-root[data-open='1'] .lsc-sheet {
  transform: translateY(0);
}

/* ── Sheet header ──────────────────────────────────────────────────── */

.lsc-head {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  padding: 20px 20px 14px;
  border-bottom: 1px solid var(--border, rgba(11, 18, 32, 0.12));
  flex: 0 0 auto;
}

.lsc-head__titles {
  flex: 1 1 auto;
  min-width: 0;
}

.lsc-eyebrow {
  margin: 0 0 4px;
  font-size: 0.74rem;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--primary-on-light, #b34400);
}

.lsc-title {
  margin: 0;
  font-size: 1.2rem;
  font-weight: 800;
  letter-spacing: -0.02em;
  line-height: 1.2;
  color: var(--text-strong, #0b1220);
}

.lsc-sub {
  margin: 6px 0 0;
  font-size: 0.9rem;
  line-height: 1.5;
  color: var(--muted, #5b6472);
}

.lsc-close {
  flex: 0 0 auto;
  width: 38px;
  height: 38px;
  border: 1px solid var(--border, rgba(11, 18, 32, 0.12));
  border-radius: 50%;
  background: var(--surface-2, #f1f4fa);
  color: var(--text, #0b1220);
  cursor: pointer;
  display: grid;
  place-items: center;
  font-size: 1.1rem;
  line-height: 1;
}

.lsc-close:focus-visible {
  outline: none;
  box-shadow: var(--focus-ring, 0 0 0 3px rgba(193, 74, 0, 0.4));
}

/* chat_translation_fix_plan.md B3: the 5-button language picker is gone.
 * The customer writes in any language and the AI/staff reply in the same
 * language — driven by per-message detection (B0), not a picker selection.
 * Single hint line below the consent block tells them so. Chrome lang
 * still follows the platform-wide language menu (GZPlatformLang). */

.lsc-hint {
  flex: 0 0 auto;
  margin: 0;
  padding: 8px 20px 12px;
  border-bottom: 1px solid var(--border, rgba(11, 18, 32, 0.12));
  color: var(--muted, #5b6472);
  font-size: 0.78rem;
  line-height: 1.45;
}

/* ── Consent pill + popover ─────────────────────────────────────────────
 * Batch 2 of plan 2026-05-26_unified_chat_modernization_plan — the old
 * orange "Hinweis: …" block (a full-width flex paragraph above the thread)
 * was replaced by:
 *
 *   - .lsc-head__actions : the head's right-rail wrapper, holding the new
 *     info-pill alongside the close (×) button. Sits inside the existing
 *     .lsc-head flexbox without disturbing its alignment.
 *   - .lsc-consent-pill   : 38×38 round icon button matching .lsc-close,
 *     so the two affordances read as a pair (size + shape parity). Subtle
 *     primary-tinted background to signal "useful info" without screaming.
 *   - .lsc-consent-pop    : the popover that hosts the full disclaimer,
 *     Datenschutzerklärung link and Einwilligung version stamp. Anchored
 *     to the top-right edge of .lsc-sheet via logical properties so RTL
 *     gets the mirror automatically — no [dir=rtl] override needed.
 *
 * The `.lsc-consent`, `.lsc-consent__link` and `.lsc-consent__ver` rules
 * below still exist because the popover's body still uses those classes —
 * the markup migrated, the names didn't. The flex/padding/background of
 * the old top-level paragraph rule are intentionally GONE (clean redesign,
 * not patched) so nothing leaks if the markup is recycled.
 */

.lsc-head__actions {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  gap: 8px;
}

.lsc-consent-pill {
  flex: 0 0 auto;
  width: 38px;
  height: 38px;
  border: 1px solid var(--border, rgba(11, 18, 32, 0.12));
  border-radius: 50%;
  background: rgba(var(--primary-rgb, 227, 82, 5), 0.08);
  color: var(--primary-on-light, #b34400);
  cursor: pointer;
  display: grid;
  place-items: center;
  padding: 0;
  transition: background 160ms ease, transform 160ms ease;
}

.lsc-consent-pill svg {
  width: 22px;
  height: 22px;
}

.lsc-consent-pill:hover,
.lsc-consent-pill[aria-expanded='true'] {
  background: rgba(var(--primary-rgb, 227, 82, 5), 0.16);
}

.lsc-consent-pill:focus-visible {
  outline: none;
  box-shadow: var(--focus-ring, 0 0 0 3px rgba(193, 74, 0, 0.4));
}

.lsc-consent-pop {
  position: absolute;
  /* Anchor just below the head (.lsc-head padding-bottom is 14px;
   * border-bottom 1px; we offset by ~62px to clear the head completely
   * regardless of title wrapping — falls back to a value that always
   * sits visibly inside the sheet on the smallest 375px viewport). */
  inset-block-start: 72px;
  inset-inline-end: 14px;
  inset-inline-start: auto;
  max-width: min(360px, calc(100% - 28px));
  z-index: 6;
  margin: 0;
  padding: 14px 16px 12px;
  border-radius: 14px;
  background: var(--surface, #ffffff);
  border: 1px solid var(--border, rgba(11, 18, 32, 0.12));
  box-shadow: 0 16px 40px rgba(15, 23, 42, 0.18);
  animation: lsc-consent-pop-in 160ms ease-out;
}

.lsc-consent-pop[hidden] {
  display: none;
}

@keyframes lsc-consent-pop-in {
  from { opacity: 0; transform: translateY(-6px); }
  to   { opacity: 1; transform: translateY(0); }
}

@media (prefers-reduced-motion: reduce) {
  .lsc-consent-pop { animation: none; }
  .lsc-consent-pill { transition: none; }
}

.lsc-consent-pop__close {
  position: absolute;
  inset-block-start: 6px;
  inset-inline-end: 6px;
  width: 28px;
  height: 28px;
  border: 0;
  border-radius: 50%;
  background: transparent;
  color: var(--muted, #5b6472);
  cursor: pointer;
  display: grid;
  place-items: center;
  padding: 0;
}

.lsc-consent-pop__close svg {
  width: 16px;
  height: 16px;
}

.lsc-consent-pop__close:hover {
  background: var(--surface-2, #f1f4fa);
  color: var(--text, #0b1220);
}

.lsc-consent-pop__close:focus-visible {
  outline: none;
  box-shadow: var(--focus-ring, 0 0 0 3px rgba(193, 74, 0, 0.4));
}

.lsc-consent {
  margin: 0;
  padding: 0 28px 0 0;
  color: var(--text, #0b1220);
  font-size: 0.85rem;
  line-height: 1.55;
}

html[dir='rtl'] .lsc-consent,
.lsc-root[dir='rtl'] .lsc-consent {
  padding: 0 0 0 28px;
}

.lsc-consent__link {
  color: var(--primary-on-light, #b34400);
  font-weight: 600;
  text-decoration: underline;
}

.lsc-consent__ver {
  display: inline-block;
  margin-inline-start: 2px;
  white-space: nowrap;
  color: var(--muted, #5b6472);
  font-weight: 600;
}

/* Narrow screens: let the popover span more of the head so a long German
 * sentence reads without forcing 4–5 lines of wrap. */
@media (max-width: 480px) {
  .lsc-consent-pop {
    inset-inline-start: 14px;
    max-width: none;
  }
}

/* ── Thread (scrollable) ───────────────────────────────────────────── */

.lsc-thread {
  flex: 1 1 auto;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  padding: 18px 20px;
  display: flex;
  flex-direction: column;
  gap: 12px;
  min-height: 180px;
}

.lsc-loading,
.lsc-empty {
  margin: auto;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 14px;
  padding: 28px 12px;
  text-align: center;
  color: var(--muted, #5b6472);
}

.lsc-spinner {
  width: 34px;
  height: 34px;
  border-radius: 50%;
  border: 3px solid rgba(var(--text-rgb, 11, 18, 32), 0.14);
  border-top-color: var(--primary, #e35205);
  animation: lsc-spin 0.85s linear infinite;
}

@keyframes lsc-spin {
  to {
    transform: rotate(360deg);
  }
}

.lsc-empty__icon {
  width: 46px;
  height: 46px;
  color: var(--primary, #e35205);
}

.lsc-empty__title {
  margin: 0;
  font-size: 1.05rem;
  font-weight: 700;
  color: var(--text-strong, #0b1220);
}

/* ── Message bubbles ───────────────────────────────────────────────── */

.lsc-msg {
  display: flex;
  flex-direction: column;
  max-width: 84%;
}

.lsc-msg__bubble {
  padding: 11px 14px;
  border-radius: 16px;
  font-size: 0.92rem;
  line-height: 1.55;
  /* Customer/AI text is rendered textContent-only by the JS; this keeps
     intentional newlines from the model readable without any markup. */
  white-space: pre-wrap;
  word-break: break-word;
  /* A message may be written in a different language than the active UI
     locale (e.g. an Arabic-locale visitor who asks in German). Without a
     per-message base direction the trailing neutral punctuation of an LTR
     sentence is reordered to the RTL side under [dir='rtl'] ("?Wie viel…"
     instead of "Wie viel…?"). plaintext resolves each bubble's base
     direction from its own first strong character (the dir="auto"
     equivalent), so LTR content keeps correct punctuation while genuine
     Arabic content still renders RTL. start-alignment then follows that
     per-message direction; box side stays controlled by .lsc-msg--*. */
  unicode-bidi: plaintext;
  text-align: start;
}

.lsc-msg__meta {
  margin-top: 4px;
  font-size: 0.7rem;
  color: var(--muted, #5b6472);
}

/* Customer → end side, primary fill. */
.lsc-msg--customer {
  align-self: flex-end;
  align-items: flex-end;
}

.lsc-msg--customer .lsc-msg__bubble {
  background: var(--primary-strong, #c14a00);
  color: var(--primary-contrast, #ffffff);
  border-end-end-radius: 5px;
}

/* AI / human → start side, surface fill. Batch 9 (the owner's recorded
   product decision): `human` is a real bubble — the EXACT onboarding
   .scc-msg--human treatment (accent-tinted so a staff reply is visibly
   distinct from the AI), on the landing literal-fallback tokens. */
.lsc-msg--ai,
.lsc-msg--human {
  align-self: flex-start;
  align-items: flex-start;
}

.lsc-msg--ai .lsc-msg__bubble,
.lsc-msg--human .lsc-msg__bubble {
  background: var(--surface-2, #f1f4fa);
  color: var(--text-strong, #0b1220);
  border: 1px solid var(--border, rgba(11, 18, 32, 0.12));
  border-end-start-radius: 5px;
}

.lsc-msg--human .lsc-msg__bubble {
  border-color: rgba(var(--primary-rgb, 227, 82, 5), 0.5);
  background: rgba(var(--primary-rgb, 227, 82, 5), 0.08);
}

.lsc-msg__author {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  margin-bottom: 4px;
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--primary-on-light, #b34400);
}

.lsc-msg__author svg {
  width: 14px;
  height: 14px;
}

/* System events (lead captured, conversation closed): centred status. */
.lsc-msg--system_event {
  align-self: center;
  max-width: 92%;
}

.lsc-msg--system_event .lsc-msg__bubble {
  background: transparent;
  color: var(--muted, #5b6472);
  font-size: 0.8rem;
  text-align: center;
  border: 1px dashed var(--border, rgba(11, 18, 32, 0.12));
  border-radius: 999px;
  padding: 7px 14px;
}

/* ── Typing indicator ──────────────────────────────────────────────── */

.lsc-typing {
  align-self: flex-start;
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 12px 16px;
  border-radius: 16px;
  border: 1px solid var(--border, rgba(11, 18, 32, 0.12));
  background: var(--surface-2, #f1f4fa);
}

.lsc-typing span {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--muted, #5b6472);
  animation: lsc-bounce 1.2s infinite ease-in-out;
}

.lsc-typing span:nth-child(2) {
  animation-delay: 0.15s;
}

.lsc-typing span:nth-child(3) {
  animation-delay: 0.3s;
}

@keyframes lsc-bounce {
  0%, 80%, 100% {
    transform: translateY(0);
    opacity: 0.5;
  }
  40% {
    transform: translateY(-5px);
    opacity: 1;
  }
}

/* ── Error / notice ────────────────────────────────────────────────── */

.lsc-error {
  flex: 0 0 auto;
  margin: 0 20px 10px;
  padding: 10px 13px;
  border: 1px solid rgba(var(--danger-rgb, 239, 68, 68), 0.45);
  border-radius: 12px;
  background: rgba(var(--danger-rgb, 239, 68, 68), 0.1);
  color: var(--danger, #ef4444);
  font-size: 0.84rem;
  line-height: 1.45;
}

.lsc-error[hidden] {
  display: none !important;
}

/* ── Escalation bar (the human hand-off — Batch 9, the owner's recorded
 *    product decision: this REPLACES the in-chat lead-capture form). The
 *    lsc-* twin of .scc-escalate / .scc-chip-btn (onboarding-support-chat
 *    .css), kept on the landing literal-fallback token system so it is
 *    correct even before the public token sheet loads
 *    (reference_public_dark_mode_localstorage). ── */

.lsc-escalate {
  flex: 0 0 auto;
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  padding: 10px 20px;
  border-top: 1px solid var(--border, rgba(11, 18, 32, 0.12));
  background: var(--surface, #ffffff);
}

.lsc-escalate[hidden] {
  display: none !important;
}

.lsc-escalate__hint {
  flex: 1 0 100%;
  margin: 0 0 2px;
  font-size: 0.8rem;
  line-height: 1.5;
  color: var(--muted, #5b6472);
}

.lsc-chip-btn {
  flex: 1 1 auto;
  min-width: 140px;
  appearance: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  border: 1px solid var(--border, rgba(11, 18, 32, 0.12));
  border-radius: 12px;
  background: var(--surface-2, #f1f4fa);
  color: var(--text, #0b1220);
  padding: 10px 14px;
  font: inherit;
  font-size: 0.86rem;
  font-weight: 700;
  cursor: pointer;
  transition: border-color 120ms ease, background 120ms ease;
}

.lsc-chip-btn svg {
  width: 16px;
  height: 16px;
  flex: 0 0 auto;
}

.lsc-chip-btn:hover {
  border-color: var(--primary, #e35205);
  background: rgba(var(--primary-rgb, 227, 82, 5), 0.08);
}

.lsc-chip-btn:focus-visible {
  outline: none;
  box-shadow: var(--focus-ring, 0 0 0 3px rgba(193, 74, 0, 0.4));
}

.lsc-chip-btn[disabled] {
  opacity: 0.55;
  cursor: progress;
}

.lsc-chip-btn--accent {
  border-color: rgba(var(--primary-rgb, 227, 82, 5), 0.55);
  color: var(--primary-on-light, #b34400);
}

/* ── Composer ──────────────────────────────────────────────────────── */

.lsc-composer {
  flex: 0 0 auto;
  display: flex;
  align-items: flex-end;
  gap: 8px;
  padding: 12px 20px calc(12px + env(safe-area-inset-bottom, 0px));
  border-top: 1px solid var(--border, rgba(11, 18, 32, 0.12));
  background: var(--surface, #ffffff);
}

.lsc-composer__field {
  flex: 1 1 auto;
  min-width: 0;
}

.lsc-composer textarea {
  width: 100%;
  box-sizing: border-box;
  border: 1px solid var(--input-border, rgba(11, 18, 32, 0.18));
  border-radius: 14px;
  background: var(--input-bg, rgba(11, 18, 32, 0.03));
  color: var(--input-text, #0b1220);
  font: inherit;
  font-size: 0.95rem;
  line-height: 1.4;
  padding: 11px 13px;
  resize: none;
  max-height: 140px;
  overflow-y: auto;
}

.lsc-composer textarea:focus-visible {
  outline: none;
  border-color: var(--primary, #e35205);
  box-shadow: var(--focus-ring, 0 0 0 3px rgba(193, 74, 0, 0.4));
}

.lsc-composer textarea[disabled] {
  opacity: 0.6;
}

.lsc-iconbtn {
  flex: 0 0 auto;
  width: 42px;
  height: 42px;
  appearance: none;
  border: 1px solid var(--border, rgba(11, 18, 32, 0.12));
  border-radius: 50%;
  background: var(--surface-2, #f1f4fa);
  color: var(--text, #0b1220);
  cursor: pointer;
  display: grid;
  place-items: center;
  transition: border-color 120ms ease, background 120ms ease;
}

.lsc-iconbtn svg {
  width: 19px;
  height: 19px;
}

.lsc-iconbtn:hover {
  border-color: var(--primary, #e35205);
  background: rgba(var(--primary-rgb, 227, 82, 5), 0.08);
}

.lsc-iconbtn:focus-visible {
  outline: none;
  box-shadow: var(--focus-ring, 0 0 0 3px rgba(193, 74, 0, 0.4));
}

.lsc-iconbtn[disabled] {
  opacity: 0.5;
  cursor: progress;
}

.lsc-iconbtn--send {
  background: var(--primary-strong, #c14a00);
  color: var(--primary-contrast, #ffffff);
  border-color: transparent;
}

.lsc-iconbtn--send:hover {
  filter: brightness(1.06);
  background: var(--primary-strong, #c14a00);
}

/* Plan 2026-05-26 Batch 4 — the legacy `.lsc-rec*` recording bar was
   replaced by the shared GZVoiceRecorder. The new UI is appended INSIDE
   the composer (`.lsc-composer`) by the shared module and rendered via
   `assets/css/_chat_voice_recorder.css` (loaded before this sheet). The
   composer's idle children (textarea, send, attach) get `data-cvr-hidden`
   while the recorder is active — the shared sheet does the hiding. No
   per-widget recording styles remain; touch-and-hold + slide-to-cancel +
   live waveform + preview all live in the shared module. */

/* ── Attachments (Batch 04 of plan 2026-05-20) ──────────────────────────
   Visitor-side image attachment surfaces:
     .lsc-tray         — staging area for uploaded-but-not-yet-sent images
     .lsc-tray__item   — one pending thumbnail (with upload spinner overlay)
     .lsc-tray__rm     — remove button on each tray item
     .lsc-msg__atts    — attachment box inside a rendered message bubble
     .lsc-msg__att     — one image thumbnail in a message bubble
   Dark-mode coverage is automatic via the existing surface/border tokens
   (theme_a/tokens.css), which is also why both light + dark widgets stay
   in lock-step with the rest of the chat without extra rules. The
   .lsc-msg__att--from-staff accent picks up the same primary tint as the
   support-team bubble's border so a hotline-sent image reads as one
   product with the existing escalation surface. */

.lsc-tray {
  flex: 0 0 auto;
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  padding: 10px 20px 0;
}

.lsc-tray:empty {
  display: none;
}

.lsc-tray__item {
  position: relative;
  width: 56px;
  height: 56px;
  border-radius: 10px;
  overflow: hidden;
  border: 1px solid var(--border, rgba(11, 18, 32, 0.12));
  background: var(--surface-2, #f1f4fa);
}

.lsc-tray__item img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.lsc-tray__spin {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  background: rgba(var(--surface-rgb, 255, 255, 255), 0.6);
}

.lsc-tray__spin .lsc-spinner {
  width: 20px;
  height: 20px;
  border-width: 2px;
}

.lsc-tray__rm {
  position: absolute;
  inset-block-start: 2px;
  inset-inline-end: 2px;
  width: 20px;
  height: 20px;
  border: 0;
  border-radius: 50%;
  background: rgba(10, 12, 20, 0.66);
  color: #fff;
  font-size: 0.85rem;
  line-height: 1;
  cursor: pointer;
  display: grid;
  place-items: center;
  padding: 0;
}

.lsc-tray__rm:focus-visible {
  outline: none;
  box-shadow: var(--focus-ring, 0 0 0 3px rgba(193, 74, 0, 0.4));
}

/* Attachment thumbnails inside a rendered message bubble. */
.lsc-msg__atts {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 8px;
}

.lsc-msg__att {
  display: block;
  width: 96px;
  height: 96px;
  object-fit: cover;
  border-radius: 10px;
  border: 1px solid var(--border, rgba(11, 18, 32, 0.12));
  background: var(--surface, #ffffff);
  cursor: zoom-in;
}

/* Staff-origin marker. Same thickness/radius as the regular thumbnail, but
   the corner picks up the primary tint so a hotline-sent image is
   recognisable at a glance inside the human-role bubble. The `title`
   attribute (set by the renderer) carries the localized "Sent by the
   support team" tooltip for keyboard / screen-reader / hover. */
.lsc-msg__att.lsc-msg__att--from-staff {
  border-color: rgba(var(--primary-rgb, 227, 82, 5), 0.55);
  box-shadow: 0 0 0 2px rgba(var(--primary-rgb, 227, 82, 5), 0.18);
}

/* Plan 2026-05-24 chat image preview, Batch 2 — tap-to-retry overlay
 * rendered when the bubble image's three-tier recovery (local → proxy →
 * proxy+cb → local) has exhausted all attempts. Same 96×96 footprint as a
 * real thumbnail so the bubble layout never reflows; a soft surface tint
 * keeps the affordance quiet but discoverable. */
.lsc-msg__att.lsc-msg__att--retry {
  appearance: none;
  border: 1px solid var(--border, rgba(11, 18, 32, 0.12));
  background: var(--surface-2, #f1f4fa);
  color: var(--muted, #526178);
  display: grid;
  place-items: center;
  cursor: pointer;
  transition: background 120ms ease, color 120ms ease, border-color 120ms ease;
}

.lsc-msg__att.lsc-msg__att--retry:hover,
.lsc-msg__att.lsc-msg__att--retry:focus-visible {
  background: var(--surface, #ffffff);
  border-color: rgba(var(--primary-rgb, 227, 82, 5), 0.45);
  color: var(--text, #0b1220);
}

.lsc-msg__att.lsc-msg__att--retry svg {
  width: 28px;
  height: 28px;
}

/* ── Voice attachment inside a message bubble ─────────────────────────────
   The native <audio controls> render is a white pill that reads fine on the
   light AI/human bubble but collides hard with the orange customer bubble
   (and the dark-mode orange even more so). Force the audio control to span
   the bubble width, lift it onto a neutral inner surface, and tighten the
   radius so it reads as ONE component (voice card) rather than two stacked
   shapes (white pill + orange bubble background). The accompanying duration
   pill is hidden because the native control already shows current/total. */
.lsc-msg__voice {
  display: block;
  width: 100%;
  min-width: 240px;
  max-width: 320px;
  height: 40px;
  border-radius: 999px;
  background: var(--surface, #ffffff);
}

/* Inside the customer (orange) bubble the audio control needs a hair of
   inner padding so the white pill doesn't kiss the bubble corner. */
.lsc-msg--customer .lsc-msg__voice {
  margin-block: 2px;
}

/* The duration text is redundant — the native player already shows
   0:07 / 0:07 — and the bare "0:07" string was rendering as an oddly-tinted
   tag at the bubble corner. Keep the DOM node (accessible duration source
   via aria-label / future custom-player swap) but hide it visually. */
.lsc-msg__voice-dur {
  position: absolute !important;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

/* Make the attachments box stack vertically when it contains a voice
   element so the audio pill always gets the full bubble width. */
.lsc-msg__atts:has(.lsc-msg__voice) {
  flex-direction: column;
  align-items: stretch;
}

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

/* ── Tablet / desktop: right side-sheet (RTL → left) ───────────────── */

@media (min-width: 700px) {
  .lsc-sheet {
    inset-inline-start: auto;
    inset-inline-end: 0;
    inset-block: 0;
    width: min(460px, 94vw);
    max-height: 100dvh;
    border-radius: 0;
    border-inline-start: 1px solid var(--border, rgba(11, 18, 32, 0.12));
    box-shadow: -24px 0 60px rgba(15, 23, 42, 0.22);
    transform: translateX(102%);
  }

  #lsc-root.lsc-root[data-open='1'] .lsc-sheet {
    transform: translateX(0);
  }

  html[dir='rtl'] .lsc-sheet,
  #lsc-root.lsc-root[dir='rtl'] .lsc-sheet {
    inset-inline-end: 0;
    transform: translateX(-102%);
  }

  html[dir='rtl'] #lsc-root.lsc-root[data-open='1'] .lsc-sheet,
  #lsc-root.lsc-root[dir='rtl'][data-open='1'] .lsc-sheet {
    transform: translateX(0);
  }
}

@media (min-width: 1100px) {
  .lsc-sheet {
    width: 480px;
  }

  .lsc-thread {
    padding: 22px 26px;
  }
}

/* ── Reduced motion ────────────────────────────────────────────────── */

@media (prefers-reduced-motion: reduce) {
  .lsc-sheet,
  .lsc-backdrop,
  .lsc-launcher {
    transition: none;
  }

  .lsc-spinner {
    animation-duration: 1.6s;
  }

  .lsc-typing span {
    animation: none;
    opacity: 0.7;
  }
}

/* ─────────────────────────────────────────────────────────────────────
 * Batch 05 (plan 2026-05-20) — E-mail-gate modal before escalation.
 *
 * Mobile-first: a bottom-sheet on ≤640px, a right-side slide-in on wider
 * viewports. RTL spiegelt die Transform-Richtung; Arabic uses the
 * platform-shipped Cairo stack. Lives ON TOP of the open chat sheet (its
 * scrim covers the existing thread). All design tokens reuse the
 * landing-chat variables so dark mode + brand recolouring carry through.
 * ───────────────────────────────────────────────────────────────────── */

.lsc-gate[hidden] {
  display: none !important;
}

.lsc-gate {
  position: absolute;
  inset: 0;
  z-index: 4;
  display: flex;
  align-items: flex-end;
  justify-content: stretch;
}

.lsc-gate__scrim {
  position: absolute;
  inset: 0;
  background: rgba(15, 23, 42, 0.42);
  backdrop-filter: blur(2px);
  -webkit-backdrop-filter: blur(2px);
  cursor: pointer;
}

.lsc-gate__panel {
  position: relative;
  z-index: 1;
  width: 100%;
  max-width: 100%;
  background: var(--surface, #ffffff);
  color: var(--text, #0f172a);
  border-top-left-radius: 16px;
  border-top-right-radius: 16px;
  box-shadow: 0 -24px 60px rgba(15, 23, 42, 0.22);
  padding: 18px 18px calc(18px + env(safe-area-inset-bottom));
  display: flex;
  flex-direction: column;
  gap: 12px;
  max-height: 90%;
  overflow-y: auto;
}

.lsc-gate__head {
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.lsc-gate__title {
  margin: 0;
  font-size: 1.05rem;
  font-weight: 700;
  line-height: 1.3;
  color: var(--text-strong, #0b1220);
}

.lsc-gate__lead {
  margin: 0;
  font-size: 0.9rem;
  line-height: 1.5;
  color: var(--muted, #475569);
}

.lsc-gate__form {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.lsc-gate__field {
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.lsc-gate__label {
  font-size: 0.78rem;
  font-weight: 600;
  color: var(--muted, #475569);
  letter-spacing: 0.02em;
}

.lsc-gate__field input {
  width: 100%;
  font: inherit;
  font-size: 0.95rem;
  line-height: 1.4;
  padding: 10px 12px;
  border-radius: 10px;
  border: 1px solid var(--border, rgba(11, 18, 32, 0.18));
  background: var(--surface, #ffffff);
  color: var(--text, #0f172a);
  min-height: 42px;
  -webkit-appearance: none;
  appearance: none;
}

.lsc-gate__field input:focus {
  outline: 2px solid rgba(var(--primary-rgb, 227, 82, 5), 0.45);
  outline-offset: 2px;
  border-color: var(--primary, #e35205);
}

.lsc-gate__err {
  margin: 0;
  padding: 8px 10px;
  border-radius: 8px;
  background: rgba(220, 38, 38, 0.10);
  color: #991b1b;
  font-size: 0.85rem;
  line-height: 1.4;
}

.lsc-gate__note {
  margin: 0;
  font-size: 0.78rem;
  color: var(--muted, #475569);
  line-height: 1.4;
}

.lsc-gate__actions {
  display: flex;
  gap: 8px;
  margin-top: 4px;
  justify-content: flex-end;
  flex-wrap: wrap;
}

.lsc-gate__btn {
  font: inherit;
  font-size: 0.9rem;
  font-weight: 600;
  min-height: 42px;
  padding: 10px 16px;
  border-radius: 10px;
  border: 1px solid transparent;
  cursor: pointer;
  background: transparent;
  color: var(--text, #0f172a);
  transition: background-color 0.18s ease, border-color 0.18s ease, transform 0.18s ease;
}

.lsc-gate__btn--ghost {
  border-color: var(--border, rgba(11, 18, 32, 0.18));
  color: var(--muted, #475569);
}

.lsc-gate__btn--ghost:hover {
  background: rgba(15, 23, 42, 0.04);
}

.lsc-gate__btn--primary {
  background: var(--primary-strong, #c14a00);
  color: var(--primary-contrast, #ffffff);
  border-color: var(--primary-strong, #c14a00);
  box-shadow: 0 6px 14px rgba(var(--primary-strong-rgb, 193, 74, 0), 0.28);
}

.lsc-gate__btn--primary:hover {
  background: var(--primary, #e35205);
  border-color: var(--primary, #e35205);
}

.lsc-gate__btn--primary:disabled {
  opacity: 0.6;
  cursor: progress;
}

/* Arabic: keep Cairo for every glyph (Arabic must never use the latin
   font, even in nested modals). Numbers stay Latin via JS keepLatin. */
html[dir='rtl'] .lsc-gate,
html[lang='ar'] .lsc-gate {
  font-family: 'Cairo', 'Segoe UI', Tahoma, Arial, sans-serif;
}

html[dir='rtl'] .lsc-gate__actions {
  justify-content: flex-start; /* the inline-end side mirrors visually */
}

/* Larger viewport: a right-side slide-in panel, not a bottom sheet. The
   panel rests against the inline-end edge of the open chat sheet (parent
   is the .lsc-root which contains the .lsc-sheet). Mirrors for RTL. */
@media (min-width: 641px) {
  .lsc-gate {
    align-items: stretch;
    justify-content: flex-end;
  }
  .lsc-gate__panel {
    width: min(380px, 92vw);
    max-height: 100%;
    border-top-left-radius: 0;
    border-top-right-radius: 0;
    border-inline-start: 1px solid var(--border, rgba(11, 18, 32, 0.12));
    box-shadow: -24px 0 60px rgba(15, 23, 42, 0.22);
    padding: 22px 24px calc(22px + env(safe-area-inset-bottom));
  }
  html[dir='rtl'] .lsc-gate__panel,
  #lsc-root[dir='rtl'] .lsc-gate__panel {
    border-inline-start: none;
    border-inline-end: 1px solid var(--border, rgba(11, 18, 32, 0.12));
    box-shadow: 24px 0 60px rgba(15, 23, 42, 0.22);
  }
}

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

/* Message body span — block-level so a future sibling (attachments box,
 * delivered-checkmark) stacks vertically rather than running inline with
 * the text content of the bubble. */
.lsc-msg__body {
  display: block;
}
