/* frontend/visitor/app.css */
* { box-sizing: border-box; }

html, body {
  margin: 0;
  padding: 0;
  height: 100%;
  background: var(--color-background);
  color: var(--color-text-on-dark);
  font-family: -apple-system, system-ui, sans-serif;
  overflow-x: hidden;
}

/* R3.2: the one shared raised-surface style, applied everywhere — no
   per-control shadow/radius values anywhere else in this stylesheet. */
.raised-surface {
  background: var(--color-surface);
  border-radius: var(--radius);
  box-shadow: var(--shadow-raised);
  border: none;
  /* The surface is light and <body> is dark, so anything landing on a raised
     surface must flip its text colour with it. Without this the four non-button
     surfaces (#mic-status, #speaking-indicator, #slide-counter, #lead-status)
     render --color-text-on-dark on --color-surface: a 1.09 contrast ratio, i.e.
     invisible. Declared on the shared class rather than per element so surfaces
     added later inherit the fix. */
  color: var(--color-text);
}

button.raised-surface,
a.raised-surface {
  color: var(--color-text);
  font-size: var(--text-md);
  font-weight: 600;
  padding: var(--space-3) var(--space-4);
  cursor: pointer;
}

button.raised-surface:disabled {
  opacity: 0.4;
  cursor: default;
}

/* Anchors included because the WhatsApp handoff (#whatsapp-link) is an <a> that
   must look and measure like the raised accent button beside it — element-typed
   to keep the same specificity as button.raised-surface, which would otherwise
   win the colour and paint dark text on the accent fill. */
button.accent,
a.accent {
  background: var(--color-accent);
  color: var(--color-text-on-dark);
}

#start-screen {
  height: 100dvh;
  width: 100dvw;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--space-4);
  text-align: center;
  padding: var(--space-4);
}

#start-screen h1 {
  font-size: var(--text-lg);
  font-weight: 700;
  margin: 0;
}

#presentation-screen {
  position: relative;
  height: 100dvh;
  width: 100dvw;
  display: none;
  background: var(--color-video-backdrop);
}

#slide-image {
  width: 100%;
  height: 100%;
  object-fit: contain;
}

#speaking-indicator {
  position: absolute;
  top: var(--space-3);
  left: 50%;
  transform: translateX(-50%);
  padding: var(--space-1) var(--space-3);
  font-size: var(--text-sm);
  opacity: 0;
  transition: opacity 200ms ease;
}

#speaking-indicator.active {
  opacity: 1;
}

#mic-status {
  position: absolute;
  top: var(--space-3);
  right: var(--space-3);
  padding: var(--space-1) var(--space-2);
  font-size: var(--text-sm);
  max-width: 60%;
}

/* R2.9: control fade — 250ms out, 150ms back in, per the spec's exact timings. */
#control-bar {
  position: absolute;
  left: 0;
  right: 0;
  bottom: max(var(--space-4), env(safe-area-inset-bottom));
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  padding: 0 var(--space-3);
  transition: opacity 150ms ease;
  opacity: 1;
}

#control-bar.faded {
  opacity: 0;
  pointer-events: none;
  transition: opacity 250ms ease;
}

#slide-counter {
  font-size: var(--text-sm);
  padding: var(--space-1) var(--space-2);
}

/* R2.11 #2: every tappable control is at least 44x44. Five controls have to fit
   inside a 320px viewport (288px of content box), and the default button
   padding spends 48px per button on horizontal air — enough that the flex row
   squeezes the text input down to 32x37. It trades that air for the 44px floor:
   narrower padding, explicit minimums, no overflow at any of the three widths. */
#control-bar button {
  padding-left: var(--space-2);
  padding-right: var(--space-2);
  min-width: 44px;
  min-height: 44px;
}

#text-input {
  flex: 1;
  min-width: 44px;
  min-height: 44px;
  font-size: var(--text-md);
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius);
  border: none;
}

/* Hold-to-talk never fades (spec R2.8) — sits below the control bar, its own
   fixed position so it's unaffected by the bar's opacity transition. */
#talk-btn {
  position: absolute;
  left: 50%;
  bottom: max(calc(var(--space-5) * 3), calc(env(safe-area-inset-bottom) + 96px));
  transform: translateX(-50%);
  width: 72px;
  height: 72px;
  /* 50% is an accepted exception to the one-corner-radius rule: this makes
     the button circular, which is a different primitive from the moulded
     rectangular radius --radius describes elsewhere — not a second radius
     value competing with it. */
  border-radius: 50%;
  font-size: var(--text-lg);
}

#talk-btn.talking {
  background: var(--color-danger);
}

/* Same bottom value as #talk-btn, literally duplicated rather than shared via
   a variable so #talk-btn's own rule is never touched (its centre must stay
   put — see the comment on it in index.html). Offset is anchored off the 50%
   centre line (not a fixed right:Npx off the viewport edge) plus talk-btn's
   own half-width (72px / 2 = 36px) plus a --space-3 gap, so the gap to
   #talk-btn holds at every viewport width instead of drifting. No
   border-radius here — it inherits var(--radius) from .raised-surface,
   keeping #talk-btn's circle the one documented exception. */
#pause-btn {
  position: absolute;
  left: calc(50% + 36px + var(--space-3));
  bottom: max(calc(var(--space-5) * 3), calc(env(safe-area-inset-bottom) + 96px));
  padding-left: var(--space-2);
  padding-right: var(--space-2);
  min-width: 44px;
  min-height: 44px;
  /* Visibility is toggled via .active from app.js, driven off
     ActiveSpeakersChanged — never optimistically on click. opacity +
     visibility + pointer-events (not display) so it can transition and drops
     out of the tab order while hidden without ever being removed from the DOM. */
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transition: opacity 200ms ease, visibility 200ms ease;
}

#pause-btn.active {
  opacity: 1;
  visibility: visible;
  pointer-events: auto;
}

/* Top-left, mirroring #mic-status's top-right placement. Never fades — it's a
   sibling of #control-bar, not a child, so the fade rule never touches it.
   Same padding/min-size override as #control-bar button, for the same reason:
   the default button padding is wider than this control needs. */
#contact-btn {
  position: absolute;
  top: var(--space-3);
  left: var(--space-3);
  padding-left: var(--space-2);
  padding-right: var(--space-2);
  min-width: 44px;
  min-height: 44px;
}

#lead-overlay {
  position: absolute;
  inset: 0;
  display: none;
  align-items: center;
  justify-content: center;
  background: var(--color-overlay-scrim);
  padding: var(--space-4);
}

#lead-card {
  width: 100%;
  max-width: 420px;
  padding: var(--space-4);
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}

#lead-card input,
#lead-card select {
  font-size: var(--text-md);
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius);
  border: 1px solid var(--color-border);
}

/* iOS renders a bare <select> at ~32px tall — under the 44px tap-target
   floor — so it needs an explicit min-height on top of the shared rule
   above. Background/text colour are explicit because a plain <select> does
   not reliably inherit them the way a styled input does. The native dropdown
   arrow itself is left alone (see spec) — styling it needs an
   un-tokenisable background-image. */
#lead-card select {
  min-height: 44px;
  background: var(--color-surface);
  color: var(--color-text);
}

/* Flex row, not absolute positioning: at 320px the h2 below already wraps to
   two lines, and an absolutely-positioned 44px close button would land on
   top of that second line. */
#lead-card-header {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--space-2);
}

#lead-card-header h2 {
  flex: 1;
  min-width: 0;
}

#lead-close-btn {
  padding-left: var(--space-2);
  padding-right: var(--space-2);
  min-width: 44px;
  min-height: 44px;
  flex-shrink: 0;
}

#lead-card h2 {
  font-size: var(--text-lg);
  margin: 0;
  color: var(--color-text);
}

#whatsapp-link {
  display: block;
  text-align: center;
  text-decoration: none;
}

/* .status must NOT pin a colour. It is used on two different backgrounds:
   #lead-status sits inside #lead-card (a .raised-surface, which already sets
   the dark-on-white colour), while #start-status sits directly on the dark
   page background and needs body's light text. Pinning --color-text here
   rendered the start screen's status at ~1.1 contrast — invisible. Inherit
   instead, so each one picks up whichever surface it actually sits on. */
.status { color: inherit; }
.warn { color: var(--color-danger); }
