/* Base */
* {
  font-family: 'Nunito', Arial, sans-serif;
}

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

/* ---- AR overlay UI ----
   Reproduced from the LIVE 8th Wall apps this build replaces, which are still up:
   https://isobelandvan.8thwall.app/twcfi-{antoinette,marina,ar}/ . Their overlay markup and
   styles are inlined in the app8("...") call in each app's index.html; all three are
   byte-identical to each other, and NEWER than any export we hold. Custom property names,
   values and rule order below are theirs verbatim unless a comment says otherwise, so a
   future diff against a re-fetch of those pages stays readable. See the ORIGINAL AR UI
   block in experiences.js. */

:root {
  --primary-color: black;
  --bg-color: white;
  --overlay-bg: rgba(0, 0, 0, 0.7);
  --overlay-text: white;
  --border-style: 2px solid var(--primary-color);
  --high-z-index: 1000;
  --medium-z-index: 999;
  --transition-smooth: 0.2s ease;
  
    /* Topbar*/
  --topbar-width: 100%;
  --topbar-height: 150px;
  --topbar-background-color: #000;
  --topbar-align: center;
 
  /* Headphones icon */
  --headphones-top: calc(50% + 1px);
  --headphones-left: 50%;
  --headphones-width: 60px;
  --headphones-transform: translateX(-50%);

  /* Marker framing rectangle */
  --ar-overlay-top: 35%;
  --ar-overlay-left: 50%;
  --ar-overlay-width: 50vw;
  --ar-overlay-max-width: 50vh;
  --ar-overlay-max-height: calc(100vh - 160px);
  --ar-overlay-aspect-ratio: 4/3;
  --ar-overlay-border: 3px dashed rgba(255, 255, 255, 0.8);
  --ar-overlay-transform: translate(-50%, -50%);
  --ar-background-opacity: 0.4;

  /* Scan prompt */
  --scan-prompt-top: 70%;
  --scan-prompt-left: 50%;
  --scan-prompt-font-size: 16px;
  --scan-prompt-padding: 15px 35px;
  --scan-prompt-min-width: 300px;
  --scan-prompt-transform: translateX(-50%);

  /* Headphone prompt */
  --headphone-prompt-top: 30%;
  --headphone-prompt-left: 50%;
  --headphone-prompt-font-size: 14px;
  --headphone-prompt-padding: 10px 25px;
  --headphone-prompt-min-width: 200px;
  --headphone-prompt-transform: translate(-50%, -50%);
}

/* UI wrapper: hidden until the engine fires realityready, then fades in. Not in the
   originals, which instead set display:none on each overlay element individually and
   revealed them one by one from their own realityready handler. Same effect, one place.

   position/z-index are load-bearing despite the element having no size of its own (every
   child is fixed or absolute, so this stays a zero-height block that intercepts no taps).
   4DViews puts z-index:1 on the renderer canvas (WEB4DS's waiterParent), and a mid-fade
   opacity between 0 and 1 makes this element a stacking context whose children's z-index
   is then scoped to it -- so without a z-index here the whole overlay renders BEHIND the
   camera feed for the half second of the fade, and pops in front when it ends. Stays below
   both gates (2000/3000). */
#ui-container {
  position: relative;
  z-index: 10;
  opacity: 0;
  transition: opacity 0.5s ease-in-out;
  display: none;
}

#ui-container.ready {
  opacity: 1;
}

/* ---- Back arrow ----
   THE ORIGINALS' NAV BAR IS GONE, and this replaces it. Theirs was a full-width black 80px
   bar holding the three storytellers as 80x60 thumbnails, which was the whole set when there
   was one experience per person. Nine experiences do not fit that shape: nine thumbnails plus
   gaps is 880px, and a bar of the current storyteller's three TAKES (what this build shipped
   first) put a switcher over the camera feed whose every tap is a full page load, restarting
   the narration and re-downloading 35-94 MB. So take selection lives on the menu only and the
   in-experience chrome is one back arrow.

   Floating rather than in a bar: with the thumbnails gone the bar was 80px of black over the
   top of the camera feed holding a single small arrow. The translucent disc is legible over
   any camera feed without taking that space, and 44px is the minimum comfortable tap target.

   z-index sits above the overlay UI and below both gates (2000/3000). It is fixed rather than
   absolute now that there is no bar to be positioned inside. */
#nav-back {
  position: fixed;
  top: max(12px, env(safe-area-inset-top));
  left: max(12px, env(safe-area-inset-left));
  width: 44px;
  height: 44px;
  box-sizing: border-box;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  background-color: rgba(0, 0, 0, 0.55);
  color: white;
  font-size: 22px;
  line-height: 1;
  text-decoration: none;
  z-index: 1001;
  transition: background-color var(--transition-smooth);
  -webkit-tap-highlight-color: transparent;
}

#nav-back:active {
  background-color: rgba(0, 0, 0, 0.85);
}

/* "Point camera at image target" prompt, shown until the scan is placed. */
#scan-prompt {
  position: fixed;
  top: var(--scan-prompt-top);
  left: var(--scan-prompt-left);
  transform: var(--scan-prompt-transform);
  font-size: var(--scan-prompt-font-size);
  padding: var(--scan-prompt-padding);
  min-width: var(--scan-prompt-min-width);
  /* Not in the originals: they had no max-width and a 300px min-width, which overflows a
     narrow phone once the SLAM coaching strings replace the default copy. */
  max-width: 90vw;
  box-sizing: border-box;
}

/* Marker framing rectangle: a dashed box with this storyteller's own printed card faded
   into it, so the visitor knows what to point at and how big it wants to be in frame.
   Hidden for good once the scan is placed (hologram-4ds.js). */
#ar-overlay-container {
  position: fixed;
  top: var(--ar-overlay-top);
  left: var(--ar-overlay-left);
  transform: var(--ar-overlay-transform);
  width: var(--ar-overlay-width);
  aspect-ratio: var(--ar-overlay-aspect-ratio);
  max-width: var(--ar-overlay-max-width);
  max-height: var(--ar-overlay-max-height);
  z-index: var(--medium-z-index);
  pointer-events: none;
}

#ar-outline {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  border: var(--ar-overlay-border);
  pointer-events: none;
}

#ar-background-image {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  opacity: var(--ar-background-opacity);
  z-index: -1;
  pointer-events: none;
}

#headphone-prompt {
  position: absolute;
  top: var(--headphone-prompt-top);
  left: var(--headphone-prompt-left);
  transform: var(--headphone-prompt-transform);
  font-size: var(--headphone-prompt-font-size);
  padding: var(--headphone-prompt-padding);
  min-width: var(--headphone-prompt-min-width);
  z-index: var(--high-z-index);
}

#headphones-icon {
  position: absolute;
  top: var(--headphones-top);
  left: var(--headphones-left);
  transform: var(--headphones-transform);
  z-index: var(--high-z-index);
  width: var(--headphones-width);
  height: auto;
}

/* Shared look for the two overlay prompts. */
#scan-prompt,
#headphone-prompt {
  background: var(--overlay-bg);
  color: var(--overlay-text);
  font-weight: bold;
  text-align: center;
  z-index: var(--high-z-index);
  line-height: 1.4;
  border-radius: 0;
}

/* Bottom-centre playback controls, shown once the scan is placed. */
#audio-controls {
  position: fixed;
  bottom: 10px;
  left: 50%;
  transform: translateX(-50%);
  z-index: var(--high-z-index);
  display: none;
}

#audio-controls-container {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
}

/* The narration element itself is never seen: #play-button and the progress pill are its
   entire interface. Parked off-screen rather than display:none, which some mobile browsers
   treat as grounds to skip loading or playing the media. Verbatim from the originals. */
#audio-player {
  position: absolute;
  left: -9999px;
  opacity: 0;
  pointer-events: none;
}

#button-controls {
  display: flex;
  gap: 15px;
  align-items: center;
}

#time-progress-container {
  width: 100%;
  display: flex;
  flex-direction: column;
  gap: 5px;
  align-items: center;
}

#progress-container {
  width: 320px;
  max-width: 90vw;
  height: 32px;
  background: var(--bg-color);
  border-radius: 16px;
  border: var(--border-style);
  position: relative;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 16px;
  box-sizing: border-box;
}

#progress-bar {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: calc(100% - 120px);
  height: 6px;
  background: rgba(0, 0, 0, 0.2);
  border-radius: 3px;
  overflow: hidden;
}

#progress-fill {
  height: 100%;
  background: var(--primary-color);
  width: 0%;
  transition: width 0.1s ease;
  border-radius: 3px;
}

#time-display {
  display: flex;
  justify-content: space-between;
  width: 100%;
  font-size: 14px;
  font-weight: 600;
  color: var(--primary-color);
  position: relative;
  z-index: 10;
  pointer-events: none;
}

.control-btn {
  background-color: var(--bg-color);
  border: var(--border-style);
  border-radius: 25px;
  padding: 16px 32px;
  color: var(--primary-color);
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: all var(--transition-smooth);
  font-size: 16px;
  font-weight: 600;
  white-space: nowrap;
}

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

/* ---- Intro / Continue gate (its click unlocks WebAudio) ---- */
#intro-overlay {
  position: fixed;
  inset: 0;
  z-index: 2000;
  background: rgba(0, 0, 0, 0.9);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
  opacity: 1;
  transition: opacity 0.5s ease-in-out;
}

#intro-overlay.hidden {
  opacity: 0;
  pointer-events: none;
}

#intro-content {
  max-width: 480px;
  text-align: center;
  color: white;
  display: flex;
  flex-direction: column;
  align-items: center;
}

/* The gate is the storyteller's name, the client's introduction to this scan, and the
   Continue button. It carries no INSTRUCTIONS: it used to repeat the scan and headphone
   prompts, which the camera feed says a moment later, and two instruction screens in a row is
   what the client reported. Description is not instruction, and the block below is theirs. */
#intro-title {
  font-size: 28px;
  font-weight: bold;
  line-height: 1.4;
  margin: 0 0 32px;
}

/* ---- The client's intro copy (their StorytellersNewInterface.pdf) ----
   Their nine pages are screenshots of this gate with the copy set into it, so the sizes and
   spacing below are measured off those pages rather than chosen: the screenshot is 387pt wide
   for a ~390px phone screen, which puts their points and our pixels at 1:1. River and place
   are 15px bold on 24px leading; the description is 14px on the same 24px, which is the 1.7
   line-height it is set with here.

   Filled by overlay-ui.js. Both stay in the flow when empty (a storyteller with no `intro`
   yet), which costs nothing: an empty <p> with no margin collapses to the margins around it. */
#intro-location {
  margin: 0 0 36px;
  font-size: 15px;
  font-weight: 700;
  line-height: 1.6;
}

#intro-river,
#intro-place {
  display: block;
}

/* max-width, not a character count: their measure wraps Tom's sentence to four lines at about
   230px, and the point of holding it narrow is that this is read at arm's length on a phone
   before the camera opens. 280px keeps that shape without setting a wrap point per sentence. */
#intro-description {
  margin: 0 0 20px;
  max-width: 280px;
  font-size: 15px;
  line-height: 1.7;
}

/* "Please allow camera access." The only instruction on this screen, and the only piece of
   its copy not in the client's PDF. Set quieter and a size down from the description so the
   client's own words stay the voice of the screen and this reads as the practical aside it
   is. Closer to the description (20px above, against 36px below) so it groups with the text
   rather than with the button, which keeps the button's spacing as the PDF has it. */
#intro-camera-note {
  margin: 0 0 36px;
  font-size: 14px;
  line-height: 1.5;
  color: rgba(255, 255, 255, 0.75);
}

/* Niantic Spatial attribution, required by the XR Engine License Agreement (see
   lib/xr/LICENSE and the note in index.html). Deliberately quiet, but it must stay
   visible and legible: do not hide it, shrink it further, or drop the licence link. */
#attribution {
  margin: 24px 0 0;
  font-size: 11px;
  line-height: 1.4;
  color: rgba(255, 255, 255, 0.6);
  max-width: 420px;
}

#attribution a {
  color: rgba(255, 255, 255, 0.75);
}

/* ---- Camera permission / AR error gate ---- */
#camera-error-overlay {
  position: fixed;
  inset: 0;
  z-index: 3000;
  background: rgba(0, 0, 0, 0.92);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
  overflow-y: auto;
  opacity: 1;
  transition: opacity 0.3s ease-in-out;
}

#camera-error-overlay.hidden {
  opacity: 0;
  pointer-events: none;
  display: none;
}

#camera-error-content {
  max-width: 480px;
  text-align: center;
  color: white;
}

#camera-error-title {
  font-size: 26px;
  font-weight: bold;
  margin: 0 0 16px;
}

#camera-error-text {
  font-size: 16px;
  line-height: 1.4;
  margin: 0 0 24px;
}

/* Shared button style for the gates */
.gate-btn {
  background: rgba(255, 255, 255, 0.95);
  color: black;
  border: 2px solid white;
  border-radius: 25px;
  padding: 14px 36px;
  font-size: 16px;
  font-weight: 700;
  cursor: pointer;
  transition: transform 0.2s ease;
}

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

/* Hide A-Frame's enter VR / AR buttons */
.a-enter-vr,
.a-enter-ar,
.a-enter-vr-button,
.a-enter-ar-button {
  display: none !important;
}
