/* ============================================================================
   bundle-immersive.css — Tier 4 only. The scroll-driven walk-through.

   READ THIS BEFORE EDITING: everything that hides content, collapses it into a
   3D scene, or pins it to the viewport lives under `.is-flying`, which
   bundle-immersive.js adds only once it is running. Without that class the
   section is an ordinary vertical list of captioned photographs.

   That is not a nicety. A "3D experience" that renders a blank page when a
   script fails is worse than no 3D at all — and this tier is the one a client
   pays $3,997 for, so it is the one that must degrade most gracefully.
   ========================================================================== */

/* ---------- Base: a plain gallery. This is what everyone gets first. ------- */
.jr{padding-block:clamp(48px,7vw,110px)}
.jr-intro{max-width:60ch;margin-inline:auto;text-align:center;margin-bottom:clamp(32px,5vw,64px)}
.jr-intro h2{margin-bottom:14px}
.jr-intro p{color:var(--fg-muted);font-size:var(--text-lg)}

.jr-world{display:flex;flex-direction:column;gap:clamp(28px,5vw,72px);max-width:1100px;margin-inline:auto}
.jr-item{margin:0}
.jr-item img{display:block;width:100%;height:auto;border-radius:var(--radius-lg)}
.jr-cap{display:flex;gap:12px;align-items:baseline;margin-top:12px;color:var(--fg-muted);font-size:.92rem}
.jr-cap .jr-idx{color:var(--accent);font-variant-numeric:tabular-nums;font-weight:600}
.jr-word{
  font-family:var(--font-display);
  font-size:clamp(1.8rem,1.2rem + 3vw,3.4rem);
  line-height:1.15;letter-spacing:var(--display-tracking,-.02em);
  text-align:center;max-width:20ch;margin-inline:auto;
}
.jr-word em{color:var(--accent);font-style:italic}
.jr-sky{display:none}

/* ---------- Upgraded: the camera flies through -------------------------- */
.jr.is-flying{
  position:relative;
  height:var(--jr-length,600vh);   /* set by JS from the deepest item */
  padding:0;
}
.jr.is-flying .jr-stage{
  position:sticky;top:0;height:100vh;overflow:hidden;
  perspective:900px;perspective-origin:50% 50%;
  transition:background-color .2s linear;
}
.jr.is-flying .jr-sky{
  display:block;position:absolute;inset:0;pointer-events:none;z-index:0;
}
.jr.is-flying .jr-world{
  position:absolute;inset:0;display:block;max-width:none;margin:0;
  transform-style:preserve-3d;will-change:transform;
}
.jr.is-flying .jr-item{
  position:absolute;left:50%;top:50%;
  width:var(--jr-w,60vw);margin:0;
  will-change:transform,opacity;backface-visibility:hidden;
}
.jr.is-flying .jr-item img{
  border-radius:2px;
  box-shadow:0 30px 90px rgba(0,0,0,.28);
}
.jr.is-flying .jr-word{
  position:absolute;left:50%;top:50%;
  width:max-content;max-width:70vw;margin:0;
  will-change:transform,opacity;
}
.jr.is-flying .jr-intro{
  position:absolute;inset:auto 0 auto 0;top:50%;translate:0 -50%;
  z-index:2;margin:0;padding-inline:24px;
}

/* Night: the walk ends after dark, so the type has to invert with it. */
.jr.is-flying.is-night .jr-cap{color:rgba(239,230,216,.62)}
.jr.is-flying.is-night .jr-word{color:#efe6d8}

/* The scene is decorative depth; the captions are the content. Keeping them
   legible at every distance matters more than the parallax does. */
.jr.is-flying .jr-cap{
  justify-content:center;font-size:.82rem;letter-spacing:.04em;
  text-transform:uppercase;
}

@media (max-width:760px){
  /* Phones: perspective at this depth induces motion sickness and the captions
     become unreadable. The plain gallery is the better product here, so the
     upgrade is simply refused. */
  .jr.is-flying{height:auto;padding-block:clamp(48px,7vw,110px)}
  .jr.is-flying .jr-stage{position:static;height:auto;overflow:visible;perspective:none;background:none!important}
  .jr.is-flying .jr-sky{display:none}
  .jr.is-flying .jr-world{position:static;display:flex;flex-direction:column;gap:36px;transform:none!important;max-width:1100px;margin-inline:auto}
  .jr.is-flying .jr-item,
  .jr.is-flying .jr-word{position:static;width:auto!important;max-width:none;transform:none!important;opacity:1!important;visibility:visible!important;translate:none}
  .jr.is-flying .jr-intro{position:static;translate:none;opacity:1!important}
}

@media (prefers-reduced-motion: reduce){
  .jr.is-flying .jr-world{transition:none}
  .jr.is-flying .jr-item,.jr.is-flying .jr-word{will-change:auto}
}

/* Film grain + vignette — the two finishing layers the immersive skill calls
   out as what removes the "clean CSS" feel. Pure CSS, zero JS: turbulence
   grain as an inline SVG tile at 5%, and a soft radial vignette. Scoped to
   the flying state; the stacked fallback stays a plain gallery. */
.jr.is-flying .jr-stage::before{
  content:'';position:absolute;inset:0;z-index:3;pointer-events:none;
  background:radial-gradient(ellipse at 50% 45%, transparent 58%, rgba(0,0,0,.30) 100%);
}
.jr.is-flying .jr-stage::after{
  content:'';position:absolute;inset:-40px;z-index:3;pointer-events:none;opacity:.05;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='240' height='240'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2'/%3E%3C/filter%3E%3Crect width='240' height='240' filter='url(%23n)'/%3E%3C/svg%3E");
  animation:jr-grain 900ms steps(3) infinite;
}
@keyframes jr-grain{
  0%{transform:translate(0,0)} 33%{transform:translate(-14px,9px)}
  66%{transform:translate(11px,-13px)} 100%{transform:translate(0,0)}
}
@media (prefers-reduced-motion: reduce){
  .jr.is-flying .jr-stage::after{animation:none}
}

/* ---------- Scroll-scrubbed film ----------
   Base state: a normal, playable video in the flow — a person with no JS can
   press play and watch the whole thing. Flying state: full-bleed behind the
   world, controls stripped, playhead owned by the scroll. */
.jr-film{margin:0 auto;max-width:1100px}
.jr-film video{display:block;width:100%;height:auto;border-radius:var(--radius-lg);background:#000}
.jr-film .jr-cap{justify-content:center;margin-top:10px}

.jr.is-flying .jr-film{
  position:absolute;inset:0;z-index:1;max-width:none;
  opacity:0;visibility:hidden;will-change:opacity;
}
.jr.is-flying .jr-film video{
  width:100%;height:100%;object-fit:cover;border-radius:0;
}
.jr.is-flying .jr-film .jr-cap{
  position:absolute;left:0;right:0;bottom:clamp(24px,5vh,56px);
  font-size:.8rem;letter-spacing:.14em;text-transform:uppercase;
  color:rgba(255,255,255,.75);text-shadow:0 1px 16px rgba(0,0,0,.6);
}
