/* /tour — the walkthrough page. The stage takes whatever the nav leaves and
   everything else floats over it: the machine is the page, and the words are
   a caption on it. */

.tour-stage {
  flex: 1;
  min-height: 0;
  position: relative;
}

/* The dip a model swap passes through — the background colour, brought up over
   the picture while the next model lands and taken back down as it comes in.
   The camera keeps moving underneath, so the move reads as passing through a
   wall rather than as a cut. */
.tour-veil {
  position: absolute;
  inset: 0;
  z-index: 12;
  background: var(--bg);
  opacity: 0;
  pointer-events: none;
  transition: opacity 90ms linear;
}

/* THE PICKER'S PANEL IS NOT PART OF A WALKTHROUGH. Isolating a sub-assembly
   puts bodies in `state.hiddenComponents`, and component-picker.js shows its
   panel whenever that set is non-empty — reasonably, because on /3d a hidden
   body needs a way back. Here the same rule opened a list of 137 hidden bodies
   over the narration on the beat that enters the vessel. The panel is built and
   parented as always; it is only not drawn, so nothing about the picker's own
   surface changes and this cannot reach /3d. */
#tour-stage > .component-panel { display: none; }

/* The loader's scrim and pill stand ABOVE the dip. A model swap raises the
   veil and then waits for the next model, and on a cold cache that wait is
   seconds — a page holding a flat colour with nothing on it reads as broken
   where the same page holding "Loading…" reads as working. */
.tour-stage > .cad-loading { z-index: 13; }

#tour-hud-host { position: absolute; inset: 0; pointer-events: none; z-index: 14; }
.tour-hud { position: absolute; inset: 0; }
.tour-hud > * { pointer-events: auto; }

/* ── the banner ─────────────────────────────────────────────────────────── */
.tour-banner {
  position: absolute;
  top: calc(env(safe-area-inset-top, 0px) + 16px);
  left: calc(env(safe-area-inset-left, 0px) + 18px);
  display: flex;
  flex-direction: column;
  gap: 2px;
  pointer-events: none;
  text-shadow: 0 1px 6px rgba(0, 0, 0, 0.7);
}
.tour-banner-title { font-size: 15px; font-weight: 600; letter-spacing: 0.01em; }
.tour-banner-sub { font-size: 12px; color: var(--text-2); }

/* ── the narration card ─────────────────────────────────────────────────── */
.tour-card {
  position: absolute;
  left: calc(env(safe-area-inset-left, 0px) + 18px);
  bottom: calc(env(safe-area-inset-bottom, 0px) + 92px);
  width: min(30rem, calc(100vw - 36px));
  padding: 16px 18px 14px;
  background: rgba(35, 35, 66, 0.9);
  border: 1px solid var(--border);
  border-radius: 14px;
  box-shadow: 0 12px 40px rgba(0, 0, 0, 0.55);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  opacity: 0;
  transform: translateY(8px);
  transition: opacity 260ms ease, transform 260ms ease;
}
.tour-card.in { opacity: 1; transform: none; }

.tour-kicker {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  font-size: 11px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  margin-bottom: 6px;
}
.tour-kicker-name { color: #35e0d0; }
.tour-kicker-count { color: var(--text-3); letter-spacing: 0.08em; flex: none; }
.tour-title { margin: 0 0 6px; font-size: 20px; line-height: 1.25; font-weight: 600; }
.tour-body { margin: 0; font-size: 14px; line-height: 1.55; color: #d6d6e4; }

.tour-chips { display: flex; flex-wrap: wrap; gap: 5px; margin-top: 11px; }
.tour-chip {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 10.5px;
  line-height: 1.6;
  padding: 1px 7px;
  border-radius: 999px;
  color: #9fe9e0;
  background: color-mix(in srgb, #35e0d0 14%, transparent);
  border: 1px solid color-mix(in srgb, #35e0d0 34%, transparent);
}

/* ── transport ──────────────────────────────────────────────────────────── */
.tour-bar {
  position: absolute;
  left: 50%;
  transform: translateX(-50%);
  bottom: calc(env(safe-area-inset-bottom, 0px) + 18px);
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 12px;
  max-width: calc(100vw - 24px);
  background: rgba(26, 26, 46, 0.86);
  border: 1px solid var(--border);
  border-radius: 999px;
  box-shadow: 0 10px 30px rgba(0, 0, 0, 0.5);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
}
.tour-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 34px; height: 34px;
  border-radius: 50%;
  border: 1px solid transparent;
  background: transparent;
  color: var(--text);
  cursor: pointer;
}
.tour-btn:hover { background: var(--surface-2); }
.tour-play { background: var(--surface-2); border-color: var(--border); }

/* One dot per beat. `--fill` is how far through the beat the player is, so the
   rail is a progress bar and a table of contents at once. */
/* Chapters, and the beats inside them. The gap between groups is what makes
   thirty ticks readable as eight things. */
.tour-rail { display: flex; align-items: center; gap: 9px; }
.tour-chapter { display: flex; align-items: center; gap: 3px; }
.tour-dot {
  position: relative;
  width: 8px; height: 26px;
  padding: 0;
  border: 0;
  background: transparent;
  cursor: pointer;
}
.tour-dot::before {
  content: "";
  position: absolute;
  left: 2px; right: 2px; top: 11px;
  height: 4px;
  border-radius: 2px;
  background: var(--border);
}
.tour-dot.done::before { background: color-mix(in srgb, #4d8dff 60%, transparent); }
.tour-dot-fill {
  position: absolute;
  left: 2px; right: 2px; top: 11px;
  height: 4px;
  border-radius: 2px;
  background: #35e0d0;
  opacity: 0;
  transform: scaleX(0);
  transform-origin: left;
}
.tour-dot.now { width: 18px; }
.tour-dot.now .tour-dot-fill { opacity: 1; transform: scaleX(var(--fill-x, 0)); }
.tour-dot:hover::before { background: var(--text-2); }

.tour-chip-btn {
  font-size: 11.5px;
  padding: 5px 10px;
  border-radius: 999px;
  border: 1px solid var(--border);
  background: transparent;
  color: var(--text-2);
  cursor: pointer;
  white-space: nowrap;
}
.tour-chip-btn:hover { color: var(--text); border-color: var(--text-3); }
.tour-chip-btn.on {
  color: var(--text);
  border-color: color-mix(in srgb, var(--accent) 60%, transparent);
  background: color-mix(in srgb, var(--accent) 22%, transparent);
}
/* The pose readout is a tool for whoever is writing the tour, not for whoever
   is watching it. */
.tour-dev { display: none; }
html.dev-mode .tour-dev { display: inline-block; }

/* ── grabbed ────────────────────────────────────────────────────────────── */
.tour-resume {
  position: absolute;
  top: calc(env(safe-area-inset-top, 0px) + 16px);
  left: 50%;
  transform: translateX(-50%) translateY(-8px);
  padding: 8px 18px;
  font-size: 13px;
  border-radius: 999px;
  border: 1px solid color-mix(in srgb, #35e0d0 50%, transparent);
  background: color-mix(in srgb, #35e0d0 18%, rgba(26, 26, 46, 0.92));
  color: var(--text);
  cursor: pointer;
  opacity: 0;
  pointer-events: none;
  transition: opacity 200ms ease, transform 200ms ease;
}
.tour-hud.grabbed .tour-resume {
  opacity: 1;
  pointer-events: auto;
  transform: translateX(-50%) translateY(0);
}

/* ── the pose flash ─────────────────────────────────────────────────────── */
.tour-flash {
  position: absolute;
  left: 50%;
  bottom: calc(env(safe-area-inset-bottom, 0px) + 72px);
  transform: translateX(-50%) translateY(6px);
  padding: 7px 14px;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 12px;
  border-radius: 10px;
  background: rgba(26, 26, 46, 0.95);
  border: 1px solid var(--border);
  opacity: 0;
  transition: opacity 200ms ease, transform 200ms ease;
  pointer-events: none;
}
.tour-flash.in { opacity: 1; transform: translateX(-50%) translateY(0); }

/* ── phone ──────────────────────────────────────────────────────────────── */
@media (max-width: 720px) {
  .tour-card {
    left: 10px; right: 10px;
    width: auto;
    bottom: calc(env(safe-area-inset-bottom, 0px) + 84px);
    padding: 13px 14px 12px;
  }
  .tour-title { font-size: 17px; }
  .tour-body { font-size: 13px; }
  .tour-bar { gap: 7px; padding: 7px 9px; bottom: calc(env(safe-area-inset-bottom, 0px) + 10px); }
  .tour-rail { gap: 6px; }
  .tour-chapter { gap: 2px; }
  .tour-dot { width: 5px; }
  .tour-dot.now { width: 12px; }
  .tour-banner-sub { display: none; }
  .tour-chips { display: none; }
}

.tour-chip-more {
  color: var(--text-2);
  background: transparent;
  border-color: var(--border);
}
/* A beat naming a body this model does not carry. The tree renames solids and
   the tour names them, so the chip says which name went stale rather than
   leaving a beat that frames the whole machine and lights nothing. */
.tour-chip-missing {
  color: var(--err);
  background: color-mix(in srgb, var(--err) 12%, transparent);
  border-color: color-mix(in srgb, var(--err) 45%, transparent);
  text-decoration: line-through;
}

/* ── the from/to pins ───────────────────────────────────────────────────── */
/* Screen-space labels on the two subjects of a move, positioned each frame by
   tags.js. `will-change` because they move every frame while a flight runs. */
.tour-tag {
  position: absolute;
  top: 0; left: 0;
  display: inline-flex;
  align-items: baseline;
  gap: 6px;
  padding: 4px 11px;
  font-size: 12px;
  line-height: 1.4;
  white-space: nowrap;
  border-radius: 999px;
  border: 1px solid var(--border);
  background: rgba(26, 26, 46, 0.9);
  box-shadow: 0 6px 20px rgba(0, 0, 0, 0.45);
  pointer-events: none;
  opacity: 0;
  will-change: transform, opacity;
}
.tour-tag-arrow { font-size: 13px; opacity: 0.9; }
.tour-tag-from { color: var(--text-2); }
.tour-tag-from .tour-tag-arrow { color: #4d8dff; }
.tour-tag-to {
  color: var(--text);
  border-color: color-mix(in srgb, #35e0d0 45%, transparent);
}
.tour-tag-to .tour-tag-arrow { color: #35e0d0; }

@media (max-width: 720px) {
  .tour-tag { font-size: 11px; padding: 3px 9px; }
}

/* ── the chapter's name, when the chapter turns over ───────────────────────
   Arrives over the shot and leaves again. Big enough to be read without being
   looked at, and out of the narration card's way — it sits above it, so the
   two never occupy the same line of sight. */
.tour-chapter-card {
  position: absolute;
  left: calc(env(safe-area-inset-left, 0px) + 18px);
  bottom: calc(env(safe-area-inset-bottom, 0px) + 250px);
  max-width: min(30rem, calc(100vw - 36px));
  opacity: 0;
  transform: translateY(10px);
  transition: opacity 520ms ease, transform 520ms ease;
  pointer-events: none;
}
.tour-chapter-card.in { opacity: 1; transform: none; }
.tour-chapter-name {
  font-size: clamp(1.6rem, 4vw, 2.4rem);
  font-weight: 600;
  line-height: 1.1;
  letter-spacing: -0.01em;
  color: #eaeaf4;
  text-shadow: 0 2px 20px rgba(0, 0, 0, 0.85), 0 0 60px rgba(0, 0, 0, 0.6);
}

/* ── the title, over the machine while it is still closed ─────────────────
   The tour opens on the appliance as an object; this is what stands on it for
   those three seconds, and it leaves as the machine dissolves so the two
   motions read as one. */
.tour-title-card {
  position: absolute;
  left: 50%;
  top: 42%;
  transform: translate(-50%, -50%) scale(0.985);
  text-align: center;
  opacity: 0;
  transition: opacity 900ms ease, transform 1400ms ease;
  pointer-events: none;
}
.tour-title-card.in { opacity: 1; transform: translate(-50%, -50%) scale(1); }
.tour-title-main {
  font-size: clamp(2rem, 6vw, 3.4rem);
  font-weight: 600;
  letter-spacing: -0.02em;
  line-height: 1.05;
  text-shadow: 0 2px 30px rgba(0, 0, 0, 0.9);
}
.tour-title-sub {
  margin-top: 8px;
  font-size: clamp(0.85rem, 2vw, 1rem);
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: #9aa0bd;
  text-shadow: 0 2px 16px rgba(0, 0, 0, 0.9);
}

/* The closing beat drops the words entirely: the last thing on screen is the
   machine and the line through it. */
.tour-card.gone { opacity: 0 !important; transform: translateY(8px); }

@media (max-width: 720px) {
  .tour-chapter-card { bottom: calc(env(safe-area-inset-bottom, 0px) + 232px); right: 10px; left: 10px; }
  .tour-title-card { top: 38%; }
}
