/* ar.css — camera-overlay AR (the MediaStream fallback rendered by ar.js). */
/* AR is a FULL-SCREEN takeover, so it has to out-rank the app chrome. At z-index 10 it sat
   under #nav-panel (1000), #route-sheet (1000/1001) and the toast/off-route layer (1100):
   the header and the bottom sheet painted straight over it, and because this element is
   itself a stacking context, NOTHING inside could escape — the exit control, the maneuver
   banner, the off-route pill and the distance badge were all trapped at page-level 10 no
   matter what z-index they carried. That is why AR appeared to have no way out.
   1500 clears every navigation layer while staying BELOW the modal layers (visitor capture
   2000, alerts 2100), which must still be able to interrupt AR. */
#ar-overlay {
  position: fixed;
  inset: 0;
  z-index: 1500;
}

/* Full-bleed rear-camera feed behind the guidance overlay. */
#ar-overlay video {
  position: absolute;
  inset: 0;
  inline-size: 100%;
  block-size: 100%;
  object-fit: cover;
}

/* Direction arrow — a clean 2D SVG chevron (blue fill + white outline), matching the
   reference Live View. Centred on screen and rotated by ar.js to the eased travel bearing.
   Vector, so it stays crisp at any size; the drop shadow gives it the Google-Maps depth.
   No CSS transition here — the rotation is eased per-frame in JS (a transition would fight
   that and re-introduce lag/wobble). */
/* ── The single ground marker ───────────────────────────────────────────────────────
   One chevron laid onto the road. Position and size are FIXED here on purpose: the
   previous marks were sized by a 1/depth projection, so a distance carried on 5-15 m of
   GPS error decided how much of the screen they filled — which is how they came to
   explode in the foreground. Orientation is the only thing navigation drives.

   Centring uses `translate` (its own property) so `transform` is free for the 3D tilt;
   the two would otherwise overwrite each other every frame. */
.ar-arrow {
  position: absolute;
  /* Below the maneuver banner and the signal chip, above the road area — it can never
     collide with the HUD because it does not move. */
  inset-block-start: 62%;
  inset-inline-start: 50%;
  inline-size: clamp(120px, 34vw, 220px);
  aspect-ratio: 100 / 210; /* matches the viewBox: the chain, its edges and the shadow band */
  /* The NEAR chevron (69% down the element) is the point pinned to the ground; the rest of
     the chain recedes up the road from it. JS rewrites this same pair every frame. */
  translate: -50% -69%;
  /* Yaw pivots about the NEAR chevron — the point pinned to the ground — so the chain swings
     like arrows laid along the road from where you are standing, instead of the whole group
     orbiting a point in mid-air. */
  transform-origin: 50% 69%;
  pointer-events: none;
  z-index: 1;
  /* Both change every frame (transform = the 3D tilt, translate = the ground anchoring);
     promote once instead of re-layering per frame. */
  will-change: transform, translate;
  /* Two shadows, two jobs. The dark one plants the marker on the ground; the tight white one
     is what keeps a blue chevron legible against the things a campus camera actually points
     at — sky, glass, a blue hoarding — where blue-on-blue would otherwise disappear. */
  filter: drop-shadow(0 3px 7px rgb(0 0 0 / 45%)) drop-shadow(0 0 1.5px rgb(255 255 255 / 70%));
}
.ar-arrow__svg {
  display: block;
  inline-size: 100%;
  block-size: 100%;
}
/* Route Blue, solid. No white layer, no outline, no disc — one marking on the road, in a
   product-owned colour, never the tenant primary. The `edge` copy sits 9 units nearer the
   viewer inside the same tilted plane and is darkened, so the marking has a visible
   thickness: still one marker, but a solid one rather than a flat glyph on the glass. */
.ar-arrow__face {
  fill: var(--wf-route);
}
.ar-arrow__edge {
  fill: color-mix(in srgb, var(--wf-route) 45%, #000);
}
/* ── The solid marker (the default; ?arrow=flat falls back to the two-tone one) ──────────
   The flat marker is two fills; this one is an object on a road. Colours are MIXED from the
   same --wf-route token rather than hard-coded, so a tenant palette still drives it. */
.ar-stop-face-hi {
  stop-color: color-mix(in srgb, var(--wf-route) 58%, #fff);
}
.ar-stop-face-lo {
  stop-color: color-mix(in srgb, var(--wf-route) 88%, #000);
}
.ar-stop-wall-hi {
  stop-color: color-mix(in srgb, var(--wf-route) 55%, #000);
}
.ar-stop-wall-lo {
  stop-color: color-mix(in srgb, var(--wf-route) 22%, #000);
}
.ar-arrow--solid .ar-arrow__face {
  fill: url("#wfArrowFace");
}
.ar-arrow--solid .ar-arrow__wall {
  fill: url("#wfArrowWall");
}
/* The cast shadow: blurred in SVG, so it follows the chevron's real outline rather than the
   element's box, and laid further down the ground plane than the wall. That offset is what
   makes the marker read as sitting ON the path rather than floating above it. */
.ar-arrow__cast {
  fill: #000;
  fill-opacity: 0.5;
}
/* With a cast shadow of its own, the element-level filter is only doing the blue-on-blue
   legibility job now, so it drops the heavy contact shadow and keeps the tight halo. */
.ar-arrow--solid {
  filter: drop-shadow(0 0 1.6px rgb(255 255 255 / 70%));
}

/* The pulse travels ALONG the chain, away from the user: near chevron first, then the next,
   then the far one. A static chain says "this way"; a moving one says which way is forward,
   which is the question being asked. Opacity only — nothing moves, so it cannot be confused
   with the marker itself turning, and it costs no layout. Each link's resting and peak values
   come from the markup (--rest / --peak), so the recession is preserved at every moment of
   the cycle. Killed automatically under prefers-reduced-motion by transitions.css. */
@keyframes ar-arrow-flow {
  0%,
  55%,
  100% {
    opacity: var(--rest);
  }
  22% {
    opacity: var(--peak);
  }
}
.ar-arrow__link {
  animation: ar-arrow-flow 1.9s ease-in-out infinite;
  animation-delay: calc(var(--i) * 0.22s);
}

/* Remaining-distance badge. */
.ar-badge {
  position: absolute;
  inset-block-end: calc(32px + env(safe-area-inset-bottom, 0px));
  /* Inset clear of the exit pill (16px offset + ~118px wide) on BOTH sides, so the badge
     stays centred while never running under it. */
  inset-inline: 140px;
  text-align: center;
  color: var(--wf-paper);
  font-size: 20px;
  font-weight: 600;
  text-shadow: 0 1px 3px rgb(0 0 0 / 60%);
}

/* Close (✕) button — always visible so AR can be exited. Top-right, clear of notches. */
/* "Map" button — the labeled way back to the map view (AR ⇄ Map toggle). */
/* Exit control. It USED to sit top-right at z-index 2 — underneath .ar-maneuver, which
   starts at the same inset-block-start, spans the full width and is z-index 3. The turn
   banner therefore covered it and AR looked like it had no way out.
   Bottom-left instead: the one region free of the top banners (maneuver / off-route /
   signal), the centred arrow and the centred distance badge. z-index 5 puts it above every
   HUD layer INCLUDING the arrival overlay (z-index 4), so there is never a state where the
   camera is showing and the way out is covered. 48px clears the 44px minimum touch target
   on both platforms, and the safe-area inset keeps it off the iOS home indicator and
   Android gesture bar. */
.ar-close {
  position: absolute;
  inset-block-end: calc(20px + env(safe-area-inset-bottom, 0px));
  inset-inline-start: 16px;
  z-index: 5;
  min-block-size: 48px;
  padding: 0 18px;
  border: 0;
  border-radius: 24px;
  /* Denser than the old 55% so the label stays legible against a bright camera feed. */
  background: rgb(0 0 0 / 72%);
  color: var(--wf-paper);
  font-size: 15px;
  font-weight: 600;
  line-height: 1;
  cursor: pointer;
  display: flex;
  align-items: center;
  gap: 8px;
  box-shadow: 0 2px 10px rgb(0 0 0 / 40%);
  backdrop-filter: blur(4px);
}
.ar-close:active {
  background: rgb(0 0 0 / 88%);
}

/* ── Turn-by-turn maneuver banner (Google-Maps-style next instruction), ported from the
   reference Live View. Top of the overlay, above the arrow. ─────────────────────────── */
.ar-maneuver {
  position: absolute;
  inset-block-start: calc(12px + env(safe-area-inset-top, 0px));
  inset-inline: 16px;
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 12px 16px;
  border-radius: 16px;
  background: color-mix(in srgb, var(--wf-route) 95%, transparent);
  box-shadow: 0 6px 20px rgb(0 0 0 / 35%);
  color: var(--wf-paper);
  z-index: 3;
}
/* The maneuver banner's icon. It is an SVG from the shared AR icon set now, not a text
   glyph, so it is sized as a box rather than by font-size — same drawing the puck shows,
   so the banner and the arrow can never disagree about what the next maneuver is. */
.ar-man-icon {
  flex: 0 0 auto;
  inline-size: 30px;
  block-size: 30px;
  line-height: 1;
}
.ar-man-icon__svg {
  display: block;
  inline-size: 100%;
  block-size: 100%;
}
.ar-man-text {
  display: flex;
  flex-direction: column;
  line-height: 1.2;
}
.ar-man-primary {
  font-size: 18px;
  font-weight: 800;
}
.ar-man-sub {
  font-size: 13px;
  font-weight: 600;
  opacity: 0.9;
}

/* GPS / weak-signal chip (top-left, clear of the maneuver banner). */
.ar-signal {
  position: absolute;
  inset-block-start: calc(76px + env(safe-area-inset-top, 0px));
  inset-inline-start: 16px;
  padding: 6px 12px;
  border-radius: 18px;
  background: rgb(0 0 0 / 45%);
  color: var(--wf-paper);
  font-size: 12px;
  font-weight: 600;
  z-index: 3;
}
.ar-signal.ar-weak {
  color: var(--wf-warning);
}

/* Off-route warning chip (below the maneuver banner). */
.ar-offroute {
  position: absolute;
  inset-block-start: calc(78px + env(safe-area-inset-top, 0px));
  inset-inline: 16px;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 9px 14px;
  border-radius: 12px;
  background: color-mix(in srgb, var(--wf-error-text) 95%, transparent);
  color: var(--wf-paper);
  font-size: 13px;
  font-weight: 700;
  text-align: center;
  z-index: 3;
}

/* "Turn around" pill under the arrow (shown when facing away from the route). */
.ar-turnaround {
  position: absolute;
  inset-block-start: calc(50% + 70px);
  inset-inline-start: 50%;
  translate: -50% 0;
  padding: 8px 16px;
  border-radius: 20px;
  background: rgb(0 0 0 / 60%);
  color: var(--wf-paper);
  font-size: 14px;
  font-weight: 700;
  white-space: nowrap;
  z-index: 2;
}

/* Calibration / movement hint (above the distance badge). */
.ar-hint {
  position: absolute;
  inset-inline: 16px;
  inset-block-end: 84px;
  padding: 9px 14px;
  border-radius: 12px;
  background: rgb(0 0 0 / 60%);
  color: var(--wf-warning);
  font-size: 12.5px;
  font-weight: 600;
  text-align: center;
  z-index: 3;
}

/* Arrival overlay — check + "You've arrived" + name, auto-closes back to the map. */
.ar-arrival {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 10px;
  text-align: center;
  background: rgb(0 0 0 / 55%);
  color: var(--wf-paper);
  z-index: 4;
}
.ar-check {
  font-size: 68px;
  line-height: 1;
  color: var(--wf-success);
  animation: ar-pop 0.5s cubic-bezier(0.16, 1, 0.3, 1);
}
.ar-arrival-title {
  font-size: 22px;
  font-weight: 800;
}
.ar-arrival-name {
  font-size: 16px;
  opacity: 0.9;
}
/* Indoor guidance — the part that is still true once GPS has given up: the room, the floor,
   and whatever the operator wrote for people arriving here. The room is the largest thing on
   the card after the tick, because in a lobby it is the only thing being looked for. */
.ar-arrival-room {
  margin-block-start: 6px;
  padding: 7px 16px;
  border-radius: 999px;
  background: var(--wf-route);
  color: var(--wf-paper);
  font-size: 19px;
  font-weight: 800;
}
.ar-arrival-floor {
  font-size: 15px;
  font-weight: 700;
  opacity: 0.95;
}
.ar-arrival-message {
  max-inline-size: min(88vw, 420px);
  margin-block-start: 4px;
  font-size: 14px;
  line-height: 1.45;
  opacity: 0.92;
  /* Operator text is written with real line breaks; keep them without allowing markup. */
  white-space: pre-line;
}
.ar-arrival-room[hidden],
.ar-arrival-floor[hidden],
.ar-arrival-message[hidden] {
  display: none;
}
.ar-arrival-sub {
  margin-block-start: 10px;
  font-size: 13px;
  opacity: 0.75;
}
@keyframes ar-pop {
  0% {
    transform: scale(0.4);
    opacity: 0;
  }
  100% {
    transform: scale(1);
    opacity: 1;
  }
}
