/* core.css - Global layout, variables, and base styles */

/* =====================================================================
   Brand typeface — Sora (OFL), self-hosted variable font, LATIN subset
   only: every other script (Tamil, Devanagari, Arabic, Han, …) falls
   through to the system stack per handbook 25, which renders native
   scripts correctly. font-display: swap paints system text first.
   Tenant fontFamily (applyKioskTheme) still overrides --kuyil-font.
   ===================================================================== */
@font-face {
  font-family: "Sora";
  src: url("/fonts/Sora-Variable.woff2") format("woff2");
  font-weight: 100 800;
  font-style: normal;
  font-display: swap;
}

/* =====================================================================
   CANONICAL BREAKPOINTS — the kiosk/widget surface steps at ONLY:
     480px  — phone / narrow widget
     640px  — large phone / small tablet (registration cards)
     900px  — tablet / small desktop
     1280px — large desktop / landscape kiosk
   plus (orientation: portrait) for tall kiosks and (max-height: 700px)
   for short screens. orb.css still steps at 800px — a legacy width kept
   this phase so the orb doesn't jump; fold into 900 in a later phase.
   Do NOT add new breakpoints.
   ===================================================================== */

/* =====================================================================
   Design tokens
   ===================================================================== */
:root {
  /* --- Tenant theme — defaults, overridden at runtime by
     applyKioskTheme() (src/lib/services/theme.ts) from kioskConfig. --- */
  --kuyil-primary: #6c8ebf;
  --kuyil-bg: #050505;
  --kuyil-accent: #a0c0ff;
  --kuyil-text: #ffffff;
  --kuyil-font:
    "Sora", system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  --kuyil-logo-url: none;
  --kuyil-bg-image: none;

  /* --- Surfaces derived from the tenant background colour. Each mixes
     --kuyil-bg toward a fixed slate partner so the DEFAULT computed colour
     equals the audited literal, while a tenant --kuyil-bg change retints
     every glass panel. Alpha is applied at the use site via color-mix. --- */
  --kuyil-surface-1: color-mix(in srgb, var(--kuyil-bg) 60%, #1d222c); /* ≈ #0f1115 — cards */
  --kuyil-surface-2: color-mix(in srgb, var(--kuyil-bg) 60%, #3a4458); /* ≈ #1a1e26 — chips/pills */
  --kuyil-surface-3: color-mix(in srgb, var(--kuyil-bg) 60%, #4e5a71); /* ≈ #222730 — active chip */
  --kuyil-line: color-mix(in srgb, var(--kuyil-bg) 60%, #5a667d); /* ≈ #272c35 — panel borders */
  --kuyil-line-strong: color-mix(in srgb, var(--kuyil-bg) 40%, #8fa0b7); /* ≈ #58626f — chip borders */

  /* --- Muted ink derived from the tenant text colour, same recipe as the
     surfaces above: DEFAULT computes to the audited literal (≈ #dae0e7,
     the rgba(218,224,231,·) family), while a light theme's dark
     --kuyil-text darkens every secondary label with it. Alpha is applied
     at the use site via color-mix. --- */
  --kuyil-ink-muted: color-mix(in srgb, var(--kuyil-text) 67%, #8fa0b7);

  /* --- Ambient aurora tints (body background + AuroraBackdrop blobs) —
     derived from the tenant primary/accent so a theme change retints the
     room light. Defaults compute to the audited literals
     (#406eb4 / #289687 / #785ac8). An orb theme preset (see
     src/lib/kiosk/orbThemes.ts) overrides these inline with its own hues. --- */
  --aurora-primary: color-mix(in srgb, var(--kuyil-primary) 50%, #144ea9);
  --aurora-teal: color-mix(in srgb, var(--kuyil-accent) 20%, #0a8c69);
  --aurora-violet: color-mix(in srgb, var(--kuyil-accent) 30%, #672eb0);

  /* --- Stage (page background) — owned by the orb theme preset via
     applyKioskTheme(); the fallbacks below ARE the audited pre-theme stage
     (they feed the body gradient), so no preset = today's exact look. The
     alpha/vignette/grain knobs drive AuroraBackdrop.svelte. --- */
  --stage-top: color-mix(in srgb, var(--kuyil-bg) 50%, #232735);
  --stage-mid: color-mix(in srgb, var(--kuyil-bg) 50%, #090b13);
  --stage-deep: #000000;
  --stage-aurora-alpha: 0.55;
  --stage-vignette: 0.28;
  --stage-grain: 0.045;

  /* --- Semantic conversation-state colours. The single source for the
     chip borders/dots/icons, orb state palettes and chat state accents:
     recoloring a state is a ONE-LINE change here. Soft/glow variants are
     derived at the use site: color-mix(in srgb, var(--state-*) N%, transparent). --- */
  --state-waiting: #3b82f6; /* blue — idle / waiting */
  --state-listening: #3cd9a7; /* mint — listening */
  --state-thinking: #ba5eba; /* orchid — processing / language chip */
  --state-speaking: #e8ab30; /* amber — speaking */
  --state-error: #ef4444; /* red — errors, logout, record dot */

  /* --- Shared accent tints (not conversation states) --- */
  --accent-violet: #a78bfa; /* assistant bubbles + default orb violet tint */
  --accent-cyan: #22d3ee; /* visitor (user) bubbles */

  /* --- Spacing scale — 4px base, in rem so it tracks root font size. --- */
  --space-1: 0.25rem; /*  4px */
  --space-2: 0.5rem; /*  8px */
  --space-3: 0.75rem; /* 12px */
  --space-4: 1rem; /* 16px */
  --space-5: 1.25rem; /* 20px */
  --space-6: 1.5rem; /* 24px */
  --space-7: 2rem; /* 32px */
  --space-8: 3rem; /* 48px */

  /* --- Border radii — softened one step for Aura --- */
  --radius-sm: 0.5rem; /*  8px — inputs, face marker */
  --radius-md: 0.875rem; /* 14px — compact panels */
  --radius-lg: 1.25rem; /* 20px — cards, form popup */
  --radius-xl: 2rem; /* 32px — hero cards */
  --radius-pill: 999px; /* fully-rounded pills / bars */

  /* --- Z-index layers (bottom → top). One-off values BETWEEN layers
     (e.g. the guided reg form at 40, its compact orb at 45, the portrait
     info bar at 20) stay literal, documented at their use site. --- */
  --z-bg: 0; /* body::before tenant background image */
  --z-base: 1; /* ambient decor (floating words) */
  --z-orb: 5; /* main-screen column: orb + greeting band */
  --z-cards: 10; /* content cards: chat panel, welcome/greeting card */
  --z-chips: 100; /* fixed status chips + language chip */
  --z-controls: 999; /* corner controls: logout, camera (+1 face marker) */
  --z-overlay: 9999; /* full-screen overlays (boot) */
  --z-top: 10000; /* reserved topmost — nothing may exceed this */

  /* --- Fluid type scale — phone widget → large portrait kiosk. Each step's
     MAX is the audited desktop (~1080p) size, so at the reference size the
     rendered output matches the old fixed values; smaller screens scale
     down smoothly instead of jumping at breakpoints. --- */
  --text-xs: clamp(0.65rem, 0.6rem + 0.2vw, 0.75rem);
  --text-sm: clamp(0.75rem, 0.7rem + 0.25vw, 0.875rem);
  --text-base: clamp(0.85rem, 0.8rem + 0.3vw, 1rem);
  --text-lg: clamp(0.95rem, 0.85rem + 0.5vw, 1.2rem);
  --text-xl: clamp(1.1rem, 1rem + 0.8vw, 1.6rem);
  --text-2xl: clamp(1.3rem, 1.1rem + 1.2vw, 2rem);
  --text-3xl: clamp(1.5rem, 1.2rem + 1.5vw, 2.5rem);
  --text-display: clamp(2rem, 1.5rem + 1.8vw, 3.2rem);
}

/* Apply themed font globally */
body {
  font-family: var(--kuyil-font);
}

/* Background image support (when --kuyil-bg-image is set by config) */
body::before {
  content: "";
  position: fixed;
  inset: 0;
  background-image: var(--kuyil-bg-image);
  background-size: cover;
  background-position: center;
  opacity: 0.15;
  pointer-events: none;
  z-index: var(--z-bg);
}

/* =====================================================================
   Layout variants — toggled via body[data-layout="..."], set at boot by
   applyKioskTheme() from kioskConfig.layout.variant.
   ===================================================================== */

/* slim: reduced motion and simpler background for lower-spec hardware */
body[data-layout="slim"] .floating-words {
  display: none;
}

body[data-layout="slim"] .app {
  padding: 2vh 4vw;
}

/* hotel: slightly warmer palette via accent shift */
body[data-layout="hotel"] {
  --kuyil-accent: #d4b483;
}

/* minimal: hide orb, full-width text panel */
body[data-layout="minimal"] .orb-container {
  display: none;
}

body[data-layout="minimal"] #chatPanel {
  width: 100%;
  max-width: 640px;
}

html,
body {
  margin: 0;
  padding: 0;
  height: 100%;
  overflow: hidden;
}

body {
  /* Layered aurora over a deep slate base — gives the liquid-glass orb
     ambient color to refract through its frosted shell. All tints derive
     from the tenant theme tokens (see :root) with identical defaults. */
  background:
    radial-gradient(
      55% 45% at 18% 12%,
      color-mix(in srgb, var(--aurora-primary) 18%, transparent),
      transparent 65%
    ),
    radial-gradient(
      50% 42% at 82% 78%,
      color-mix(in srgb, var(--aurora-teal) 14%, transparent),
      transparent 65%
    ),
    radial-gradient(
      40% 35% at 70% 18%,
      color-mix(in srgb, var(--aurora-violet) 10%, transparent),
      transparent 65%
    ),
    radial-gradient(
      circle at top,
      var(--stage-top) 0,
      var(--stage-mid) 55%,
      var(--stage-deep) 100%
    );
  color: var(--kuyil-text);
  display: flex;
  align-items: stretch;
  justify-content: center;
}

.app {
  width: 100%;
  max-width: 1400px;
  display: flex;
  flex-direction: column;
  align-items: center;
  /* dvh tracks the VISIBLE viewport on mobile/widget surfaces (browser chrome
     hides/shows); the vh line immediately before is the fallback for older
     kiosk browsers that don't know dynamic viewport units. */
  min-height: 100vh;
  min-height: 100dvh;
  overflow: hidden;
  padding: 1.2vh 2vw;
  box-sizing: border-box;
  position: relative;
}

/* Floating words background - Lovable style */
.floating-words {
  position: fixed;
  inset: 0;
  pointer-events: none;
  overflow: hidden;
  z-index: var(--z-base);
}

.floating-word {
  position: absolute;
  font-family: var(--kuyil-font);
  font-size: clamp(1.5rem, 3vw, 2.8rem);
  font-weight: 700;
  letter-spacing: 0.08em;
  color: rgba(167, 179, 190, 0.05);
  opacity: 0.05;
  animation: word-drift 10s ease-in-out infinite;
  user-select: none;
}

@keyframes word-drift {
  0%,
  100% {
    opacity: var(--word-opacity-min, 0.025);
    transform: translateY(0);
  }
  50% {
    opacity: var(--word-opacity-max, 0.065);
    transform: translateY(-10px);
  }
}

/* Main Screen — a single CSS grid; every big surface is a grid item so
   overlap is impossible by construction (rows stack, they cannot collide).
   Rows, top → bottom:
     1  status chips
     2  portrait info bar (collected-details card; empty in landscape)
     3  guided registration form (empty when no form)
     4  orb band — flexible (1fr), shrinks FIRST on short screens; the
        landscape collected-details card docks in this row's left column
     5  chat panel
     6  bottom hint
   Rows 2/3/5 are fit-content(cap): sized to their content, capped so the orb
   band always keeps its floor, and collapsing to ZERO when the element is
   hidden — so the orb recenters naturally per state. The columns keep the orb
   column centered (equal 1fr gutters) while the landscape reg card uses the
   left gutter. Bottom padding reserves the fixed corner-control band
   (logout / camera); env() insets keep everything inside notches / home
   indicators on the widget surface. pointer-events: none on the container
   (children restore auto) so it never blocks clicks on the chat panel.
   Each grid-template-rows is declared twice: vh fallback first, then dvh for
   browsers that track the dynamic viewport. */
.main-screen {
  position: fixed;
  inset: 0;
  display: grid;
  /* Center column: `auto` min lets the orb keep its intrinsic size (hero
     ≈40rem, conversation ≤24rem, portrait 70vw) — it can never be clipped —
     while the 26rem growth cap leaves the equal 1fr gutters room for the
     landscape collected-details card during conversations. */
  grid-template-columns: minmax(0, 1fr) minmax(auto, 26rem) minmax(0, 1fr);
  grid-template-rows:
    auto
    fit-content(13vh)
    fit-content(46vh)
    minmax(min(8rem, 18vh), 1fr)
    fit-content(26vh)
    auto;
  grid-template-rows:
    auto
    fit-content(13dvh)
    fit-content(46dvh)
    minmax(min(8rem, 18dvh), 1fr)
    fit-content(26dvh)
    auto;
  --screen-pad-x: var(--space-5);
  --screen-pad-top: var(--space-5);
  /* Reserves the fixed corner-control band (logout / camera preview). */
  --screen-pad-bottom: 5rem;
  padding:
    calc(var(--screen-pad-top) + env(safe-area-inset-top, 0px))
    calc(var(--screen-pad-x) + env(safe-area-inset-right, 0px))
    calc(var(--screen-pad-bottom) + env(safe-area-inset-bottom, 0px))
    calc(var(--screen-pad-x) + env(safe-area-inset-left, 0px));
  box-sizing: border-box;
  z-index: var(--z-orb);
  pointer-events: none;
}

.main-screen > * {
  pointer-events: auto;
}

/* Center content container — the orb band. Centered inside the flexible grid
   row, so hiding the chat/cards (their rows collapse to zero) recenters the
   orb automatically with no positional math. */
.center-content {
  grid-row: 4;
  grid-column: 2;
  align-self: center;
  justify-self: center;
  min-width: 0;
  min-height: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--space-4);
  width: 100%;
  max-width: 600px;
  position: relative;
  z-index: var(--z-cards);
}

/* Orb container - holds orb and audio bar */
.orb-container {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-3);
}

/* Greeting card - Lovable style */
.greeting-card {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-2);
  text-align: center;
  padding: var(--space-7) var(--space-8);
  background: color-mix(in srgb, var(--kuyil-surface-1) 75%, transparent);
  border: 1px solid color-mix(in srgb, var(--kuyil-line) 40%, transparent);
  border-radius: var(--radius-xl);
  box-shadow: 0 8px 60px rgba(9, 11, 17, 0.5);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  transition: opacity 0.3s ease;
}

.greeting-text {
  font-size: clamp(1.8rem, 4vw, 3rem);
  font-weight: 300;
  color: var(--kuyil-text);
  letter-spacing: -0.02em;
  line-height: 1.1;
  text-wrap: balance;
  transition: opacity 0.3s ease;
}

.greeting-subtitle {
  font-size: clamp(0.9rem, 2vw, 1.1rem);
  /* alpha ≥ .78 keeps the muted look while passing 4.5:1 on the card. */
  color: color-mix(in srgb, var(--kuyil-ink-muted) 78%, transparent);
  font-weight: 300;
  transition: opacity 0.3s ease;
}

/* Instruction pill */
.instruction-pill {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  padding: 10px var(--space-4);
  background: color-mix(in srgb, var(--kuyil-surface-2) 80%, transparent);
  border: 1px solid color-mix(in srgb, var(--kuyil-line-strong) 20%, transparent);
  border-radius: var(--radius-pill);
  margin-top: var(--space-1);
}

.pill-dot {
  width: 6px;
  height: 6px;
  background: var(--state-listening);
  border-radius: 50%;
  box-shadow: 0 0 8px color-mix(in srgb, var(--state-listening) 60%, transparent);
  animation: cta-glow 3s ease-in-out infinite;
}

@keyframes cta-glow {
  0%,
  100% {
    opacity: 1;
    box-shadow: 0 0 8px color-mix(in srgb, var(--state-listening) 60%, transparent);
  }
  50% {
    opacity: 0.6;
    box-shadow: 0 0 12px color-mix(in srgb, var(--state-listening) 80%, transparent);
  }
}

.pill-text {
  font-size: var(--text-sm);
  color: color-mix(in srgb, var(--kuyil-ink-muted) 90%, transparent);
  font-weight: 400;
  letter-spacing: 0.5px;
}

/* Bottom hint container - Lovable style (grid row 6, below the chat). */
.bottom-hint-container {
  grid-row: 6;
  grid-column: 1 / -1;
  justify-self: center;
  margin-top: var(--space-3);
  padding: var(--space-3) var(--space-6);
  background: color-mix(in srgb, var(--kuyil-surface-1) 70%, transparent);
  border-radius: var(--radius-lg);
  transition: opacity 0.3s ease;
}

.bottom-hint-text {
  font-size: var(--text-sm);
  font-weight: 300;
  /* alpha ≥ .72 keeps the muted look while passing 4.5:1 on the hint pill. */
  color: color-mix(in srgb, var(--kuyil-ink-muted) 72%, transparent);
  text-align: center;
  margin: 0;
}

/* Leaving/completion countdowns now render ON the orb as a rim ring with a
   language-neutral digit (AuraOrb.svelte) — the old floating .leaving-warning
   / .completion-timer overlays are gone. */

/* Chat panel styles live in chat.css — the single owner of .chat-panel. */

/* Language chip — top right, QUIET (Aura: the orb owns state; this is a
   small factual marker). Opaque hairline pill — no glow halo, no blur
   (blur budget lives with the cards). Safe-area insets keep it clear of
   notches on the widget surface. */
.lang-chip {
  position: fixed;
  top: calc(var(--space-6) + env(safe-area-inset-top, 0px));
  /* Logical: pins to the inline-END corner, opposite the brand lockup's
     inline-start cell, so dir="rtl" flips the pair instead of piling both
     into the same physical corner. Identical to `right` under LTR; max()
     of both physical insets keeps the offset safe whichever side is END. */
  inset-inline-end: calc(
    var(--space-6) + max(env(safe-area-inset-left, 0px), env(safe-area-inset-right, 0px))
  );
  z-index: var(--z-chips);
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  padding: var(--space-2) var(--space-4);
  border-radius: var(--radius-pill);
  background: color-mix(in srgb, var(--kuyil-surface-2) 96%, transparent);
  border: 1px solid color-mix(in srgb, var(--kuyil-accent) 35%, transparent);
  opacity: 0;
  transform: translateY(-1rem);
  transition: opacity 0.3s ease, transform 0.3s ease;
}

.lang-chip.visible {
  opacity: 1;
  transform: translateY(0);
}

.lang-chip__dot {
  width: 0.5rem;
  height: 0.5rem;
  border-radius: 50%;
  background: var(--kuyil-accent);
  animation: lang-dot-pulse 2s ease-in-out infinite;
}

.lang-chip__text {
  font-size: var(--text-sm);
  font-weight: 600;
  color: color-mix(in srgb, var(--kuyil-ink-muted) 95%, transparent);
  letter-spacing: 0.125rem;
}

@keyframes lang-dot-pulse {
  0%,
  100% {
    opacity: 1;
    transform: scale(1);
  }
  50% {
    opacity: 0.6;
    transform: scale(1.1);
  }
}

/* Camera preview (fixed corner control; safe-area aware) */
#camWrapper {
  position: fixed;
  right: calc(var(--space-5) + env(safe-area-inset-right, 0px));
  bottom: calc(var(--space-5) + env(safe-area-inset-bottom, 0px));
  width: 5.625rem;
  height: 4.375rem;
  border-radius: 0.625rem;
  overflow: hidden;
  z-index: var(--z-controls);
}

#camPreview {
  width: 100%;
  height: 100%;
  object-fit: cover;
  opacity: 0.9;
  border-radius: 0.625rem;
  border: 2px solid rgba(255, 255, 255, 0.4);
}

#camPreview:hover {
  opacity: 1;
}

/* Camera failed (permission/device): wordless red frame on the operator
   corner control so a dead presence pipeline is visible at a glance. */
#camWrapper.cam-error {
  box-shadow: 0 0 0 2px var(--state-error),
    0 0 12px color-mix(in srgb, var(--state-error) 60%, transparent);
}

/* Square face marker overlay on camera preview */
#faceMarker {
  position: fixed;
  /* Face-lock green — a camera cue, deliberately not a state colour. */
  border: 3px solid #22c55e;
  box-shadow: 0 0 14px rgba(34, 197, 94, 0.95);
  border-radius: var(--radius-sm);
  pointer-events: none;
  z-index: calc(var(--z-controls) + 1);
  opacity: 0;
  transform: translate(-50%, -50%);
  transition: opacity 0.15s ease-out;
}

/* Logout button - bottom left (fixed corner control; safe-area aware).
   2.75rem = 44px — the WCAG minimum touch target; do not shrink. */
.logout-btn {
  position: fixed;
  left: calc(var(--space-5) + env(safe-area-inset-left, 0px));
  bottom: calc(var(--space-5) + env(safe-area-inset-bottom, 0px));
  z-index: var(--z-controls);
  width: 2.75rem;
  height: 2.75rem;
  border-radius: 50%;
  background: color-mix(in srgb, var(--state-error) 80%, transparent);
  border: 1px solid color-mix(in srgb, var(--state-error) 30%, transparent);
  color: white;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: opacity 0.2s ease, transform 0.2s ease,
    background-color 0.2s ease, border-color 0.2s ease;
  opacity: 0.7;
}

.logout-btn:hover {
  background: color-mix(in srgb, var(--state-error) 90%, transparent);
  border-color: color-mix(in srgb, var(--state-error) 50%, transparent);
  opacity: 0.9;
  transform: scale(1.05);
}

.logout-btn:active {
  transform: scale(0.95);
}

/* Camera capture button - Lovable style */
.capture-btn {
  position: fixed;
  right: var(--space-5);
  bottom: 100px;
  z-index: var(--z-controls);
  width: 64px;
  height: 64px;
  border-radius: 50%;
  background: color-mix(in srgb, var(--kuyil-surface-2) 90%, transparent);
  border: 2px solid rgba(51, 119, 153, 0.3);
  color: rgba(218, 224, 231, 0.7);
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow:
    0 0 20px rgba(51, 153, 204, 0.1),
    0 0 40px rgba(88, 61, 143, 0.06);
  transition: transform 0.2s ease, border-color 0.2s ease, color 0.2s ease;
  overflow: hidden;
}

.capture-btn:hover {
  border-color: rgba(51, 119, 153, 0.5);
  color: color-mix(in srgb, var(--kuyil-ink-muted) 90%, transparent);
  transform: scale(1.05);
}

.capture-btn:active {
  transform: scale(0.95);
}

.capture-btn__dot {
  position: absolute;
  top: 8px;
  right: 8px;
  width: 10px;
  height: 10px;
  background: var(--state-error);
  border-radius: 50%;
  animation: capture-glow 2.5s ease-in-out infinite;
}

@keyframes capture-glow {
  0%,
  100% {
    opacity: 1;
    box-shadow: 0 0 8px color-mix(in srgb, var(--state-error) 60%, transparent);
  }
  50% {
    opacity: 0.6;
    box-shadow: 0 0 12px color-mix(in srgb, var(--state-error) 80%, transparent);
  }
}

/* Hide elements when chat is visible — fades out gracefully */
.chat-visible .greeting-card,
.chat-visible .instruction-pill,
.chat-visible .bottom-hint-container,
.chat-visible #greetingCard,
.chat-visible #bottomHint {
  opacity: 0;
  pointer-events: none;
}

/* During a conversation the summary (left gutter column), chips (row 1) and
   chat (row 5) share the grid with the orb band; the smaller orb keeps its
   sphere comfortably inside the flexible row.
   - width term: leaves room for the left summary card's gutter column */
.app.chat-visible {
  /* Smaller orb during a conversation so the orb + chat both fit inside the
     grid rows. The prism sphere is the full --orb-size (no inner core), so
     this is tighter than the old glass orb's value.
     vh (not dvh) on purpose: custom properties can't use the declare-twice
     dvh fallback (the second declaration always wins, then fails var()
     substitution on older kiosk browsers). Safe here — the orb centers in a
     flexible grid row, so a few % of mobile-chrome vh error only shifts the
     decorative bleed, never clips the chat/cards. */
  --orb-size: min(24rem, calc(100vw - 26rem), calc(46vh - 2rem));
}

/* Greeting card RTL / Arabic support */
.greeting-card[dir="rtl"],
.greeting-card[dir="auto"][lang*="ar"] {
  padding: var(--space-7) 2.5rem var(--space-7) 3.5rem;
}

.greeting-text[dir="rtl"],
.greeting-text[dir="auto"][lang*="ar"] {
  letter-spacing: 0;
  line-height: 1.4;
}

/* =====================================================================
   A11y — every focusable element gets a visible ring tinted by the tenant
   accent. NEVER remove an outline without a replacement (see handbook 24).
   ===================================================================== */
:focus-visible {
  outline: 2px solid var(--kuyil-accent);
  outline-offset: 2px;
}

/* =====================================================================
   Respect reduced motion — ONE comprehensive kill-switch for every looping /
   entrance animation on the kiosk surface (per-file rules in orb.css and
   component styles also remain; the AuraOrb canvas renders a static frame
   under reduced motion). Keyframes covered here: word-drift, cta-glow,
   capture-glow, lang-dot-pulse, listening-pulse, fade-in-up, welcome-in,
   word-swap, welcome-dot, reg-form-in, reg-card-in, arrow-pulse.
   Entrance keyframes are safe to drop: their base styles are the end state.
   ===================================================================== */
@media (prefers-reduced-motion: reduce) {
  .floating-word,
  .pill-dot,
  .capture-btn__dot,
  .lang-chip__dot,
  .listening-placeholder-bubble span::after,
  .chat-line,
  .welcome-card,
  .welcome-card__word,
  .welcome-card__dot,
  .reg-form,
  .reg-form__row.is-active .reg-form__arrow,
  .reg-card,
  .reg-card__row {
    animation: none !important;
  }
}

/* Mobile adjustments */
@media (max-width: 900px) {
  .main-screen {
    --screen-pad-x: var(--space-3);
    --screen-pad-top: var(--space-3);
    /* Corner controls are smaller at this width (4rem camera pill). */
    --screen-pad-bottom: 4rem;
  }

  .center-content {
    gap: var(--space-2);
  }

  .greeting-card {
    padding: var(--space-5) var(--space-6);
    border-radius: var(--radius-lg);
  }

  .greeting-text {
    font-size: clamp(1.3rem, 5vw, 2rem);
  }

  .greeting-subtitle {
    font-size: clamp(0.75rem, 2vw, 0.95rem);
  }

  .instruction-pill {
    padding: var(--space-2) var(--space-3);
  }

  .pill-text {
    font-size: var(--text-xs);
  }

  #camWrapper {
    width: 4rem;
    height: 3rem;
    right: calc(var(--space-3) + env(safe-area-inset-right, 0px));
    bottom: calc(var(--space-3) + env(safe-area-inset-bottom, 0px));
  }

  .bottom-hint-container {
    padding: var(--space-2) var(--space-4);
    margin-bottom: var(--space-1);
  }

  .bottom-hint-text {
    font-size: var(--text-xs);
  }
}

/* Short screens (embedded widget iframes, short landscape) — the flexible orb
   row shrinks first (smaller floor); the form/chat caps tighten so the row
   budget stays inside the viewport instead of clipping the chat/cards. */
@media (max-height: 700px) {
  .main-screen {
    --screen-pad-x: var(--space-2);
    --screen-pad-top: var(--space-2);
    --screen-pad-bottom: 4rem;
    grid-template-rows:
      auto
      fit-content(13vh)
      fit-content(38vh)
      minmax(min(6rem, 12vh), 1fr)
      fit-content(30vh)
      auto;
    grid-template-rows:
      auto
      fit-content(13dvh)
      fit-content(38dvh)
      minmax(min(6rem, 12dvh), 1fr)
      fit-content(30dvh)
      auto;
  }

  .center-content {
    gap: var(--space-1);
  }

  .greeting-card {
    padding: var(--space-4) var(--space-5);
    border-radius: var(--radius-lg);
  }

  .greeting-text {
    font-size: clamp(1.2rem, 4vw, 1.8rem);
  }
}

/* Very small screens */
@media (max-width: 480px) {
  .main-screen {
    --screen-pad-x: var(--space-2);
    --screen-pad-top: var(--space-2);
    --screen-pad-bottom: 3.5rem;
  }

  .center-content {
    gap: var(--space-1);
  }

  .greeting-card {
    padding: var(--space-3) var(--space-4);
    border-radius: 14px;
  }

  .greeting-text {
    font-size: clamp(1rem, 5vw, 1.5rem);
  }

  .greeting-subtitle {
    font-size: clamp(0.65rem, 2.5vw, 0.85rem);
  }

  .instruction-pill {
    padding: 0.4rem 0.6rem;
  }

  .pill-text {
    font-size: var(--text-xs);
  }

  .bottom-hint-container {
    padding: 0.4rem var(--space-3);
  }

  .bottom-hint-text {
    font-size: var(--text-xs);
  }

  #camWrapper {
    width: 3.5rem;
    height: 2.625rem;
    right: calc(var(--space-2) + env(safe-area-inset-right, 0px));
    bottom: calc(var(--space-2) + env(safe-area-inset-bottom, 0px));
  }

  .lang-chip {
    top: calc(var(--space-3) + env(safe-area-inset-top, 0px));
    inset-inline-end: calc(
      var(--space-3) + max(env(safe-area-inset-left, 0px), env(safe-area-inset-right, 0px))
    );
    padding: var(--space-2) var(--space-3);
  }
}

/* =====================================================================
   Portrait kiosks / tablets (tall screens) — vertical stack:
     · status chips + info bar  → top
     · orb (fills the width)    → middle
     · chat panel               → bottom (floor)
   Scoped to portrait so landscape kiosks/widgets are untouched. Orb sizing
   lives in orb.css; the top info bar (collected details) restyles itself in
   RegistrationCard.svelte. Layout only — THE ONE LAW is unaffected (no text).
   ===================================================================== */
@media (orientation: portrait) {
  /* Same grid, portrait budget: row 2 (collected-details info bar) caps at
     13dvh, the guided form a little tighter, the chat bar at 24dvh; the 1fr
     orb band absorbs the rest, so the chat naturally docks at the floor.
     Bottom padding reserves the corner-control band (logout / camera).
     The old `.app.chat-visible padding-top: calc(6.5rem + 13vh)` hack is
     gone: the info bar occupies its own grid row, so it pushes the orb band
     down by construction — no compensation needed. */
  .main-screen {
    --screen-pad-x: var(--space-3);
    --screen-pad-bottom: 5.5rem;
    grid-template-rows:
      auto
      fit-content(13vh)
      fit-content(42vh)
      minmax(min(8rem, 10vh), 1fr)
      fit-content(24vh)
      auto;
    grid-template-rows:
      auto
      fit-content(13dvh)
      fit-content(42dvh)
      minmax(min(8rem, 10dvh), 1fr)
      fit-content(24dvh)
      auto;
  }

  /* Orb band: the wide portrait orb may exceed the 40rem center column —
     let the container use the full column so it stays centered. */
  .center-content {
    max-width: 100%;
  }
}
