/* The scroll tour (index.html, trainer.html): one pinned frame whose
   screenshot zooms to each step's region while the caption swaps; on
   phones, a plain list of per-step crops. Markup and data attributes:
   see the tour section of either page. */

/*
   The screenshot and its caption are pinned together, centred in the
   viewport below the header; the .step elements that follow are
   invisible spacers that only set the scroll timing, pulled up under
   the stage so the tour starts as soon as it is centred. Without JS
   the stage is static and the steps render as a plain caption list. */
.tour { padding: 0; }
.tour .wrap { max-width: 1280px; }
.tour-only .t-hero { display: none; }
/* --header-h is the sticky header's measured height (set by tour.js):
   a large system font makes the header taller, and the pinned
   frame must start below it, not under it. */
.tour-stage {
  position: sticky; top: 0; z-index: 2; height: 100vh;
  display: flex; flex-direction: column; justify-content: center;
  padding: calc(var(--header-h, 76px) + 6px) 0 12px;
}
/* The tour walks several screenshots in one frame. Each shot carries
   its own aspect ratio (data-ar), and the frame takes the active
   shot's, so nothing is letterboxed or cropped. */
.frame {
  --ar: 2064 / 1265; --arw: 1.632;
  position: relative; overflow: hidden; border-radius: 14px; border: 1px solid var(--border);
  aspect-ratio: var(--ar); background: var(--bg-surface); box-shadow: 0 30px 80px -40px #000;
  /* Never so tall that the pinned caption gets pushed off a short screen. */
  width: min(100%, calc((100vh - 380px) * var(--arw))); margin-inline: auto; flex-shrink: 0;
  transition: width 0.6s cubic-bezier(0.2, 0.7, 0.1, 1);
}
.zoom {
  position: absolute; inset: 0; transform-origin: 0 0;
  transform: translate(var(--tx, 0%), var(--ty, 0%)) scale(var(--s, 1));
  transition: transform 0.8s cubic-bezier(0.2, 0.7, 0.1, 1);
}
.zoom img {
  position: absolute; inset: 0; display: block; width: 100%; height: 100%; max-width: none;
  object-fit: cover; object-position: top left; opacity: 0; transition: opacity 0.6s;
}
.zoom img.on { opacity: 1; }
.ring {
  position: absolute; opacity: 0; pointer-events: none;
  border: calc(2px / var(--s, 1)) solid var(--accent); border-radius: calc(8px / var(--s, 1));
  box-shadow: 0 0 0 200vmax #0a0d12a6;
  transition: opacity 0.5s, left 0.8s, top 0.8s, width 0.8s, height 0.8s;
}
html:not(.js) .zoom img:first-child { opacity: 1; }
.chapter { color: var(--text-tertiary); }

.step-card {
  max-width: 520px; width: 100%; background: var(--bg-surface); border: 1px solid var(--border);
  border-radius: 14px; padding: 18px 24px;
}
.step-n { font-family: var(--font-mono); font-size: 0.8rem; color: var(--accent-text); }
.step-card h3 { margin: 2px 0 4px; font-size: 1.4rem; }
.step-card p { margin: 0; font-size: 1.02rem; }

.tour-caption { display: none; margin: 16px auto 0; border-color: #4fb55c55; min-height: 116px; flex-shrink: 0; }
html.js .tour-caption { display: block; }
.tour-caption.swap { animation: caption-in 0.45s cubic-bezier(0.2, 0.7, 0.1, 1); }
@keyframes caption-in { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }

.steps { position: relative; z-index: 1; margin-top: -50vh; padding-bottom: 6vh; pointer-events: none; }
.step { min-height: 42vh; display: flex; align-items: center; justify-content: center; }
html.js .steps .step-card { visibility: hidden; }
html:not(.js) .tour-stage { position: static; height: auto; padding: 24px 0; }
html:not(.js) .steps { margin-top: 0; pointer-events: auto; }
html:not(.js) .step { min-height: 0; padding: 12px 0; }

@media (max-width: 860px) {
  /* A phone's tall, narrow viewport: centring a 160px frame in 100vh
     leaves most of the screen empty, so the stage pins the frame just
     under the header instead and is only as tall as it needs to be. */
  .tour-stage { height: auto; justify-content: flex-start; padding: calc(var(--header-h, 60px) + 20px) 0 12px; }
  .steps { margin-top: 0; }
  .step { min-height: 38vh; }
  .step-card { padding: 14px 18px; }
  .step-card h3 { font-size: 1.2rem; }
  .tour-caption { min-height: 104px; }
  /* Phones get no pinned frame: a whole screenshot is unreadable at this
     width, so each step shows its own crop (built by tour.js from
     data-region) above its caption, as a plain list. */
  html.js .tour-stage { display: none; }
  html.js .steps { margin-top: 0; padding: 12px 0 24px; pointer-events: auto; }
  html.js .steps .step-card { visibility: visible; }
  .step { min-height: 0; flex-direction: column; gap: 12px; padding: 16px 0; }
  .steps .step-shot { display: block; }
}

.step-shot {
  display: none; position: relative; overflow: hidden; border-radius: 12px; border: 1px solid var(--border);
  background: var(--bg-surface); aspect-ratio: var(--car); width: min(100%, calc(60vh * var(--car)));
}
.step-shot img {
  position: absolute; display: block; max-width: none; height: auto;
  width: calc(100% / var(--w)); left: calc(-100% * var(--x) / var(--w)); top: calc(-100% * var(--y) / var(--h));
}

/* A small label above a heading. */
.kicker {
  font-family: var(--font-mono); font-size: 0.78rem; letter-spacing: 0.08em; text-transform: uppercase;
  color: var(--accent-text); display: block; margin-bottom: 10px;
}

/* Fade-ins (tour.js adds .in as each scrolls into view). */
html.js .reveal { opacity: 0; transform: translateY(28px); transition: opacity 0.7s, transform 0.7s cubic-bezier(0.2, 0.7, 0.1, 1); }
html.js .reveal.in { opacity: 1; transform: none; }

/* Cards below a tour. .two: a 2 x 2 grid. */
.more { padding: 20px 0 100px; }
.more .wrap { max-width: 1120px; display: grid; grid-template-columns: repeat(3, 1fr); gap: 20px; }
.more-card { background: var(--bg-surface); border: 1px solid var(--border); border-radius: 14px; padding: 22px 24px; }
.more-card h3 { margin: 4px 0 8px; font-size: 1.25rem; }
.more-card p { margin: 0; font-size: 1rem; }
.more-card .mono { font-family: var(--font-mono); color: var(--accent-text); }
@media (max-width: 860px) { .more .wrap { grid-template-columns: 1fr; } }
.more.two .wrap { grid-template-columns: repeat(2, 1fr); max-width: 900px; }
@media (max-width: 860px) { .more.two .wrap { grid-template-columns: 1fr; } }

@media (prefers-reduced-motion: reduce) {
  html.js .reveal { opacity: 1; transform: none; transition: none; }
  .frame, .zoom, .ring, .zoom img { transition: none; }
  .tour-caption.swap { animation: none; }
}
