/* WalkSpy watch page — stacked video + chrome bar + map.
 *
 * Three-row anatomy (desktop & mobile alike, just different proportions):
 *   .wp-frame   — the player. 16:9. Custom auto-hiding chrome over <video>.
 *   .wp-bar     — the always-visible bridge. Walker chip / route-scrubber /
 *                 counters / actions. Lives between video and map and is
 *                 the visual + interactive connector tying them together.
 *   .wp-map     — the map. 16:9, full content-width. Co-equal canvas to
 *                 the video. Cursor follows time; click route to seek.
 *
 * The scrubber inside .wp-bar is the load-bearing element of the page —
 * it is the timeline, the player transport, and (eventually) the clip-
 * region selector all at once. Speed-derived sparkline behind it gives
 * the rail this walk's signature shape.
 */

/* Guided Mode "Following" attribution: appears at the top of any walk
   recorded under Guided Mode, linking back to the recommended route. */
.wp-following {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  padding: 8px 14px 8px 8px;
  background: linear-gradient(135deg, var(--w-brand-50, #effbfc), var(--w-brand-100, #d4f2f5));
  border: 1px solid var(--w-brand-300, #92dae3);
  border-radius: 999px;
  color: var(--w-brand-800, #0a6d79);
  font-family: var(--w-font);
  font-size: var(--w-text-sm);
  font-weight: 500;
  text-decoration: none;
  align-self: flex-start;
  transition: background 120ms ease, transform 120ms ease;
}
.wp-following:hover {
  background: linear-gradient(135deg, var(--w-brand-100, #d4f2f5), var(--w-brand-200, #b8e9ee));
  transform: translateY(-1px);
}
.wp-following > i:first-child {
  width: 28px;
  height: 28px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  background: var(--w-brand-500, #16acbe);
  color: #fff;
  flex-shrink: 0;
  font-size: 13px;
}
.wp-following__label {
  font-size: 11px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--w-brand-700, #0f8e9e);
  font-weight: 600;
}
.wp-following__name {
  font-weight: 600;
  color: var(--w-brand-800, #0a6d79);
  white-space: nowrap;
  max-width: 320px;
  overflow: hidden;
  text-overflow: ellipsis;
}
.wp-following > i:last-child {
  font-size: 11px;
  opacity: 0.6;
}

.wp-stage {
  max-width: 1440px;
  margin: 0 auto;
  padding: var(--w-space-3) var(--w-space-4);
  display: flex;
  flex-direction: column;
  gap: var(--w-space-3);
  font-family: var(--w-font);
  color: var(--w-fg);
}

.wp-frame-strip {
  width: 100%;
  overflow: hidden;
}
.wp-frame-strip__rail {
  display: flex;
  gap: 8px;
  overflow-x: auto;
  padding: 2px 0 8px;
  scrollbar-width: thin;
}
.wp-frame-strip__item {
  flex: 0 0 132px;
  display: grid;
  gap: 5px;
  padding: 0;
  border: 0;
  background: transparent;
  color: var(--w-fg-muted);
  font: var(--w-weight-semibold) 11px/1 var(--w-font);
  text-align: left;
  cursor: pointer;
}
.wp-frame-strip__item img {
  width: 132px;
  aspect-ratio: 16 / 9;
  display: block;
  object-fit: cover;
  border-radius: var(--w-radius-sm);
  border: 1px solid var(--w-border);
  background: #000;
}
.wp-frame-strip__item:hover img,
.wp-frame-strip__item:focus-visible img {
  border-color: var(--w-brand-500, #16acbe);
  box-shadow: 0 0 0 2px color-mix(in srgb, var(--w-brand-500, #16acbe) 28%, transparent);
}
.wp-frame-strip__item:focus-visible {
  outline: none;
}

.wp-walk-identity {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: end;
  gap: var(--w-space-3);
  padding: var(--w-space-3) var(--w-space-4);
  border: 1px solid var(--w-border);
  border-radius: var(--w-radius-md);
  background: linear-gradient(135deg, color-mix(in srgb, var(--w-brand-50, #effbfc) 72%, #fff), var(--w-surface));
}
.wp-walk-identity__main {
  min-width: 0;
}
.wp-walk-identity__eyebrow {
  display: block;
  margin-bottom: 4px;
  color: var(--w-brand-700, #0f8e9e);
  font: var(--w-weight-bold) 11px/1 var(--w-font);
  letter-spacing: 0.08em;
  text-transform: uppercase;
}
.wp-walk-identity h1 {
  margin: 0;
  color: var(--w-fg);
  font: var(--w-weight-semibold) clamp(20px, 2.5vw, 32px)/1.1 var(--w-font);
  letter-spacing: 0;
  overflow-wrap: anywhere;
}
.wp-walk-identity__facts {
  min-width: min(420px, 100%);
  display: grid;
  gap: 8px;
  justify-items: end;
}
.wp-walk-identity__facts a,
.wp-walk-identity__facts time {
  max-width: 100%;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 8px 11px;
  border: 1px solid color-mix(in srgb, var(--w-brand-300, #92dae3) 58%, var(--w-border));
  border-radius: var(--w-radius-pill);
  background: rgba(255,255,255,0.72);
  color: var(--w-fg);
  font: var(--w-weight-semibold) var(--w-text-sm)/1.15 var(--w-font);
  text-decoration: none;
}
.wp-walk-identity__facts i {
  color: var(--w-brand-600, #109aaa);
  flex: 0 0 auto;
}
.wp-walk-identity__facts span {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

@media (max-width: 760px) {
  .wp-walk-identity {
    grid-template-columns: 1fr;
    align-items: start;
    padding: var(--w-space-3);
  }
  .wp-walk-identity__facts {
    min-width: 0;
    justify-items: stretch;
  }
  .wp-walk-identity__facts a,
  .wp-walk-identity__facts time {
    width: 100%;
  }
}

/* Player + map row. Layout strategy depends on the video's orientation,
   set by walk-chrome.js after `loadedmetadata` reads the video's natural
   dimensions:
     • landscape (default): width-bound — player takes 3/5 of the row
       (16:9-ish), map fills 2/5 (close to square).
     • portrait: height-bound — player is capped to a viewport-friendly
       height and its width derives from --video-aspect; map flex-fills
       the (now wider) remaining width.
   On narrow viewports we stack regardless so both still fit. */
.wp-row {
  display: flex;
  flex-direction: row;
  align-items: stretch;
  gap: var(--w-space-3);
  width: 100%;
}
.wp-row > .wp-frame { flex: 3 1 0; }
.wp-row > .wp-map   { flex: 2 1 0; }

.wp-row[data-orient="portrait"] > .wp-frame {
  flex: 0 0 auto;
  height: clamp(320px, 65vh, 600px);
  width: auto;
  max-width: 50%;
}
.wp-row[data-orient="portrait"] > .wp-map {
  flex: 1 1 0;
}

@media (max-width: 1023px) {
  .wp-row,
  .wp-row[data-orient="portrait"] {
    flex-direction: column;
  }
  .wp-row > .wp-frame,
  .wp-row > .wp-map,
  .wp-row[data-orient="portrait"] > .wp-frame,
  .wp-row[data-orient="portrait"] > .wp-map {
    flex: 0 0 auto;
    height: auto;
    width: 100%;
    max-width: 100%;
  }
}

/* ── Player frame ──────────────────────────────────────────────────── */
.wp-frame {
  position: relative;
  width: 100%;
  /* Aspect is overridden by walk-chrome.js once loadedmetadata reports
     the actual video dimensions; default 16:9 covers SSR + load. */
  aspect-ratio: var(--video-aspect, 16 / 9);
  background: #000;
  border-radius: var(--w-radius-md);
  overflow: hidden;
  box-shadow: var(--w-shadow-md);
  isolation: isolate;
}
.wp-frame__video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  display: block;
  background: #000;
  object-fit: contain;
}

/* ── Multi-camera grid ────────────────────────────────────────────────
   Recorded mode renders one tile per camera inside .wp-grid. Single-cam
   pages keep the frame's natural 16:9 aspect; multi-cam fills the frame
   and divides it into a grid (cols × rows) chosen by data-cell-count.
   Tiles use object-fit:contain so portrait + landscape mix without crop.
*/
.wp-grid {
  position: absolute;
  inset: 0;
  display: grid;
  gap: 2px;
  background: #000;
  grid-template-columns: repeat(var(--wp-cols, 1), 1fr);
  grid-template-rows:    repeat(var(--wp-rows, 1), 1fr);
}
.wp-cell {
  position: relative;
  background: #000;
  overflow: hidden;
  min-width: 0;
  min-height: 0;
}
.wp-cell__video {
  width: 100%;
  height: 100%;
  display: block;
  background: #000;
  object-fit: contain;
  cursor: pointer;
}

/* Visible thumbnail overlay. The native <video poster> is unreliable in
   Chrome once preload="metadata" decodes the first frame (it paints over
   the poster). This <img> sits on top of the video, matches its bounds,
   and fades out the first time the master video plays. */
.wp-cell__thumb {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: contain;
  background: #000;
  z-index: 1;
  pointer-events: none;
  transition: opacity var(--w-motion-base) var(--w-ease);
}
.wp-cell__thumb.is-hidden {
  opacity: 0;
}

/* Per-tile audio toggle (top-right). Active = this cam owns the audio. */
.wp-cell__audio {
  position: absolute;
  top: var(--w-space-2);
  right: var(--w-space-2);
  z-index: 4;
  width: 36px;
  height: 36px;
  border: 0;
  border-radius: var(--w-radius-circle);
  background: rgb(0 0 0 / 0.55);
  backdrop-filter: blur(8px);
  color: rgb(255 255 255 / 0.85);
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 14px;
  transition: background var(--w-motion-fast), color var(--w-motion-fast), transform var(--w-motion-fast);
}
.wp-cell__audio:hover  { color: #fff; transform: scale(1.06); }
.wp-cell__audio:focus-visible { outline: none; box-shadow: var(--w-shadow-glow); }
.wp-cell__audio.is-active {
  background: var(--w-brand-500);
  color: var(--w-fg-on-brand);
  box-shadow: var(--w-shadow-glow);
}

/* Camera label pill (bottom-left). Pointer-events:none so it doesn't
   intercept the play-on-tile click. */
.wp-cell__label {
  position: absolute;
  bottom: var(--w-space-2);
  left: var(--w-space-2);
  z-index: 3;
  padding: 4px 10px;
  background: rgb(0 0 0 / 0.55);
  backdrop-filter: blur(8px);
  border-radius: var(--w-radius-pill);
  color: #fff;
  font: var(--w-weight-semibold) var(--w-text-xs)/1 var(--w-font);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  pointer-events: none;
}

/* ── Multi-cam grid layouts ───────────────────────────────────────────
   The featured tile spans 2×2 (except N=2 where both tiles are equal).
   Followers wrap inside .wp-grid__strip with display:contents on desktop
   so they participate directly in the grid. With grid-auto-flow:dense
   the followers backfill any holes the featured tile leaves.
*/
.wp-frame--multi .wp-grid {
  grid-auto-flow: dense;
}
.wp-grid__strip { display: contents; }

/* N=2 — both tiles equal; featured is just the audio source visually. */
.wp-frame--multi[data-cell-count="2"] .wp-grid {
  grid-template-columns: 1fr 1fr;
  grid-template-rows: 1fr;
}

/* N=3 — 3 cols × 2 rows. Featured spans 2 cols × 2 rows; the 2 followers
   stack in the right column. */
.wp-frame--multi[data-cell-count="3"] .wp-grid {
  grid-template-columns: repeat(3, 1fr);
  grid-template-rows: 1fr 1fr;
}
.wp-frame--multi[data-cell-count="3"] .wp-cell.is-featured {
  grid-column: span 2;
  grid-row: span 2;
}

/* N >= 4 — 4 cols, auto-rows. Featured spans 2×2; followers auto-flow.
   For any cam count >=4, this is the unified layout. */
.wp-frame--multi:not([data-cell-count="1"]):not([data-cell-count="2"]):not([data-cell-count="3"]) .wp-grid {
  grid-template-columns: repeat(4, 1fr);
  grid-template-rows: none;
  grid-auto-rows: minmax(0, 1fr);
}
.wp-frame--multi:not([data-cell-count="1"]):not([data-cell-count="2"]):not([data-cell-count="3"]) .wp-cell.is-featured {
  grid-column: span 2;
  grid-row: span 2;
}

/* Multi-cam: the frame has no fixed aspect; height is clamp-driven so
   the grid grows vertically as cams pile up but never dwarfs the page.
   Switched to flex column so the pinned row + grid stack natively
   without one absolute-positioning over the other. */
.wp-frame--multi {
  aspect-ratio: auto;
  height: clamp(360px, 64vh, 760px);
  display: flex;
  flex-direction: column;
}
.wp-frame--multi > .wp-grid {
  position: relative;
  inset: auto;
  flex: 1 1 auto;
  min-height: 0;
}

/* ── Featured tile (the developing print on the contact sheet) ────────
   A teal halo rim + soft inset glow marks it as the audio-source +
   primary surface. Multi-cam only — single-cam doesn't need a "this
   is the source" indicator. */
.wp-frame--multi .wp-cell.is-featured {
  z-index: 6;
}
.wp-frame--multi .wp-cell.is-featured::after {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: inherit;
  pointer-events: none;
  box-shadow:
    inset 0 0 0 2px var(--w-brand-500),
    inset 0 0 28px rgb(22 172 190 / 0.16),
    0 0 0 4px rgb(22 172 190 / 0.18);
  z-index: 1;
  transition: box-shadow var(--w-motion-base) var(--w-ease);
}
/* When NOT featured (in multi-cam), hover hints that you can promote it. */
.wp-frame--multi .wp-cell:not(.is-featured):not(.is-dragging):hover {
  cursor: pointer;
}
.wp-frame--multi .wp-cell:not(.is-featured):not(.is-dragging):hover .wp-cell__video,
.wp-frame--multi .wp-cell:not(.is-featured):not(.is-dragging):hover .wp-cell__thumb {
  filter: brightness(1.07);
}
.wp-frame--multi .wp-cell:not(.is-featured)::after {
  content: '';
  position: absolute;
  inset: 0;
  pointer-events: none;
  box-shadow: inset 0 0 0 1px rgb(255 255 255 / 0.04);
  border-radius: inherit;
  z-index: 1;
  transition: box-shadow var(--w-motion-fast) var(--w-ease);
}
.wp-frame--multi .wp-cell:not(.is-featured):not(.is-dragging):hover::after {
  box-shadow: inset 0 0 0 1px rgb(22 172 190 / 0.55);
}

/* ── Pinned row above the grid ─────────────────────────────────────────
   "PINNED" tag + horizontal scroll row. Each pinned cell shrinks to a
   compact thumbnail height; the cell's affordances stay clickable. */
.wp-pinned {
  display: flex;
  align-items: stretch;
  gap: var(--w-space-3);
  padding: var(--w-space-2) var(--w-space-3);
  background: rgb(0 0 0 / 0.55);
  backdrop-filter: blur(10px);
  border-radius: var(--w-radius-md) var(--w-radius-md) 0 0;
  border-bottom: 1px solid rgb(255 255 255 / 0.08);
  position: relative;
  z-index: 7;
}
.wp-pinned[hidden] { display: none !important; }
.wp-pinned__tag {
  flex: 0 0 auto;
  align-self: center;
  font: var(--w-weight-bold) 0.65rem/1 var(--w-font);
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: oklch(82% 0.10 75); /* warm amber to echo the pin colour */
  padding: 0 var(--w-space-2);
  border-right: 1px solid rgb(255 255 255 / 0.12);
  white-space: nowrap;
}
.wp-pinned__row {
  flex: 1 1 auto;
  display: flex;
  gap: var(--w-space-2);
  overflow-x: auto;
  overflow-y: hidden;
  padding: 2px;
  scroll-snap-type: x proximity;
  scrollbar-width: thin;
  scrollbar-color: rgb(255 255 255 / 0.2) transparent;
}
.wp-pinned__row::-webkit-scrollbar { height: 4px; }
.wp-pinned__row::-webkit-scrollbar-thumb {
  background: rgb(255 255 255 / 0.18);
  border-radius: var(--w-radius-pill);
}
.wp-pinned__row > .wp-cell {
  flex: 0 0 auto;
  width: clamp(140px, 20%, 220px);
  height: 110px;
  aspect-ratio: auto;
  border-radius: var(--w-radius-sm);
  scroll-snap-align: start;
}
/* The frame itself loses its top-rounded corners when a pinned row is
   present, since the pinned row owns the top. */
.wp-frame--multi:has(.wp-pinned:not([hidden])) {
  border-top-left-radius: 0;
  border-top-right-radius: 0;
}
.wp-frame--multi:has(.wp-pinned:not([hidden])) .wp-grid { border-radius: 0; }

/* ── Drag handle (top-left, masking-tape badge) ───────────────────────
   Only present on multi-cam tiles. The handle is the only draggable
   element so click-to-promote isn't accidentally triggered by a drag. */
.wp-cell__handle {
  position: absolute;
  top: var(--w-space-2);
  left: var(--w-space-2);
  z-index: 5;
  width: 28px;
  height: 28px;
  border-radius: var(--w-radius-sm);
  background: rgb(255 255 255 / 0.92);
  color: var(--w-navy-700);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  cursor: grab;
  font-size: 12px;
  box-shadow: 0 1px 3px rgb(0 0 0 / 0.35), inset 0 0 0 1px rgb(0 0 0 / 0.06);
  /* Touch-friendly hit area without expanding the visible badge. */
  touch-action: none;
  transition: transform var(--w-motion-fast) var(--w-ease),
              background var(--w-motion-fast) var(--w-ease);
  /* The handle should be reachable under the featured halo. */
  user-select: none;
}
.wp-cell__handle:hover  { transform: scale(1.06); }
.wp-cell__handle:active { cursor: grabbing; transform: scale(0.95); }
.wp-cell__handle::before {
  /* Thin stripe across the handle to evoke a strip of masking tape. */
  content: '';
  position: absolute;
  inset: 4px 2px;
  background: repeating-linear-gradient(
    -28deg,
    transparent 0 3px,
    rgb(0 0 0 / 0.04) 3px 5px
  );
  border-radius: 2px;
  pointer-events: none;
}

/* ── Per-tile button cluster (top-right): pin + audio ─────────────────
   The cluster is a small flex pill so the buttons read as a unit. */
.wp-cell__cluster {
  position: absolute;
  z-index: 5;
  display: inline-flex;
  align-items: center;
  gap: 6px;
}
.wp-cell__cluster--tr {
  top: var(--w-space-2);
  right: var(--w-space-2);
}

/* Re-anchor the (existing) audio button now that it lives in the cluster. */
.wp-cell__audio {
  position: static;            /* override the previous absolute positioning */
  width: 36px;
  height: 36px;
  border: 0;
  border-radius: var(--w-radius-circle);
  background: rgb(0 0 0 / 0.55);
  backdrop-filter: blur(8px);
  color: rgb(255 255 255 / 0.85);
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 14px;
  transition: background var(--w-motion-fast),
              color      var(--w-motion-fast),
              transform  var(--w-motion-fast);
}

/* ── Pin button (brass thumbtack) ─────────────────────────────────────
   Neutral when unpinned; warm amber gradient + slight rotation when
   pinned, like a thumbtack pressed into the tile. */
.wp-cell__pin {
  width: 36px;
  height: 36px;
  border: 0;
  border-radius: var(--w-radius-circle);
  background: rgb(0 0 0 / 0.55);
  backdrop-filter: blur(8px);
  color: rgb(255 255 255 / 0.7);
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 13px;
  transition: background var(--w-motion-fast),
              color      var(--w-motion-fast),
              transform  var(--w-motion-fast);
}
.wp-cell__pin:hover {
  color: oklch(85% 0.12 75);
  transform: scale(1.06);
}
.wp-cell__pin:focus-visible {
  outline: none;
  box-shadow: var(--w-shadow-glow);
}
.wp-cell__pin[aria-pressed="true"],
.wp-cell.is-pinned .wp-cell__pin {
  background: linear-gradient(155deg, oklch(76% 0.13 75) 0%, oklch(60% 0.14 60) 100%);
  color: #fff;
  box-shadow:
    0 0 0 2px rgb(255 255 255 / 0.12),
    0 2px 6px rgb(0 0 0 / 0.5);
  transform: rotate(-12deg);
}
.wp-cell__pin[aria-pressed="true"]:hover,
.wp-cell.is-pinned .wp-cell__pin:hover {
  transform: rotate(-12deg) scale(1.04);
}

/* ── Big in-tile play button ──────────────────────────────────────────
   A 96px brand-teal disc centred on the featured tile. Shows when the
   master is paused or ended; hides while playing. Pulses outward when
   paused so the call-to-action reads from across the room. The hiker
   scales up to 56px and the play badge nearly doubles, so the "press
   to play" cue lands before the walker registers as a brand mark. */
.wp-cell__bigplay {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  z-index: 7;
  width: 96px;
  height: 96px;
  border-radius: var(--w-radius-circle);
  background: var(--w-brand-500);
  color: var(--w-fg-on-brand);
  border: 0;
  cursor: pointer;
  display: none;
  align-items: center;
  justify-content: center;
  padding: 0;
  box-shadow:
    0 10px 30px rgb(0 0 0 / 0.5),
    0 0 0 6px rgb(22 172 190 / 0.18);
  transition: background  var(--w-motion-fast) var(--w-ease),
              transform   var(--w-motion-fast) var(--w-ease),
              box-shadow  var(--w-motion-base) var(--w-ease);
  /* Subtle outward pulse to draw the eye. Paused-only; the rule below
     pauses it during playback. */
  animation: wp-bigplay-pulse 2.4s ease-in-out infinite;
}
.wp-cell__bigplay:hover {
  background: var(--w-brand-600);
  transform: translate(-50%, -50%) scale(1.06);
}
.wp-cell__bigplay:focus-visible {
  outline: none;
  box-shadow:
    0 10px 30px rgb(0 0 0 / 0.5),
    var(--w-shadow-glow);
}
.wp-cell__bigplay:active {
  transform: translate(-50%, -50%) scale(0.96);
}

/* Visibility — only on the featured cell, only when not currently playing.
   We keep .wp-cell__bigplay rendered in every cell so featured promotion
   is just a CSS visibility flip; no DOM reparenting required.
   Live mode hides it entirely — LiveKit streams auto-attach, there's no
   "press to play" affordance to offer. */
.wp-cell.is-featured .wp-cell__bigplay {
  display: inline-flex;
}
.wp-frame[data-state="playing"] .wp-cell.is-featured .wp-cell__bigplay,
.wp-frame[data-mode="live"] .wp-cell__bigplay {
  display: none;
}

/* Big variant of the hiker — 56px figure with a 26px play badge. */
.wp-hiker--big {
  width: 56px;
  height: 56px;
}
.wp-hiker--big .wp-hiker__badge,
.wp-hiker__badge--big {
  width: 26px;
  height: 26px;
  font-size: 13px;
  bottom: -6px;
  right: -8px;
  /* Keep the badge planted while the bigger hiker bobs slightly more. */
  animation-name: wp-hiker-badge-counter;
}

/* Hide the bigplay's pulse once the user hits play (and on ended state
   we keep it visible without the pulse — the static disc is invitation
   enough for a replay). */
.wp-frame[data-state="playing"] .wp-cell__bigplay,
.wp-frame[data-state="ended"]   .wp-cell__bigplay {
  animation: none;
}

@keyframes wp-bigplay-pulse {
  0%, 100% {
    box-shadow:
      0 10px 30px rgb(0 0 0 / 0.5),
      0 0 0 6px  rgb(22 172 190 / 0.22);
  }
  50% {
    box-shadow:
      0 10px 30px rgb(0 0 0 / 0.5),
      0 0 0 22px rgb(22 172 190 / 0);
  }
}
@media (prefers-reduced-motion: reduce) {
  .wp-cell__bigplay { animation: none; }
}

/* Mobile — slightly smaller bigplay so it doesn't overpower the 50vh
   featured tile on narrow phones. */
@media (max-width: 640px) {
  .wp-cell__bigplay { width: 80px; height: 80px; }
  .wp-hiker--big   { width: 44px; height: 44px; }
  .wp-hiker--big .wp-hiker__badge,
  .wp-hiker__badge--big {
    width: 22px; height: 22px; font-size: 11px;
    bottom: -5px; right: -7px;
  }
}

/* ── Drag/drop feedback ───────────────────────────────────────────────
   The dragging tile dims; drop-target tiles show a soft brand-tinted
   bar on the side that drop-into would land. */
.wp-cell.is-dragging {
  opacity: 0.45;
  filter: saturate(0.7);
  transform: scale(0.98);
  transition: transform var(--w-motion-fast) var(--w-ease);
}
.wp-frame--multi.is-dragging .wp-pinned__row,
.wp-frame--multi.is-dragging .wp-grid__strip {
  outline: 1px dashed rgb(22 172 190 / 0.35);
  outline-offset: -2px;
}
.wp-cell.is-drop-before { box-shadow: inset 4px 0 0 var(--w-brand-500); }
.wp-cell.is-drop-after  { box-shadow: inset -4px 0 0 var(--w-brand-500); }
@media (min-width: 641px) {
  /* Vertical drop hints on desktop where the grid is 2D. */
  .wp-cell.is-drop-before { box-shadow: inset 0 4px 0 var(--w-brand-500); }
  .wp-cell.is-drop-after  { box-shadow: inset 0 -4px 0 var(--w-brand-500); }
}
.wp-pinned__row.is-drop-into,
.wp-grid__strip.is-drop-into {
  background: rgb(22 172 190 / 0.12);
  outline: 2px dashed var(--w-brand-500);
  outline-offset: -2px;
}

/* ── Mobile multi-cam layout ──────────────────────────────────────────
   Featured tile fills ~50vh on top; pinned cams (if any) sit in a
   tighter row above the featured; non-featured non-pinned tiles
   become a horizontal scroll-snap strip below the featured. Drag
   handles still work via the same native HTML5 DnD pathway. */
@media (max-width: 640px) {
  .wp-frame--multi {
    height: auto;
    min-height: 0;
    display: flex;
    flex-direction: column;
    aspect-ratio: auto;
  }
  .wp-frame--multi .wp-grid {
    position: static;
    display: flex;
    flex-direction: column;
    grid-template-columns: none !important;
    grid-template-rows: none !important;
    grid-auto-rows: auto !important;
    gap: var(--w-space-2);
    background: transparent;
  }
  .wp-frame--multi .wp-cell.is-featured {
    grid-column: auto !important;
    grid-row: auto !important;
    width: 100%;
    height: 50vh;
    flex: 0 0 50vh;
    border-radius: var(--w-radius-md);
  }
  /* Strip becomes its own horizontal scroller below the featured. The
     desktop "display: contents" is overridden so the strip wraps the
     followers as a tactile, swipeable row. */
  .wp-frame--multi .wp-grid__strip {
    display: flex !important;
    flex-direction: row;
    overflow-x: auto;
    overflow-y: hidden;
    scroll-snap-type: x mandatory;
    -webkit-overflow-scrolling: touch;
    gap: var(--w-space-2);
    padding: 2px var(--w-space-3) calc(var(--w-space-3) + 56px);
    /* extra bottom padding clears the chrome bar overlay at the bottom */
  }
  .wp-frame--multi .wp-grid__strip > .wp-cell {
    flex: 0 0 64%;
    height: clamp(150px, 24vh, 220px);
    aspect-ratio: 16/9;
    scroll-snap-align: start;
    border-radius: var(--w-radius-sm);
  }
  .wp-pinned {
    border-radius: var(--w-radius-md) var(--w-radius-md) 0 0;
    padding: var(--w-space-2);
  }
  .wp-pinned__row > .wp-cell {
    width: 132px;
    height: 88px;
  }
  /* Touch targets — pin and audio buttons need at least 40px reach. */
  .wp-cell__audio,
  .wp-cell__pin {
    width: 40px;
    height: 40px;
  }
  .wp-cell__handle {
    width: 32px;
    height: 32px;
  }
}

/* ── Tablet (641-1023px) — slightly compressed grid ───────────────────
   At this width the page hasn't yet stacked into mobile; we just lower
   the frame height a touch so featured + 1-2 followers fit comfortably. */
@media (min-width: 641px) and (max-width: 1023px) {
  .wp-frame--multi {
    height: clamp(320px, 56vh, 600px);
  }
}

/* ── Theater mode (full-bleed walk surface) ───────────────────────────
   A click on the chrome bar's "Theater" button toggles body.theater-mode.
   Site header + footer hide; .wp-stage stretches to fill the viewport;
   the player + map fight for the visible space. An exit pill appears
   in the top-right (data-wp-theater-exit). Esc also exits. */
body.theater-mode > header,
body.theater-mode > footer,
body.theater-mode > main > .mainContainer > .contentBlock > * {
  /* fall-through: the inner content stays visible. The next selector
     handles header/footer at the layout level — we keep the matchers
     above as a safety net only when the layout shell changes. */
}
body.theater-mode header,
body.theater-mode footer {
  display: none !important;
}
body.theater-mode main,
body.theater-mode .mainContainer,
body.theater-mode .contentBlock {
  margin: 0 !important;
  padding: 0 !important;
  max-width: none !important;
}
body.theater-mode .wp-stage {
  max-width: none;
  padding: var(--w-space-2);
  gap: var(--w-space-2);
  min-height: 100vh;
  min-height: 100dvh;
  background: var(--w-navy-900);
  border-radius: 0;
}
body.theater-mode .wp-row {
  /* In theater mode the player + map share most of the height. The
     scrubber chrome bar sits below; we cap the row at most of viewport. */
  height: calc(100vh - 200px);
  height: calc(100dvh - 200px);
  flex: 0 0 auto;
}
body.theater-mode .wp-row > .wp-frame   { flex: 5 1 0; height: 100%; }
body.theater-mode .wp-row > .wp-map     { flex: 2 1 0; height: 100%; }
body.theater-mode .wp-frame--multi      { height: 100%; }

@media (max-width: 1023px) {
  body.theater-mode .wp-row {
    height: auto;
  }
}

/* The exit pill — only visible in theater mode. Sticky top-right with
   a kbd hint so the Esc affordance is obvious. */
.wp-theater-exit {
  position: fixed;
  top: var(--w-space-3);
  right: var(--w-space-3);
  z-index: 9000;
  display: none;
  align-items: center;
  gap: var(--w-space-2);
  padding: 8px 14px 8px 12px;
  background: rgb(20 20 26 / 0.78);
  backdrop-filter: blur(14px);
  border: 1px solid rgb(255 255 255 / 0.12);
  border-radius: var(--w-radius-pill);
  color: #fff;
  cursor: pointer;
  font: var(--w-weight-medium) var(--w-text-sm)/1 var(--w-font);
  box-shadow: 0 6px 24px rgb(0 0 0 / 0.45);
  transition: background var(--w-motion-fast),
              transform   var(--w-motion-fast);
}
.wp-theater-exit:hover {
  background: rgb(28 28 36 / 0.88);
  transform: translateY(-1px);
}
.wp-theater-exit:focus-visible {
  outline: none;
  box-shadow: var(--w-shadow-glow), 0 6px 24px rgb(0 0 0 / 0.45);
}
.wp-theater-exit kbd {
  font: var(--w-weight-semibold) 0.7rem/1 var(--w-font);
  background: rgb(255 255 255 / 0.12);
  border: 1px solid rgb(255 255 255 / 0.18);
  border-radius: var(--w-radius-sm);
  padding: 2px 6px;
  color: rgb(255 255 255 / 0.85);
}
body.theater-mode .wp-theater-exit { display: inline-flex; }

/* In theater mode the chrome bar contracts a touch — no walker chip
   ellipsis, just the scrubber + actions on a slim background. */
body.theater-mode .wp-bar {
  border-radius: var(--w-radius-md);
  background: rgb(20 20 26 / 0.85);
  backdrop-filter: blur(14px);
  border-color: rgb(255 255 255 / 0.08);
  color: #fff;
}
body.theater-mode .wp-bar__walker-name { color: #fff; }
body.theater-mode .wp-bar__walker-title { color: rgb(255 255 255 / 0.7); }
body.theater-mode .wp-bar__counters { color: rgb(255 255 255 / 0.65); }

/* Multi-cam pill, top-left of player frame */
.wp-frame__camstrip {
  position: absolute;
  top: var(--w-space-3);
  left: var(--w-space-3);
  z-index: 3;
  display: flex;
  gap: 2px;
  padding: 4px;
  background: rgb(0 0 0 / 0.55);
  backdrop-filter: blur(8px);
  border-radius: var(--w-radius-pill);
  font: var(--w-weight-semibold) var(--w-text-xs)/1 var(--w-font);
}
.wp-frame__camtab {
  background: transparent;
  color: rgb(255 255 255 / 0.75);
  border: 0;
  padding: 6px 12px;
  border-radius: var(--w-radius-pill);
  cursor: pointer;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  transition: background var(--w-motion-fast), color var(--w-motion-fast);
}
.wp-frame__camtab:hover { color: #fff; }
.wp-frame__camtab.is-active {
  background: var(--w-brand-500);
  color: var(--w-fg-on-brand);
  box-shadow: var(--w-shadow-glow);
}

/* Player chrome — auto-hiding overlay at the bottom of the frame.
   Stays visible while paused; hides 2.5s after pointer rest while playing. */
.wp-chrome {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 2;
  display: flex;
  align-items: center;
  gap: var(--w-space-3);
  padding: var(--w-space-3) var(--w-space-4);
  color: #fff;
  background: linear-gradient(to top, rgb(0 0 0 / 0.78) 0%, rgb(0 0 0 / 0.45) 50%, rgb(0 0 0 / 0) 100%);
  opacity: 1;
  transform: translateY(0);
  transition: opacity var(--w-motion-base) var(--w-ease), transform var(--w-motion-base) var(--w-ease);
}
.wp-frame[data-chrome="idle"] .wp-chrome {
  opacity: 0;
  transform: translateY(8px);
  pointer-events: none;
}

/* Hiker play button — the brand pillar */
.wp-chrome__play {
  flex: 0 0 auto;
  width: 44px;
  height: 44px;
  border-radius: var(--w-radius-circle);
  background: var(--w-brand-500);
  color: var(--w-fg-on-brand);
  border: 0;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 18px;
  box-shadow: 0 2px 8px rgb(0 0 0 / 0.3);
  transition: background var(--w-motion-fast), transform var(--w-motion-fast);
}
.wp-chrome__play:hover { background: var(--w-brand-600); transform: scale(1.04); }
.wp-chrome__play:focus-visible { outline: none; box-shadow: var(--w-shadow-glow); }

/* Hiker / pause swap based on video state. The hiker is shown when paused
   (an inviting "ready to walk" cue); the pause glyph appears while the
   video is playing. The hiker's limbs scissor on a 1.2s loop while shown. */
.wp-chrome__play .fa-pause { display: none; }
.wp-frame[data-state="playing"] .wp-chrome__play .wp-hiker { display: none; }
.wp-frame[data-state="playing"] .wp-chrome__play .fa-pause { display: inline-block; }
.wp-frame[data-state="paused"]  .wp-chrome__play .wp-hiker { display: inline-flex; }
.wp-frame[data-state="paused"]  .wp-chrome__play .fa-pause { display: none; }
.wp-frame[data-state="ended"]   .wp-chrome__play .wp-hiker { display: inline-flex; }
.wp-frame[data-state="ended"]   .wp-chrome__play .fa-pause { display: none; }

/* Animated hiker silhouette. Two legs and two arms scissor in opposite
   phase to suggest a stride; the head + torso bob subtly in time with
   the gait. The whole rig is monochrome (currentColor) so it inherits
   the play button's white-on-brand. */
.wp-hiker {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 24px;
  height: 24px;
  line-height: 0;
  animation: wp-hiker-bob 1.2s ease-in-out infinite;
}
.wp-hiker svg {
  width: 100%;
  height: 100%;
  overflow: visible;
}
/* Play-triangle badge clipped to the hiker's lower-right so the button
   reads as "press to play" even before the user notices the walker. */
.wp-hiker__badge {
  position: absolute;
  right: -4px;
  bottom: -4px;
  width: 13px;
  height: 13px;
  border-radius: var(--w-radius-circle);
  background: #fff;
  color: var(--w-brand-700, var(--w-brand-500));
  font-size: 7px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  box-shadow: 0 1px 3px rgb(0 0 0 / 0.4);
  /* Counter the hiker's bob so the badge stays planted on the button. */
  animation: wp-hiker-badge-counter 1.2s ease-in-out infinite;
}
@keyframes wp-hiker-badge-counter {
  0%, 100% { transform: translateY(0); }
  50%      { transform: translateY(1px); }
}
.wp-hiker__limb {
  transform-box: fill-box;
  animation-duration: 1.2s;
  animation-timing-function: ease-in-out;
  animation-iteration-count: infinite;
  will-change: transform;
}
/* Hip / shoulder pivots: rotate around the TOP-CENTRE of each limb rect. */
.wp-hiker__leg-a, .wp-hiker__leg-b { transform-origin: 50% 0%; }
.wp-hiker__arm-a, .wp-hiker__arm-b { transform-origin: 50% 0%; }

/* Pair A: front-leg-A swings forward in sync with arm-B (opposite arm). */
.wp-hiker__leg-a { animation-name: wp-hiker-swing-fwd; }
.wp-hiker__arm-b { animation-name: wp-hiker-swing-fwd; }
/* Pair B: leg-B and arm-A swing forward together (opposite phase to pair A). */
.wp-hiker__leg-b { animation-name: wp-hiker-swing-back; }
.wp-hiker__arm-a { animation-name: wp-hiker-swing-back; }

@keyframes wp-hiker-swing-fwd {
  0%, 100% { transform: rotate(-22deg); }
  50%      { transform: rotate( 22deg); }
}
@keyframes wp-hiker-swing-back {
  0%, 100% { transform: rotate( 22deg); }
  50%      { transform: rotate(-22deg); }
}
@keyframes wp-hiker-bob {
  0%, 100% { transform: translateY(0); }
  25%      { transform: translateY(-1px); }
  50%      { transform: translateY(0); }
  75%      { transform: translateY(-1px); }
}

@media (prefers-reduced-motion: reduce) {
  .wp-hiker,
  .wp-hiker__limb,
  .wp-map-walker__hiker,
  .wp-map-walker__halo,
  .leaflet-container .wp-route-upcoming { animation: none !important; }
  /* Settle the limbs in a clear stride pose so the icon still reads as walking. */
  .wp-hiker__leg-a, .wp-hiker__arm-b { transform: rotate(-18deg); }
  .wp-hiker__leg-b, .wp-hiker__arm-a { transform: rotate( 18deg); }
}

.wp-chrome__time {
  font: var(--w-weight-medium) var(--w-text-sm)/1 var(--w-font);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  opacity: 0.92;
  text-shadow: 0 1px 2px rgb(0 0 0 / 0.5);
}

.wp-chrome__speed {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  height: 34px;
  padding: 0 8px;
  border-radius: var(--w-radius-pill);
  background: rgb(255 255 255 / 0.10);
  color: rgb(255 255 255 / 0.9);
  font: var(--w-weight-semibold) var(--w-text-xs)/1 var(--w-font);
  white-space: nowrap;
}
.wp-chrome__speed i {
  font-size: 12px;
  opacity: 0.82;
}
.wp-chrome__speed select {
  appearance: none;
  border: 0;
  background: transparent;
  color: #fff;
  font: inherit;
  cursor: pointer;
  padding: 0 2px;
}
.wp-chrome__speed select:focus-visible {
  outline: none;
  box-shadow: 0 0 0 2px rgb(255 255 255 / 0.35);
  border-radius: 4px;
}
.wp-chrome__speed option {
  color: #111827;
  background: #fff;
}

.wp-chrome__spacer { flex: 1; }

.wp-chrome__btn {
  background: transparent;
  border: 0;
  color: #fff;
  width: 36px;
  height: 36px;
  border-radius: var(--w-radius-circle);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  font-size: 14px;
  opacity: 0.85;
  transition: background var(--w-motion-fast), opacity var(--w-motion-fast);
}
.wp-chrome__btn:hover { background: rgb(255 255 255 / 0.12); opacity: 1; }
.wp-chrome__btn:focus-visible { outline: none; box-shadow: var(--w-shadow-glow); }
.wp-chrome__btn.is-flashing {
  width: auto;
  min-width: 54px;
  padding: 0 10px;
  border-radius: var(--w-radius-pill);
  background: var(--w-brand-500);
  color: var(--w-fg-on-brand);
  opacity: 1;
  font: var(--w-weight-semibold) var(--w-text-xs)/1 var(--w-font);
}

/* Volume cluster — slider expands on hover */
.wp-chrome__volume {
  display: inline-flex;
  align-items: center;
  gap: 4px;
}
.wp-chrome__volume input[type="range"] {
  width: 0;
  opacity: 0;
  transition: width var(--w-motion-base) var(--w-ease), opacity var(--w-motion-base) var(--w-ease);
  accent-color: var(--w-brand-500);
}
.wp-chrome__volume:hover input[type="range"],
.wp-chrome__volume:focus-within input[type="range"] {
  width: 80px;
  opacity: 1;
}

/* Live mode: hide play/scrubbing controls (no scrubbing while live) */
.wp-frame[data-mode="live"] .wp-chrome__play,
.wp-frame[data-mode="live"] .wp-chrome__time { display: none; }

@media (max-width: 640px) {
  .wp-chrome {
    gap: var(--w-space-2);
    padding: var(--w-space-2);
  }
  .wp-chrome__play {
    width: 40px;
    height: 40px;
  }
  .wp-chrome__time {
    font-size: 12px;
  }
  .wp-chrome__speed {
    height: 32px;
    padding: 0 7px;
  }
  .wp-chrome__speed i {
    display: none;
  }
  .wp-chrome__btn {
    width: 34px;
    height: 34px;
  }
  .wp-chrome__volume input[type="range"] {
    display: none;
  }
}

/* Live unavailable overlay */
.wp-frame__live-fallback {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  background: rgb(0 0 0 / 0.85);
  color: #fff;
  padding: var(--w-space-5);
  font: var(--w-weight-medium) var(--w-text-base)/var(--w-leading-snug) var(--w-font);
  z-index: 4;
}
.wp-frame__live-fallback i {
  font-size: var(--w-text-3xl);
  margin-bottom: var(--w-space-3);
  opacity: 0.75;
}

/* Reconnecting overlay: same shape as fallback but warmer (yellow vs
   black), used while we're cycling through reconnect attempts so the
   watcher knows we're trying rather than giving up. */
.wp-frame__live-reconnecting {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  background: rgb(0 0 0 / 0.6);
  color: #fff;
  padding: var(--w-space-5);
  font: var(--w-weight-semibold) var(--w-text-base)/var(--w-leading-snug) var(--w-font);
  z-index: 4;
}
.wp-frame__live-reconnecting i {
  font-size: var(--w-text-3xl);
  margin-bottom: var(--w-space-3);
  color: #f4b740;
}

/* Watcher live-pill: small chrome indicator mirroring the in-frame
   overlay so a watcher with the player partly off-screen still sees
   that the broadcast is healthy / reconnecting / dead. */
.wp-live-pill {
  align-self: flex-start;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 5px 12px;
  border-radius: 999px;
  font: 700 12px var(--w-font-body);
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: #fff;
  background: rgba(0, 0, 0, 0.55);
}
.wp-live-pill::before {
  content: '';
  width: 8px; height: 8px;
  border-radius: 50%;
  background: currentColor;
}
.wp-live-pill--green  { color: #2faa6e; }
.wp-live-pill--yellow { color: #f4b740; }
.wp-live-pill--red    { color: #ff4f4f; animation: wp-live-pulse 1.6s ease-in-out infinite; }
@keyframes wp-live-pulse {
  0%, 100% { background: rgba(255, 79, 79, 0.55); }
  50%      { background: rgba(255, 79, 79, 0.85); }
}

.wp-sync-badges {
  position: absolute;
  inset: 0;
  z-index: 6;
  pointer-events: none;
}
.wp-sync-badge {
  position: absolute;
  max-width: min(280px, 48%);
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 0;
  border: 1px solid rgb(255 255 255 / 0.24);
  border-radius: var(--w-radius-pill);
  background: rgb(5 12 18 / 0.76);
  color: #fff;
  text-decoration: none;
  pointer-events: auto;
  box-shadow: 0 10px 26px rgb(0 0 0 / 0.34);
  backdrop-filter: blur(12px);
  overflow: hidden;
}
.wp-sync-badge__link {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  min-width: 0;
  padding: 7px 8px 7px 7px;
  color: inherit;
  text-decoration: none;
}
.wp-sync-badge__avatar {
  width: 31px;
  height: 31px;
  border-radius: 50%;
  object-fit: cover;
  flex: 0 0 31px;
  border: 2px solid rgb(255 255 255 / 0.55);
}
.wp-sync-badge.is-encounter .wp-sync-badge__avatar {
  border-color: #ff1356;
  box-shadow: 0 0 0 0 rgb(255 19 86 / 0.45);
  animation: wp-sync-signal 1.55s ease-in-out infinite;
}
.wp-sync__filters {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-bottom: var(--w-space-3);
}
.wp-sync__filters button {
  border: 1px solid var(--w-border);
  border-radius: var(--w-radius-pill);
  background: var(--w-bg-alt, #eef2f6);
  color: var(--w-fg);
  padding: 7px 12px;
  cursor: pointer;
  font: 700 12px/1 var(--w-font);
}
.wp-sync__filters button.is-active {
  border-color: transparent;
  background: var(--w-brand-500, #16acbe);
  color: #fff;
}
.wp-sync-row__actions {
  display: inline-flex;
  flex-wrap: wrap;
  gap: 6px;
  justify-content: end;
}
.wp-sync-row__actions button {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}
.wp-sync-row__open {
  background: #17202a !important;
}
.wp-sync-badge.is-encounter {
  border-color: rgb(255 19 86 / 0.55);
  box-shadow: 0 10px 26px rgb(255 19 86 / 0.28);
}
.wp-sync-badge.is-encounter .wp-sync-badge__mark {
  background: #ff1356;
}
.wp-sync-row.is-encounter {
  border-color: rgb(255 19 86 / 0.35);
  background: rgb(255 19 86 / 0.06);
}
.wp-sync__head-actions {
  display: grid;
  justify-items: end;
  gap: 8px;
}
.wp-sync__open {
  display: inline-flex;
  align-items: center;
  padding: 8px 12px;
  border-radius: var(--w-radius-pill);
  background: #17202a;
  color: #fff;
  text-decoration: none;
  font: 800 12px/1 var(--w-font);
}
.wp-sync-tile__actions {
  display: inline-flex;
  gap: 6px;
}
.wp-sync-tile__actions .is-active,
.wp-sync-tile.is-audio {
  outline: 2px solid var(--w-brand-500, #16acbe);
}
.wp-sync-tile__actions [data-live-audio].is-active {
  background: var(--w-brand-500, #16acbe);
  color: #fff;
}
.wp-sync-badge.is-left { left: 12px; }
.wp-sync-badge.is-right { right: 12px; }
.wp-sync-badge__mark {
  width: 31px;
  height: 31px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  background: var(--w-brand-500, #16acbe);
  color: #fff;
  box-shadow: 0 0 0 0 rgb(22 172 190 / 0.48);
  animation: wp-sync-signal 1.55s ease-in-out infinite;
  flex: 0 0 31px;
}
.wp-sync-badge span:last-child {
  min-width: 0;
  display: grid;
  gap: 2px;
}
.wp-sync-badge strong,
.wp-sync-badge em {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.wp-sync-badge strong {
  font: 800 12px/1.1 var(--w-font);
}
.wp-sync-badge em {
  color: rgb(255 255 255 / 0.72);
  font: 700 10px/1 var(--w-font);
  font-style: normal;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}
@keyframes wp-sync-signal {
  0%, 100% { box-shadow: 0 0 0 0 rgb(22 172 190 / 0.5); }
  50% { box-shadow: 0 0 0 9px rgb(22 172 190 / 0); }
}

.wp-sync {
  padding: var(--w-space-4);
  border: 1px solid var(--w-border);
  border-radius: var(--w-radius-md);
  background:
    linear-gradient(135deg, rgb(22 172 190 / 0.10), transparent 48%),
    var(--w-surface);
}
.wp-sync__head {
  display: flex;
  align-items: end;
  justify-content: space-between;
  gap: var(--w-space-3);
  margin-bottom: var(--w-space-3);
}
.wp-sync__head h2,
.wp-sync-board__head h3 {
  margin: 0 0 3px;
  color: var(--w-fg);
  font: var(--w-weight-semibold) var(--w-text-xl)/1.15 var(--w-font);
}
.wp-sync__head p,
.wp-sync-board__head p,
.wp-sync__empty {
  margin: 0;
  color: var(--w-fg-muted);
  font: var(--w-weight-regular) var(--w-text-sm)/1.3 var(--w-font);
}
.wp-sync__head > span {
  padding: 5px 10px;
  border-radius: var(--w-radius-pill);
  background: #ff1356;
  color: #fff;
  font: 800 10px/1 var(--w-font);
  letter-spacing: 0.07em;
  text-transform: uppercase;
  white-space: nowrap;
}
.wp-sync__list {
  display: grid;
  gap: 8px;
}
.wp-sync-row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 10px;
  align-items: center;
  padding: 8px;
  border: 1px solid var(--w-border);
  border-radius: var(--w-radius-sm);
  background: var(--w-bg-alt);
}
.wp-sync-row__main {
  min-width: 0;
  display: flex;
  align-items: center;
  gap: 10px;
  color: inherit;
  text-decoration: none;
}
.wp-sync-row__main img {
  width: 54px;
  height: 42px;
  object-fit: cover;
  border-radius: 6px;
  background: #000;
  flex: 0 0 auto;
}
.wp-sync-row__main span {
  min-width: 0;
  display: grid;
  gap: 3px;
}
.wp-sync-row strong,
.wp-sync-row em {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.wp-sync-row strong {
  color: var(--w-fg);
  font: 750 var(--w-text-sm)/1.1 var(--w-font);
}
.wp-sync-row em {
  color: var(--w-fg-muted);
  font: 600 var(--w-text-xs)/1.2 var(--w-font);
  font-style: normal;
}
.wp-sync-row button,
.wp-sync-tile__bar button {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  border: 0;
  border-radius: var(--w-radius-pill);
  background: var(--w-brand-500);
  color: #fff;
  padding: 8px 12px;
  cursor: pointer;
  font: 800 12px/1 var(--w-font);
}
.wp-sync-row button:disabled {
  cursor: default;
  opacity: 0.62;
}
.wp-sync-board {
  margin-top: var(--w-space-4);
  padding-top: var(--w-space-4);
  border-top: 1px solid var(--w-border);
}
.wp-sync-board__head {
  margin-bottom: var(--w-space-3);
}
.wp-sync-board__grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: var(--w-space-3);
}
.wp-sync-tile {
  min-width: 0;
  border: 1px solid var(--w-border);
  border-radius: var(--w-radius-sm);
  overflow: hidden;
  background: #06090d;
}
.wp-sync-tile__frame {
  position: relative;
  aspect-ratio: 16 / 9;
  background: #000;
}
.wp-sync-tile__frame video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: contain;
}
.wp-sync-tile__connecting {
  position: absolute;
  left: 10px;
  top: 10px;
  z-index: 2;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 5px 8px;
  border-radius: var(--w-radius-pill);
  background: rgb(0 0 0 / 0.62);
  color: #fff;
  font: 800 10px/1 var(--w-font);
  letter-spacing: 0.06em;
  text-transform: uppercase;
}
.wp-sync-tile.is-playing .wp-sync-tile__connecting {
  background: #ff1356;
}
.wp-sync-tile__bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 9px 10px;
  background: var(--w-surface);
}
.wp-sync-tile__bar a {
  min-width: 0;
  display: grid;
  gap: 2px;
  color: inherit;
  text-decoration: none;
}
.wp-sync-tile__bar strong,
.wp-sync-tile__bar span {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.wp-sync-tile__bar strong {
  color: var(--w-fg);
  font: 800 13px/1.1 var(--w-font);
}
.wp-sync-tile__bar span {
  color: var(--w-fg-muted);
  font: 650 11px/1.1 var(--w-font);
}
.wp-sync-tile__bar button {
  width: 30px;
  height: 30px;
  padding: 0;
  justify-content: center;
  background: var(--w-bg-alt);
  color: var(--w-fg);
}

@media (max-width: 720px) {
  .wp-sync-badges {
    inset: auto 12px 64px 12px;
    top: auto;
    height: auto;
    max-height: 28vh;
    overflow: auto;
    pointer-events: none;
  }
  .wp-sync-badges > * {
    pointer-events: auto;
  }
  .wp-sync-badge {
    max-width: 100%;
    left: 0 !important;
    right: auto !important;
    position: relative !important;
    margin: 0 0 6px;
  }
  .wp-sync-row {
    grid-template-columns: 1fr;
  }
  .wp-sync-row button {
    justify-content: center;
  }
}

/* ── Chrome bar (between frame and map) ────────────────────────────── */
.wp-bar {
  display: grid;
  grid-template-columns: minmax(180px, 1fr) minmax(0, 3fr) auto;
  align-items: center;
  gap: var(--w-space-4);
  padding: var(--w-space-3) var(--w-space-4);
  background: var(--w-surface);
  border: 1px solid var(--w-border);
  border-radius: var(--w-radius-md);
  box-shadow: var(--w-shadow-sm);
}

@media (max-width: 880px) {
  .wp-bar {
    grid-template-columns: 1fr;
    gap: var(--w-space-3);
    padding: var(--w-space-3);
  }
}

.wp-bar__walker {
  display: flex;
  align-items: center;
  gap: var(--w-space-3);
  text-decoration: none;
  color: inherit;
  min-width: 0;
}
.wp-bar__walker img {
  width: 36px;
  height: 36px;
  border-radius: var(--w-radius-circle);
  object-fit: cover;
  flex: 0 0 36px;
}
.wp-bar__walker-meta { min-width: 0; }
.wp-bar__walker-name {
  font: var(--w-weight-semibold) var(--w-text-sm)/1.2 var(--w-font);
  color: var(--w-fg);
  display: block;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.wp-bar__walker-title {
  font: var(--w-weight-regular) var(--w-text-xs)/1.3 var(--w-font);
  color: var(--w-fg-muted);
  display: block;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.wp-bar__cluster {
  display: flex;
  align-items: center;
  gap: var(--w-space-3);
  justify-content: flex-end;
}
.wp-bar__counters {
  display: inline-flex;
  align-items: center;
  gap: var(--w-space-2);
  color: var(--w-fg-muted);
  font: var(--w-weight-medium) var(--w-text-xs)/1 var(--w-font);
}
.wp-bar__counters span {
  display: inline-flex;
  align-items: center;
  gap: 4px;
}
.wp-bar__counters i { color: var(--w-brand-500); font-size: 11px; }
.wp-bar__actions {
  display: inline-flex;
  align-items: center;
  gap: var(--w-space-2);
}

@media (max-width: 880px) {
  .wp-bar__cluster { flex-wrap: wrap; justify-content: flex-start; }
}

/* ── Scrubber ──────────────────────────────────────────────────────── */
.wp-scrub {
  position: relative;
  width: 100%;
  height: 44px;
  cursor: pointer;
  user-select: none;
  touch-action: none;
}

/* Speed-derived sparkline sits behind the rail */
.wp-scrub__sparkline {
  position: absolute;
  left: 0;
  right: 0;
  top: 6px;
  bottom: 6px;
  width: 100%;
  height: calc(100% - 12px);
  pointer-events: none;
  opacity: 0.45;
}
.wp-scrub__sparkline path {
  fill: var(--w-brand-100);
  stroke: var(--w-brand-300);
  stroke-width: 1;
}

/* The thin rail itself */
.wp-scrub__track {
  position: absolute;
  left: 0;
  right: 0;
  top: 50%;
  height: 6px;
  transform: translateY(-50%);
  background: var(--w-border);
  border-radius: var(--w-radius-pill);
  overflow: hidden;
}
.wp-scrub__played {
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  width: 0%;
  background: linear-gradient(to right, var(--w-brand-300), var(--w-brand-500));
  border-radius: var(--w-radius-pill);
  transition: width 80ms linear;
}
.wp-scrub.is-scrubbing .wp-scrub__played { transition: none; }

/* Playhead — vertical line with a brand-teal dot */
.wp-scrub__playhead {
  position: absolute;
  top: 0;
  bottom: 0;
  width: 2px;
  background: #fff;
  transform: translateX(-50%);
  pointer-events: none;
  box-shadow: 0 0 0 1px rgb(0 0 0 / 0.15);
  transition: left 80ms linear;
}
.wp-scrub.is-scrubbing .wp-scrub__playhead { transition: none; }
.wp-scrub__playhead::after {
  content: '';
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  width: 14px;
  height: 14px;
  border-radius: var(--w-radius-circle);
  background: var(--w-brand-500);
  box-shadow: 0 0 0 2px #fff, 0 1px 4px rgb(0 0 0 / 0.25);
}

/* Waypoint dots along the rail */
.wp-scrub__waypoints {
  position: absolute;
  left: 0;
  right: 0;
  top: 0;
  bottom: 0;
  pointer-events: none;
}
.wp-scrub__dot {
  position: absolute;
  top: 50%;
  width: 8px;
  height: 8px;
  border-radius: var(--w-radius-circle);
  background: var(--w-brand-700);
  border: 2px solid #fff;
  transform: translate(-50%, -50%);
  pointer-events: auto;
  cursor: pointer;
  transition: transform var(--w-motion-fast) var(--w-ease);
  z-index: 2;
}
.wp-scrub__dot:hover,
.wp-scrub__dot.is-active {
  transform: translate(-50%, -50%) scale(1.45);
}

/* Live-mode scrubber: hide playhead, show pulsing "now" cap */
.wp-scrub--live .wp-scrub__playhead { display: none; }
.wp-scrub--live .wp-scrub__played::after {
  content: '';
  position: absolute;
  right: -6px;
  top: 50%;
  width: 12px;
  height: 12px;
  border-radius: var(--w-radius-circle);
  background: var(--w-live);
  transform: translateY(-50%);
  box-shadow: 0 0 0 2px #fff;
  animation: wp-pulse 1.4s ease-in-out infinite;
}
@keyframes wp-pulse {
  0%, 100% { opacity: 1; transform: translateY(-50%) scale(1); }
  50%      { opacity: 0.55; transform: translateY(-50%) scale(0.75); }
}

/* ── Map ────────────────────────────────────────────────────────────
   Inside .wp-row the map has no aspect-ratio — flex stretch matches it
   to the player's height (which is set by the player's 16:9 ratio). On
   narrow viewports where .wp-row stacks, the @media block below gives
   the map an explicit 4:3 ratio so it doesn't collapse to nothing. */
.wp-map {
  width: 100%;
  border-radius: var(--w-radius-md);
  overflow: hidden;
  box-shadow: var(--w-shadow-sm);
  border: 1px solid var(--w-border);
  background: var(--w-bg-alt);
  position: relative;
  min-height: 280px;
}
@media (max-width: 1023px) {
  .wp-map { aspect-ratio: 4 / 3; min-height: 0; }
}

.wp-related {
  padding: var(--w-space-4);
  border: 1px solid var(--w-border);
  border-radius: var(--w-radius-md);
  background: var(--w-surface);
}

.wp-related__head {
  display: flex;
  justify-content: space-between;
  align-items: end;
  gap: var(--w-space-3);
  margin-bottom: var(--w-space-3);
}

.wp-related__head h2 {
  margin: 0 0 3px;
  color: var(--w-fg);
  font: var(--w-weight-semibold) var(--w-text-xl)/1.15 var(--w-font);
}

.wp-related__head p {
  margin: 0;
  color: var(--w-fg-muted);
  font: var(--w-weight-regular) var(--w-text-sm)/1.3 var(--w-font);
}

.wp-related__head a {
  color: var(--w-brand-600);
  font: var(--w-weight-semibold) var(--w-text-sm)/1 var(--w-font);
  text-decoration: none;
  white-space: nowrap;
}

.wp-related__rail {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: minmax(220px, 1fr);
  gap: var(--w-space-3);
  overflow-x: auto;
  padding-bottom: 2px;
  scroll-snap-type: x proximity;
}

.wp-related-card {
  min-width: 0;
  display: grid;
  grid-template-columns: 88px minmax(0, 1fr);
  gap: 10px;
  align-items: center;
  padding: 8px;
  border: 1px solid var(--w-border);
  border-radius: var(--w-radius-sm);
  background: var(--w-bg-alt);
  color: var(--w-fg);
  text-decoration: none;
  scroll-snap-align: start;
  transition: border-color var(--w-motion-fast), transform var(--w-motion-fast);
}

.wp-related-card:hover {
  border-color: var(--w-brand-400);
  transform: translateY(-1px);
}

.wp-related-card img {
  width: 88px;
  height: 66px;
  object-fit: cover;
  border-radius: 6px;
  background: #000;
}

.wp-related-card__body {
  min-width: 0;
  display: grid;
  gap: 3px;
}

.wp-related-card strong,
.wp-related-card span,
.wp-related-card em {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.wp-related-card strong {
  color: var(--w-fg);
  font: var(--w-weight-semibold) var(--w-text-sm)/1.25 var(--w-font);
}

.wp-related-card span,
.wp-related-card em {
  color: var(--w-fg-muted);
  font: var(--w-weight-regular) var(--w-text-xs)/1.2 var(--w-font);
  font-style: normal;
}

@media (max-width: 720px) {
  .wp-related__head {
    display: block;
  }
  .wp-related__head a {
    display: inline-block;
    margin-top: var(--w-space-2);
  }
  .wp-related__rail {
    grid-auto-columns: minmax(250px, 86vw);
  }
}
/* The Leaflet container needs explicit dimensions; the wrapper above
   defines the aspect ratio and the .ww-map child fills it. */
.wp-map .ww-map,
.wp-map [data-walk-map] {
  width: 100% !important;
  height: 100% !important;
  border-radius: 0 !important;
  border: 0 !important;
  box-shadow: none !important;
}
.wp-map .leaflet-container {
  width: 100% !important;
  height: 100% !important;
  font-family: var(--w-font);
}

.wp-nearby-walk-icon-wrap {
  background: transparent;
  border: 0;
}
.wp-nearby-walk-icon {
  width: 36px;
  height: 36px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 3px solid #fff;
  border-radius: 50%;
  box-shadow: 0 5px 16px rgb(0 0 0 / 0.32);
  color: #fff;
  font-size: 13px;
  overflow: hidden;
  position: relative;
}
.wp-nearby-walk-icon.has-avatar img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.wp-nearby-walk-icon.is-live {
  background: #ff1356;
  animation: wp-nearby-live-pulse 1.5s ease-in-out infinite;
}
.wp-nearby-walk-icon.is-finished {
  background: #17202a;
}
.wp-nearby-walk-icon.is-encounter {
  width: 44px;
  height: 44px;
  border-color: #16acbe;
  animation: wp-nearby-encounter-pulse 1.2s ease-in-out infinite;
}
.wp-nearby-walk-icon__ping {
  position: absolute;
  inset: -6px;
  border: 2px solid #16acbe;
  border-radius: 50%;
  pointer-events: none;
}
.leaflet-marker-icon.is-encounter .wp-nearby-walk-icon,
.leaflet-marker-icon.is-presence-near .wp-nearby-walk-icon {
  box-shadow: 0 0 0 3px #16acbe, 0 5px 16px rgb(0 0 0 / 0.32);
}
@keyframes wp-nearby-live-pulse {
  0%, 100% { box-shadow: 0 5px 16px rgb(0 0 0 / 0.32), 0 0 0 0 rgb(255 19 86 / 0.45); }
  50% { box-shadow: 0 5px 16px rgb(0 0 0 / 0.32), 0 0 0 9px rgb(255 19 86 / 0); }
}
@keyframes wp-nearby-encounter-pulse {
  0%, 100% { box-shadow: 0 5px 16px rgb(0 0 0 / 0.32), 0 0 0 0 rgb(22 172 190 / 0.55); }
  50% { box-shadow: 0 5px 16px rgb(0 0 0 / 0.32), 0 0 0 12px rgb(22 172 190 / 0); }
}
.wp-nearby-popup .leaflet-popup-content-wrapper {
  border-radius: var(--w-radius-sm);
  overflow: hidden;
}
.wp-nearby-popup .leaflet-popup-content {
  margin: 0;
}
.wp-nearby-popup__card {
  width: 250px;
  display: grid;
  grid-template-columns: 82px minmax(0, 1fr);
  gap: 10px;
  padding: 8px;
  color: var(--w-fg, #17202a);
  text-decoration: none;
}
.wp-nearby-popup__card img {
  width: 82px;
  height: 72px;
  object-fit: cover;
  border-radius: 6px;
  background: #000;
}
.wp-nearby-popup__body {
  min-width: 0;
  display: grid;
  gap: 3px;
}
.wp-nearby-popup__body em {
  color: var(--w-fg-muted, #667085);
  font: 700 10px/1 var(--w-font);
  font-style: normal;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}
.wp-nearby-popup__body em.is-live {
  color: #d80f49;
}
.wp-nearby-popup__body strong,
.wp-nearby-popup__body span {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.wp-nearby-popup__body strong {
  color: var(--w-fg, #17202a);
  font: 700 13px/1.2 var(--w-font);
}
.wp-nearby-popup__wrap {
  display: grid;
  gap: 0;
}
.wp-nearby-popup__actions {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin: 0 8px 8px;
}
.wp-nearby-popup__watch {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  padding: 8px 10px;
  border-radius: var(--w-radius-pill);
  background: var(--w-signal, #FF4D1A);
  color: #fff;
  text-decoration: none;
  font: 800 12px/1 var(--w-font);
}
.wp-nearby-popup__together {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  margin: 0;
  padding: 8px 10px;
  border: 0;
  border-radius: var(--w-radius-pill);
  background: var(--w-brand-500, #16acbe);
  color: #fff;
  cursor: pointer;
  font: 800 12px/1 var(--w-font);
}

/* ── Screens board (/screens) ──────────────────────────────────────── */
.ws-screens {
  max-width: 1280px;
  margin: 0 auto;
  padding: var(--w-space-5) var(--w-space-4) var(--w-space-8);
}
.ws-screens__head {
  display: flex;
  align-items: end;
  justify-content: space-between;
  gap: var(--w-space-4);
  margin-bottom: var(--w-space-5);
}
.ws-screens__eyebrow {
  margin: 0 0 6px;
  color: var(--w-brand-600, #0e7a9e);
  font: 800 11px/1 var(--w-font);
  letter-spacing: 0.08em;
  text-transform: uppercase;
}
.ws-screens__head h1 {
  margin: 0 0 8px;
  font: 800 clamp(1.6rem, 2.4vw, 2.2rem)/1.1 var(--w-font);
}
.ws-screens__head p {
  margin: 0;
  max-width: 42rem;
  color: var(--w-fg-muted);
  font: 500 15px/1.45 var(--w-font);
}
.ws-screens__tools {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}
.ws-screens__browse,
.ws-screens__share {
  display: inline-flex;
  align-items: center;
  padding: 10px 14px;
  border: 0;
  border-radius: var(--w-radius-pill);
  background: #17202a;
  color: #fff;
  text-decoration: none;
  cursor: pointer;
  font: 800 13px/1 var(--w-font);
}
.ws-screens__share { background: var(--w-brand-500, #16acbe); }
.ws-screens__empty {
  padding: var(--w-space-7);
  border: 1px dashed var(--w-border);
  border-radius: var(--w-radius-md);
  background: var(--w-surface);
  text-align: center;
}
.ws-screens__empty h2 { margin: 0 0 8px; }
.ws-screens__empty p { margin: 0 0 16px; color: var(--w-fg-muted); }
.ws-screens__grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: var(--w-space-4);
}
.ws-screens__grid[data-count="1"] { grid-template-columns: minmax(0, 920px); }
.ws-screens__grid[data-count="2"] { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.ws-screens-tile {
  position: relative;
  min-width: 0;
  border: 1px solid var(--w-border);
  border-radius: var(--w-radius-md);
  overflow: hidden;
  background: #06090d;
  transition: box-shadow 160ms ease, outline-color 160ms ease, opacity 160ms ease;
}
.ws-screens-tile__drag {
  position: absolute;
  top: 10px;
  right: 10px;
  z-index: 3;
  width: 34px;
  height: 34px;
  border: 0;
  border-radius: 8px;
  background: rgb(0 0 0 / 0.55);
  color: #fff;
  cursor: grab;
}
.ws-screens-tile__drag:active { cursor: grabbing; }
.ws-screens-tile.is-dragging {
  opacity: 0.55;
}
.ws-screens-tile.is-drop-target {
  outline: 2px dashed var(--w-brand-500, #16acbe);
}
.ws-screens__grid.is-reordering .ws-screens-tile:not(.is-dragging) {
  transition: transform 120ms ease;
}
.ws-screens-tile.is-audio {
  outline: 3px solid var(--w-brand-500, #16acbe);
  box-shadow: 0 12px 32px rgb(22 172 190 / 0.22);
}
.ws-screens-tile__frame {
  position: relative;
  aspect-ratio: 16 / 9;
  background: #000;
}
.ws-screens-tile__frame video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: contain;
}
.ws-screens-tile__status {
  position: absolute;
  left: 10px;
  top: 10px;
  z-index: 2;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 5px 8px;
  border-radius: var(--w-radius-pill);
  background: rgb(0 0 0 / 0.62);
  color: #fff;
  font: 800 10px/1 var(--w-font);
  letter-spacing: 0.06em;
  text-transform: uppercase;
}
.ws-screens-tile.is-playing.is-live .ws-screens-tile__status {
  background: #ff1356;
}
.ws-screens-tile__bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 10px 12px;
  background: var(--w-surface);
}
.ws-screens-tile__bar a {
  min-width: 0;
  display: grid;
  gap: 2px;
  color: inherit;
  text-decoration: none;
}
.ws-screens-tile__bar strong,
.ws-screens-tile__bar span {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.ws-screens-tile__bar strong {
  font: 800 14px/1.15 var(--w-font);
}
.ws-screens-tile__bar span {
  color: var(--w-fg-muted);
  font: 650 12px/1.15 var(--w-font);
}
.ws-screens-tile__actions {
  display: inline-flex;
  gap: 6px;
}
.ws-screens-tile__actions button {
  width: 34px;
  height: 34px;
  border: 0;
  border-radius: 50%;
  background: var(--w-bg-alt, #eef2f6);
  color: var(--w-fg);
  cursor: pointer;
}
.ws-screens-tile__actions [data-screens-audio].is-active {
  background: var(--w-brand-500, #16acbe);
  color: #fff;
}
@media (max-width: 720px) {
  .ws-screens__head { display: grid; align-items: start; }
  .ws-screens__grid[data-count="2"] { grid-template-columns: 1fr; }
}
.wp-nearby-popup__body span {
  color: var(--w-fg-muted, #667085);
  font: 600 11px/1.2 var(--w-font);
}
.wp-nearby-popup__body i {
  width: 12px;
  color: var(--w-brand-600, #109aaa);
  text-align: center;
}

/* ── Map: route layers ─────────────────────────────────────────────
   Three stacked polylines: white casing for legibility on any tile,
   dashed brand-teal "upcoming" with marching-ants flow forward, and
   solid brand-teal "traveled" painted up to the live cursor. */
.leaflet-container .wp-route-casing   { stroke: #ffffff; }
.leaflet-container .wp-route-upcoming {
  stroke-dasharray: 8 7;
  animation: wp-route-flow 1.6s linear infinite;
  filter: drop-shadow(0 0 4px rgba(22,172,190,0.45));
}
.leaflet-container .wp-route-traveled {
  filter: drop-shadow(0 0 6px rgba(22,172,190,0.55));
}
@keyframes wp-route-flow {
  to { stroke-dashoffset: -30; }
}

/* Start / Finish circle markers — slightly bigger + subtle drop-shadow. */
.leaflet-container .wp-route-start,
.leaflet-container .wp-route-end {
  filter: drop-shadow(0 1px 3px rgba(0,0,0,0.35));
}

/* ── Map: live walker marker ───────────────────────────────────────
   L.divIcon-rendered HTML containing the same SVG hiker as the play
   button, with a brand-teal halo ring underneath. Bobs continuously
   so it reads as "moving"; flips horizontally when travel direction
   reverses (east default; data-facing="west" mirrors). */
.wp-map-walker-wrap { background: transparent; border: 0; }

.wp-map-walker {
  position: relative;
  width: 44px;
  height: 44px;
  pointer-events: none;
}
.wp-map-walker__halo {
  position: absolute;
  left: 50%;
  bottom: 6px;
  transform: translateX(-50%);
  width: 30px;
  height: 30px;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(22,172,190,0.35) 0%, rgba(22,172,190,0.0) 70%);
  animation: wp-walker-pulse 1.6s ease-in-out infinite;
}
.wp-map-walker__hiker {
  position: absolute;
  left: 50%;
  bottom: 0;
  width: 28px;
  height: 28px;
  transform: translateX(-50%);
  color: #ffffff;
  filter: drop-shadow(0 1px 2px rgba(0,0,0,0.45));
  animation: wp-hiker-bob 1.2s ease-in-out infinite;
}
.wp-map-walker__hiker svg {
  width: 100%;
  height: 100%;
  overflow: visible;
}
/* Brand-teal fill plate behind the hiker so it pops on busy maps. */
.wp-map-walker__hiker::before {
  content: '';
  position: absolute;
  inset: -2px -3px;
  background: var(--w-brand-500);
  border-radius: 8px 8px 14px 14px;
  z-index: -1;
  box-shadow: 0 2px 6px rgba(0,0,0,0.3);
}
/* Mirror the figure when travelling westward (so it always faces forward). */
.wp-map-walker[data-facing="west"] .wp-map-walker__hiker svg {
  transform: scaleX(-1);
}
@keyframes wp-walker-pulse {
  0%, 100% { transform: translateX(-50%) scale(0.85); opacity: 0.85; }
  50%      { transform: translateX(-50%) scale(1.15); opacity: 0.45; }
}

/* Ghost cursor (hover-preview from the scrubber) */
.leaflet-container .wp-map-ghost {
  filter: drop-shadow(0 0 6px rgba(22,172,190,0.6));
}

/* ── Reduced motion ────────────────────────────────────────────────── */
@media (prefers-reduced-motion: reduce) {
  .wp-chrome,
  .wp-scrub__played,
  .wp-scrub__playhead,
  .wp-chrome__play,
  .wp-chrome__btn { transition: none !important; }
  .wp-scrub--live .wp-scrub__played::after { animation: none !important; }
}
