:root {
  --blush: #f7e9e3;
  --rose: #d98a8a;
  --rose-dark: #b96a6a;
  --plum: #4a3640;
  --gold: #c9a24b;
  --cream: #fffaf6;
  --shadow: 0 10px 40px rgba(74, 54, 64, 0.18);
}

* { box-sizing: border-box; margin: 0; padding: 0; }

/* The `hidden` attribute must always win. Author rules like `.overlay { display:flex }`
   and `.countdown { display:flex }` otherwise override the UA's [hidden]{display:none}
   and leave those elements stuck on screen. */
[hidden] { display: none !important; }

html, body {
  height: 100%;
  font-family: "Segoe UI", system-ui, -apple-system, sans-serif;
  background: linear-gradient(160deg, var(--blush), var(--cream));
  color: var(--plum);
  overflow: hidden;
  user-select: none;
  -webkit-user-select: none;
}

/* Build-version badge: a tiny, unobtrusive marker (bottom-centre, above the
   safe-area inset) so a tester can confirm the device loaded the latest code. */
#version-badge {
  position: fixed;
  left: 50%;
  bottom: calc(2px + env(safe-area-inset-bottom));
  transform: translateX(-50%);
  z-index: 9999;
  font: 10px/1.3 ui-monospace, Menlo, monospace;
  color: rgba(74, 54, 64, 0.45);
  background: rgba(255, 255, 255, 0.4);
  padding: 1px 7px;
  border-radius: 6px;
  pointer-events: none;
  white-space: nowrap;
}
#version-badge:empty { display: none; }

/* Diagnostic readout (only shown with ?debug=1) for the spoken-name capture. */
.name-debug {
  font: 11px/1.4 ui-monospace, Menlo, monospace;
  color: var(--rose-dark);
  background: rgba(0, 0, 0, 0.04);
  padding: 6px 10px;
  border-radius: 8px;
  max-width: 92vw;
  word-break: break-word;
  white-space: pre-wrap;
}

/* `100dvh` (dynamic viewport height) tracks the *visible* area as iOS Safari's
   toolbar shows/hides. Plain `100vh` is the LARGE viewport, so anything docked to
   the bottom (the recording finish/accept buttons) sits behind the toolbar and
   off-screen. The `100vh` line is the fallback for browsers without dvh. */
#app { height: 100vh; height: 100dvh; width: 100vw; position: relative; }

.screen {
  position: absolute;
  inset: 0;
  display: none;
  flex-direction: column;
  align-items: center;
  /* "safe center" centers content when it fits, but falls back to top-aligned
     (no clipping) when content is taller than the screen — so the Submit button
     is never cut off on a landscape iPad, and there's no dead space when some
     children (hashtag/admin link) are hidden. overflow-y allows scrolling. */
  justify-content: safe center;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  padding: 4vh 6vw;
  text-align: center;
  gap: 20px;
  animation: fade 0.4s ease;
}
.screen.active { display: flex; }

@keyframes fade {
  from { opacity: 0; transform: translateY(12px); }
  to { opacity: 1; transform: translateY(0); }
}

h1 { font-size: clamp(2.2rem, 6vw, 4rem); font-weight: 700; letter-spacing: -0.5px; }
h2 { font-size: clamp(1.6rem, 4vw, 2.6rem); font-weight: 700; }
.subhead { font-size: clamp(1.1rem, 2.4vw, 1.6rem); color: var(--rose-dark); }
.prompt {
  font-size: clamp(1.1rem, 2.6vw, 1.7rem);
  font-style: italic;
  color: var(--plum);
  max-width: 800px;
  line-height: 1.4;
}
.hearts { font-size: clamp(3rem, 10vw, 6rem); animation: float 3s ease-in-out infinite; }
/* Understated typographic flourish used in place of decorative emoji. */
.ornament { width: 56px; height: 2px; border-radius: 2px; background: var(--gold); opacity: 0.8; margin: 0 auto 4px; }
@keyframes float { 0%,100%{transform:translateY(0)} 50%{transform:translateY(-12px)} }

.welcome-inner { display: flex; flex-direction: column; align-items: center; gap: 20px; }
.hashtag { color: var(--gold); font-weight: 600; letter-spacing: 1px; font-size: 1.2rem; }

/* Buttons */
.btn {
  border: none;
  border-radius: 999px;
  font-size: clamp(1.1rem, 2.4vw, 1.5rem);
  padding: 18px 40px;
  cursor: pointer;
  font-weight: 600;
  transition: transform 0.12s ease, box-shadow 0.12s ease, background 0.12s ease;
}
.btn:active { transform: scale(0.96); }
.btn-primary { background: var(--rose); color: white; box-shadow: var(--shadow); }
.btn-primary:hover { background: var(--rose-dark); }
.btn-big { padding: 26px 64px; font-size: clamp(1.3rem, 3vw, 1.9rem); }
.btn-ghost { background: transparent; color: var(--rose-dark); box-shadow: none; }
.btn-danger { background: #c25b5b; color: white; }
.btn-secondary { background: var(--cream); color: var(--plum); box-shadow: var(--shadow); }

/* Choice cards */
.choices { display: flex; gap: 28px; flex-wrap: wrap; justify-content: center; }
.choice {
  width: 220px; height: 220px;
  border: 3px solid transparent;
  border-radius: 28px;
  background: var(--cream);
  box-shadow: var(--shadow);
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 16px; cursor: pointer;
  transition: transform 0.15s ease, border-color 0.15s ease;
}
.choice:hover { transform: translateY(-6px); border-color: var(--rose); }
.choice:active { transform: scale(0.97); }
.choice-icon { font-size: 4rem; }
.choice-label { font-size: 1.3rem; font-weight: 600; }

/* Camera */
.camera-wrap {
  position: relative;
  width: min(94vw, 1280px);
  max-height: 72vh;         /* sized by whichever limit hits first (width or height) */
  aspect-ratio: 16 / 9;
  flex-shrink: 0;            /* don't let flexbox squash the video box */
  background: #000;
  border-radius: 24px;
  overflow: hidden;
  box-shadow: var(--shadow);
}

/* Welcome text overlaid on the live feed (landing state) */
.stage-top {
  position: absolute;
  top: 0; left: 0; right: 0;
  padding: 26px 20px 60px;
  text-align: center;
  color: #fff;
  background: linear-gradient(to bottom, rgba(0,0,0,0.55), rgba(0,0,0,0));
  pointer-events: none;
  transition: opacity 0.3s ease;
}
.stage-top .hearts { font-size: clamp(2rem, 5vw, 3rem); }
.couple-photo {
  width: clamp(80px, 12vw, 130px);
  height: clamp(80px, 12vw, 130px);
  border-radius: 50%;
  object-fit: cover;
  border: 4px solid #fff;
  box-shadow: 0 6px 22px rgba(0,0,0,0.4);
  margin: 0 auto 10px;
  display: block;
}
.stage-top h1 { font-size: clamp(1.6rem, 4vw, 2.6rem); text-shadow: 0 2px 12px rgba(0,0,0,0.5); }
.stage-top .subhead { color: #ffe9e9; text-shadow: 0 2px 10px rgba(0,0,0,0.5); }

.cam-fallback {
  position: absolute; inset: 0;
  display: flex; flex-direction: column; align-items: center;
  /* "safe center" centers when the message + recovery guide fit, but falls back
     to top-aligned (no clipping) when they're taller than a phone screen, so the
     Enable button is always reachable. overflow-y lets the guest scroll to it. */
  justify-content: safe center;
  overflow-y: auto; -webkit-overflow-scrolling: touch;
  gap: 16px; background: var(--blush); color: var(--plum); text-align: center;
  font-size: 1.3rem;
  padding: max(30px, env(safe-area-inset-top)) 30px
           max(30px, calc(20px + env(safe-area-inset-bottom)));
}
.cam-fallback-detail {
  font-size: 0.85rem; opacity: 0.6; font-family: monospace;
  word-break: break-word; max-width: 90%; margin: 0;
}

/* Visual recovery guide for a blocked camera on iPhone Chrome. */
.cam-guide {
  width: 100%; max-width: 420px;
  background: rgba(255,255,255,0.65); border-radius: 16px;
  padding: 18px 20px; text-align: left;
}
.cam-guide-steps {
  margin: 0; padding: 0; list-style: none;
  display: flex; flex-direction: column; gap: 14px;
  counter-reset: step;
}
.cam-guide-steps li {
  display: flex; align-items: flex-start; gap: 12px;
  font-size: 1rem; line-height: 1.35;
}
.cam-guide-steps li::before {
  counter-increment: step; content: counter(step);
  flex: 0 0 auto; width: 24px; height: 24px; margin-top: 1px;
  border-radius: 50%; background: var(--plum); color: #fff;
  font-size: 0.85rem; font-weight: 700;
  display: flex; align-items: center; justify-content: center;
}
.cam-guide-ico { flex: 0 0 auto; }
.cam-guide-ico svg { width: 22px; height: 22px; display: block; opacity: 0.7; }
.cam-guide-or {
  margin: 16px 0 0; font-size: 0.9rem; opacity: 0.75; text-align: center;
  line-height: 1.35;
}

/* Prompt banner shown DURING recording */
.in-video-prompt {
  position: absolute;
  left: 50%; bottom: 24px;
  transform: translateX(-50%);
  background: rgba(74,54,64,0.82);
  color: #fff;
  padding: 16px 30px;
  border-radius: 999px;
  font-size: clamp(1.1rem, 2.6vw, 1.7rem);
  font-weight: 600;
  max-width: 90%;
  text-align: center;
  animation: promptIn 0.4s ease;
  box-shadow: 0 6px 24px rgba(0,0,0,0.35);
}
@keyframes promptIn {
  from { opacity: 0; transform: translate(-50%, 16px) scale(0.96); }
  to { opacity: 1; transform: translate(-50%, 0) scale(1); }
}
#preview, #photo-result, #photo-canvas {
  width: 100%; height: 100%; object-fit: cover;
  /* No mirror: the live preview matches the (un-mirrored) recording & playback. */
}
.rec-badge {
  position: absolute; top: 16px; left: 16px;
  background: rgba(200,40,40,0.92); color: white;
  padding: 8px 16px; border-radius: 999px; font-weight: 700;
  font-size: 1.1rem; letter-spacing: 1px;
  animation: blink 1s steps(2, start) infinite;
}
@keyframes blink { 50% { opacity: 0.4; } }
.countdown {
  position: absolute; inset: 0; display: flex; align-items: center; justify-content: center;
  font-size: 10rem; font-weight: 800; color: white; background: rgba(0,0,0,0.45);
  text-shadow: 0 4px 20px rgba(0,0,0,0.5);
}
.capture-controls { display: flex; gap: 18px; flex-wrap: wrap; justify-content: center; }

/* Live captions shown under the video while recording */
.live-caption {
  min-height: 1.6em;
  max-width: min(86vw, 1000px);
  margin: 4px auto 0;
  font-size: clamp(1.1rem, 2.6vw, 1.7rem);
  font-weight: 600;
  line-height: 1.35;
  color: var(--plum);
  background: var(--cream);
  border-radius: 14px;
  padding: 12px 22px;
  box-shadow: var(--shadow);
  text-align: center;
}
.live-caption:empty { visibility: hidden; }

/* Discreet admin gear — bottom corner, faint, so guests don't wander in.
   Only visible on the landing screen (toggled via body class). */
#admin-link {
  position: fixed; bottom: 12px; right: 14px;
  font-size: 1.2rem; text-decoration: none; opacity: 0.18;
  padding: 8px; z-index: 40; transition: opacity 0.2s;
  display: none;
}
#admin-link:hover { opacity: 0.7; }
body.on-landing #admin-link { display: block; }

/* Voice-message capture: an orb over a calm background covering the live feed. */
.audio-viz {
  position: absolute; inset: 0; display: flex; flex-direction: column;
  align-items: center; justify-content: center; gap: 22px;
  background: radial-gradient(120% 120% at 50% 0%, #5a4350, var(--plum) 70%);
  color: var(--cream);
}
.audio-orb {
  width: 120px; height: 120px; border-radius: 50%;
  background: radial-gradient(circle at 50% 38%, var(--rose), var(--rose-dark));
}
.audio-orb.pulsing { animation: audiopulse 1.6s ease-out infinite; }
@keyframes audiopulse {
  0%   { box-shadow: 0 0 0 0 rgba(217, 138, 138, 0.55); }
  70%  { box-shadow: 0 0 0 40px rgba(217, 138, 138, 0); }
  100% { box-shadow: 0 0 0 0 rgba(217, 138, 138, 0); }
}
.audio-label { font-size: 1.2rem; opacity: 0.92; }
.audio-result { display: block; width: min(90%, 440px); margin: 14px auto 0; }

/* Discreet marketing-site link — bottom-left, mirrors the admin link.
   Testing convenience; only visible on the landing screen. */
#marketing-link {
  position: fixed; bottom: 12px; left: 14px;
  font-size: 0.8rem; text-decoration: none; color: var(--plum);
  opacity: 0.18; padding: 8px; z-index: 40; transition: opacity 0.2s;
  display: none;
}
#marketing-link:hover { opacity: 0.7; }
body.on-landing #marketing-link { display: block; }

/* Visible Admin link on the landing screen (for setup/testing) */
.admin-link-visible {
  display: none;
  margin-top: 8px;
  color: var(--rose-dark);
  text-decoration: none;
  font-size: 0.95rem;
  font-weight: 600;
  opacity: 0.75;
  border: 2px solid var(--rose);
  border-radius: 999px;
  padding: 8px 20px;
  transition: background 0.15s, color 0.15s;
}
.admin-link-visible:hover { background: var(--rose); color: #fff; opacity: 1; }
body.on-landing .admin-link-visible { display: inline-block; }
.live-caption .interim { opacity: 0.55; }

/* Form fields */
.field { display: flex; flex-direction: column; gap: 8px; width: min(90vw, 620px); text-align: left; font-size: 1.2rem; font-weight: 600; }
.field small { color: var(--rose-dark); font-weight: 400; }
.field input[type="text"], .field textarea {
  font-size: 1.3rem; padding: 16px; border-radius: 16px;
  border: 2px solid #e3cfc6; background: var(--cream); font-family: inherit; color: var(--plum);
}
.field input:focus, .field textarea:focus { outline: none; border-color: var(--rose); }
.checkbox-field { flex-direction: row; align-items: center; gap: 14px; cursor: pointer; }
.checkbox-field input { width: 28px; height: 28px; accent-color: var(--rose); }
.row { display: flex; gap: 18px; align-items: center; }
.prefill-status {
  font-size: 1.05rem; color: var(--rose-dark); font-weight: 600;
  background: #fff3ef; border-radius: 12px; padding: 10px 18px;
}
.details-photo {
  max-height: 30vh; max-width: min(70vw, 380px);
  border-radius: 18px; object-fit: cover;
  border: 4px solid #fff; box-shadow: var(--shadow);
}
.row { flex-wrap: wrap; justify-content: center; }
.btn-small { font-size: 0.95rem; padding: 8px 18px; }

/* "Say your name" page */
.sayname-orb {
  width: clamp(110px, 18vh, 170px);
  height: clamp(110px, 18vh, 170px);
  border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  background: var(--cream); box-shadow: var(--shadow);
}
/* A quiet listening indicator — a soft inner dot rather than a mic emoji. */
.sayname-orb::before {
  content: ""; width: 30%; height: 30%; border-radius: 50%;
  background: var(--rose); opacity: 0.85;
}
.sayname-orb.pulsing { animation: orbpulse 1.3s ease-in-out infinite; }
@keyframes orbpulse {
  0%, 100% { box-shadow: 0 0 0 0 rgba(217,138,138,0.5); transform: scale(1); }
  50% { box-shadow: 0 0 0 22px rgba(217,138,138,0); transform: scale(1.05); }
}
.sayname-field { align-items: center; text-align: center; }
.sayname-field span { text-align: center; }
#sayname-input {
  font-size: clamp(1.6rem, 5vw, 2.6rem);
  font-weight: 700; color: var(--plum); text-align: center;
}
.from-confirm { font-size: 1.2rem; color: var(--plum); }
.from-confirm strong { color: var(--rose-dark); }
.linkbtn {
  background: none; border: none; color: var(--rose-dark); cursor: pointer;
  font-size: 1rem; text-decoration: underline; padding: 0; font-weight: 600;
}
#name-mic.listening { background: #c25b5b; color: #fff; animation: blink 1s steps(2,start) infinite; }

/* Overlay */
.overlay {
  position: absolute; inset: 0; background: rgba(255,250,246,0.92);
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 24px;
  font-size: 1.4rem; z-index: 50;
}
.spinner {
  width: 64px; height: 64px; border-radius: 50%;
  border: 6px solid #e3cfc6; border-top-color: var(--rose);
  animation: spin 0.9s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }
/* Upload-failure panel inside the saving overlay (spinner is swapped for this). */
#saving-error { display: flex; flex-direction: column; align-items: center; gap: 20px; max-width: 32rem; text-align: center; }
#saving-error-msg { line-height: 1.4; color: var(--plum); }

/* --- Landscape / short viewports (e.g. iPad in landscape) ----------------
   Tighten vertical spacing, size the camera by height so it never squishes,
   shrink the details photo, and drop the hashtag (shown elsewhere) so the
   Submit button always fits. */
@media (orientation: landscape) and (max-height: 820px) {
  .screen { gap: 12px; padding: 3vh 5vw; }
  /* Size the video by height (aspect-ratio keeps 16:9) so it fills the screen
     without squishing, while max-height leaves room for the buttons below. */
  .camera-wrap { width: auto; height: 66vh; max-height: 66vh; }
  .welcome-hashtag, #welcome-hashtag { display: none; }
  .details-photo { max-height: 20vh; }
  .field { gap: 4px; }
  h2 { font-size: clamp(1.3rem, 3vw, 2rem); }
  .stage-top { padding: 12px 20px 36px; }
}

/* Very short screens: shrink the video + details photo so everything fits. */
@media (orientation: landscape) and (max-height: 620px) {
  .camera-wrap { height: 60vh; max-height: 60vh; }
  .details-photo { max-height: 14vh; }
  .screen { gap: 8px; padding: 2vh 5vw; }
}

/* --- Full-bleed camera with the controls floating over it — ALL devices ------
   The live feed fills the whole capture screen; the prompt, captions, buttons,
   and audio player float over the bottom on a readability scrim — a clean,
   immersive kiosk experience on phone, tablet, and desktop alike. Scoped to
   #screen-stage so the name/review forms keep their normal centered layout.
   object-fit:contain letterboxes ANY aspect (portrait or landscape) so the full
   frame always shows; the #000 background makes the bars black. */
#screen-stage {
  padding: 0;
  gap: 0;
  justify-content: flex-end;   /* dock the floating controls to the bottom */
}
#screen-stage .camera-wrap {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  max-height: none;
  aspect-ratio: auto;
  border-radius: 0;
  box-shadow: none;
  z-index: 0;
}
#screen-stage #preview,
#screen-stage #photo-result,
#screen-stage #photo-canvas {
  object-fit: contain;
}
/* Scrim behind the floating controls so light buttons/text stay legible. */
#screen-stage::before {
  content: "";
  position: absolute;
  left: 0; right: 0; bottom: 0;
  height: 45%;
  background: linear-gradient(to top, rgba(0,0,0,0.62), rgba(0,0,0,0));
  z-index: 1;
  pointer-events: none;
}
/* Lift the prompt, captions, buttons, hashtag, and audio player over the video. */
#screen-stage > .live-caption,
#screen-stage > .prompt,
#screen-stage > .capture-controls,
#screen-stage > .hashtag,
#screen-stage > .audio-result {
  position: relative;
  z-index: 2;
  width: 100%;
}
#screen-stage > .prompt {
  color: #fff;
  text-shadow: 0 2px 10px rgba(0,0,0,0.6);
  padding: 0 20px;
  margin-bottom: 4px;
}
/* Buttons: a docked, comfortably tappable column rather than a centered row. */
#screen-stage .capture-controls {
  flex-direction: column;
  align-items: center;
  gap: 10px;
  padding: 12px 18px calc(16px + env(safe-area-inset-bottom));
}
#screen-stage .capture-controls .btn {
  width: min(86vw, 460px);
  padding: 14px 26px;
  font-size: 1.05rem;
}
#screen-stage .capture-controls .btn-big {
  padding: 16px 26px;
  font-size: 1.18rem;
}
/* Ghost buttons need light text to read over the darkened video. */
#screen-stage .capture-controls .btn-ghost { color: #fff; }
/* The timed in-recording prompt moves up top so it never collides with Stop. */
#screen-stage .in-video-prompt {
  bottom: auto;
  top: 14%;
}
/* Captions sit just above the buttons. */
#screen-stage .live-caption {
  max-width: min(92vw, 700px);
  margin: 0 auto 6px;
  background: rgba(255, 250, 246, 0.92);
}
/* The video + controls take priority; hide the hashtag to give the frame room. */
#screen-stage .hashtag {
  display: none;
}
