/* =============================================================
   TEASHOP V2 — SCROLL JOURNEY
   Loaded on the front page only. Owns the `.journey-*` namespace.
   ============================================================= */

.journey {
  position: relative;
  background: var(--night-2);
  /* #main-content is unconstrained, so the stage is already edge-to-edge.
     A 100vw full-bleed trick would only add the scrollbar's width back as
     overflow and shift the copy and rail off-centre. */
  width: 100%;
}

/* The track is what the reader actually scrolls; the stage sticks inside it.
   Height scales with chapter count so adding a seventh chapter in the
   Customizer does not compress the pacing of the other six. */
.journey-track {
  position: relative;
  height: calc(var(--journey-chapters, 6) * 90vh);
}

.journey-stage {
  position: sticky;
  top: 0;
  height: 100vh;
  overflow: hidden;
  isolation: isolate;
  background: #101812;
}

/* --- Plates ------------------------------------------------- */

.journey-canvas,
.journey-plate,
.journey-plate img,
.journey-film {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
}

.journey-canvas { z-index: 0; }

.journey-plate {
  margin: 0;
  opacity: 0;
  /* Held slightly over-size so the drift never exposes an edge. */
  transform: scale(1.08);
  transition: opacity 0.9s ease;
  will-change: opacity, transform;
}

.journey-plate.is-active { opacity: 1; }

.journey-plate img,
.journey-film {
  object-fit: cover;
  object-position: center;
  filter: saturate(0.88) contrast(1.04) brightness(0.92);
}

.journey-film { opacity: 0; }
.journey-plate.has-film .journey-film { opacity: 1; }
.journey-plate.has-film img { opacity: 0; }

.journey-shade {
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  background:
    /* Top scrim: the header floats on this, and chapter images vary from
       bright sky to dark interior, so the backing has to be guaranteed. */
    linear-gradient(180deg, rgba(7, 12, 8, 0.72) 0%, rgba(7, 12, 8, 0.34) 12%, transparent 24%),
    linear-gradient(90deg, rgba(7, 12, 8, 0.82) 0%, rgba(7, 12, 8, 0.42) 40%, rgba(7, 12, 8, 0.04) 72%),
    linear-gradient(0deg, rgba(7, 12, 8, 0.72) 0%, rgba(7, 12, 8, 0.10) 42%, transparent 70%),
    radial-gradient(circle at 68% 28%, transparent 0%, rgba(6, 10, 7, 0.18) 66%, rgba(6, 10, 7, 0.52) 100%);
}

/* --- Copy ---------------------------------------------------- */

.journey-copy-layer {
  position: absolute;
  inset: 0;
  z-index: 3;
  pointer-events: none;
}

.journey-copy {
  position: absolute;
  left: clamp(22px, 7vw, 108px);
  top: 50%;
  width: min(560px, 44vw);
  opacity: 0;
  transform: translateY(calc(-50% + 26px));
  transition: opacity 0.6s ease, transform 0.75s cubic-bezier(0.2, 0.75, 0.2, 1);
}

.journey-copy.is-active {
  opacity: 1;
  transform: translateY(-50%);
  pointer-events: auto;
}

.journey-kicker {
  display: flex;
  align-items: center;
  gap: 13px;
  margin: 0 0 22px;
  color: rgba(236, 229, 214, 0.76);
  font-size: 0.7rem;
  font-weight: 500;
  letter-spacing: 0.17em;
  text-transform: uppercase;
}

.journey-kicker::before {
  content: "";
  width: 34px;
  height: 1px;
  background: currentColor;
  flex: none;
}

.journey-title {
  max-width: 12ch;
  margin: 0;
  font-family: var(--font-heading);
  font-size: clamp(2.9rem, 6.4vw, 7rem);
  font-weight: 300;
  line-height: 0.92;
  letter-spacing: -0.045em;
  color: var(--ink);
  text-wrap: balance;
  text-shadow: 0 4px 38px rgba(4, 8, 5, 0.42);
}

.journey-title em {
  font-style: italic;
  color: var(--color-accent);
}

.journey-body {
  max-width: 42ch;
  margin: 26px 0 0;
  color: rgba(244, 240, 228, 0.8);
  font-size: clamp(0.95rem, 1.1vw, 1.1rem);
  line-height: 1.65;
  text-shadow: 0 2px 18px rgba(4, 8, 5, 0.6);
}

.journey-note {
  display: inline-flex;
  margin-top: 26px;
  padding: 8px 14px;
  border: 1px solid rgba(255, 255, 255, 0.22);
  border-radius: var(--radius-pill);
  color: rgba(244, 240, 228, 0.72);
  font-size: 0.67rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  backdrop-filter: blur(12px);
}

.journey-cta {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  margin-top: 30px;
  padding: 14px 26px;
  border-radius: var(--radius-pill);
  background: var(--paper);
  color: var(--night);
  font-size: 0.75rem;
  font-weight: 700;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  transition: transform 0.25s ease, background 0.25s ease;
}

.journey-cta::after { content: "\2192"; }
.journey-cta:hover {
  transform: translateY(-2px);
  background: #fffaf0;
  color: var(--night);
}

/* --- Chapter rail -------------------------------------------- */

.journey-rail {
  position: absolute;
  right: clamp(16px, 3vw, 46px);
  top: 50%;
  z-index: 5;
  display: flex;
  flex-direction: column;
  gap: 18px;
  transform: translateY(-50%);
}

.journey-rail::before {
  content: "";
  position: absolute;
  top: 9px;
  bottom: 9px;
  left: 50%;
  width: 1px;
  background: rgba(255, 255, 255, 0.24);
  transform: translateX(-50%);
}

.journey-dot {
  position: relative;
  width: 18px;
  height: 18px;
  padding: 0;
  border: 0;
  background: transparent;
  cursor: pointer;
}

.journey-dot::after {
  content: "";
  position: absolute;
  inset: 6px;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.42);
  transition: inset 0.3s ease, background 0.3s ease, box-shadow 0.3s ease;
}

.journey-dot.is-active::after {
  inset: 3px;
  background: var(--paper);
  box-shadow: 0 0 0 5px rgba(236, 229, 214, 0.16);
}

.journey-dot-label {
  position: absolute;
  top: 50%;
  right: 28px;
  color: var(--ink);
  opacity: 0;
  white-space: nowrap;
  transform: translate(6px, -50%);
  transition: opacity 0.25s ease, transform 0.25s ease;
  font-size: 0.68rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  text-shadow: 0 2px 12px rgba(4, 8, 5, 0.8);
}

.journey-dot:hover .journey-dot-label,
.journey-dot.is-active .journey-dot-label {
  opacity: 1;
  transform: translate(0, -50%);
}

/* --- HUD ------------------------------------------------------ */

.journey-hud {
  position: absolute;
  left: clamp(22px, 4.8vw, 72px);
  right: clamp(22px, 4.8vw, 72px);
  bottom: 26px;
  z-index: 5;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-5);
  color: rgba(244, 240, 228, 0.64);
  font-size: 0.66rem;
  letter-spacing: 0.13em;
  text-transform: uppercase;
}

.journey-count b { color: var(--paper); font-weight: 600; }

.journey-progress {
  position: relative;
  flex: 1;
  max-width: min(280px, 28vw);
  height: 1px;
  background: rgba(255, 255, 255, 0.2);
}

.journey-progress::after {
  content: "";
  position: absolute;
  inset: 0;
  background: var(--paper);
  transform: scaleX(var(--journey-progress, 0));
  transform-origin: 0 50%;
}

.journey-scroll {
  display: flex;
  align-items: center;
  gap: 11px;
}

.journey-scroll i {
  position: relative;
  width: 22px;
  height: 34px;
  flex: none;
  border: 1px solid rgba(255, 255, 255, 0.44);
  border-radius: var(--radius-pill);
}

.journey-scroll i::after {
  content: "";
  position: absolute;
  top: 7px;
  left: 50%;
  width: 2px;
  height: 7px;
  background: var(--paper);
  border-radius: 4px;
  transform: translateX(-50%);
  animation: journey-wheel 1.7s ease-in-out infinite;
}

@keyframes journey-wheel {
  0%   { opacity: 0; transform: translate(-50%, 0); }
  35%  { opacity: 1; }
  100% { opacity: 0; transform: translate(-50%, 10px); }
}

/* The seam where the journey hands over to the shop. */
.journey-outro {
  position: relative;
  z-index: 2;
  padding: clamp(60px, 9vw, 120px) 0 clamp(40px, 6vw, 80px);
  background: linear-gradient(180deg, var(--night-2) 0%, var(--color-bg) 100%);
  text-align: center;
}

.journey-outro h2 {
  margin: 0 auto;
  max-width: 18ch;
  font-family: var(--font-heading);
  font-size: clamp(1.9rem, 3.6vw, 3.1rem);
  font-weight: 300;
  line-height: 1.08;
  letter-spacing: -0.03em;
  color: var(--ink);
}

.journey-outro p {
  margin: var(--space-5) auto 0;
  max-width: 52ch;
  color: var(--color-text-light);
  font-size: var(--text-lg);
  line-height: var(--leading-relaxed);
}

/* --- Small screens -------------------------------------------- */

@media (max-width: 900px) {
  .journey-copy { width: min(560px, 62vw); }
}

@media (max-width: 760px) {
  .journey-track { height: calc(var(--journey-chapters, 6) * 82vh); }

  .journey-shade {
    background:
      linear-gradient(0deg, rgba(7, 12, 8, 0.9) 0%, rgba(7, 12, 8, 0.52) 40%, transparent 70%),
      radial-gradient(circle at 50% 34%, transparent 0%, rgba(6, 10, 7, 0.3) 92%);
  }

  .journey-copy {
    left: 20px;
    right: 52px;
    top: auto;
    bottom: 92px;
    width: auto;
    transform: translateY(20px);
  }

  .journey-copy.is-active { transform: none; }

  .journey-title {
    max-width: 11ch;
    font-size: clamp(2.5rem, 11vw, 4.4rem);
  }

  .journey-body {
    margin-top: 16px;
    font-size: 0.92rem;
    line-height: 1.55;
  }

  .journey-note { display: none; }
  .journey-cta { margin-top: 20px; padding: 12px 20px; }

  .journey-rail { right: 10px; gap: 13px; }
  .journey-dot-label { display: none; }

  .journey-hud { left: 20px; right: 20px; bottom: 18px; }
  .journey-progress { display: none; }
  .journey-scroll span { display: none; }

  .journey-plate img,
  .journey-film { object-position: 50% 45%; }
}

/* --- Reduced motion -------------------------------------------
   The drift and the scrub both go; chapters still change, because
   that is the content, not the decoration. */
@media (prefers-reduced-motion: reduce) {
  .journey-plate { transform: none !important; transition: opacity 0.2s linear; }
  .journey-copy { transition: opacity 0.2s linear; }
  .journey-scroll i::after { animation: none; }
  .journey-film { display: none; }
}

/* Once the engine is driving opacity per frame, the CSS crossfade would
   only smear it. The transition stays as the no-JS fallback. */
.journey.is-live .journey-plate { transition: none; }

/* =============================================================
   HEADER HANDOVER
   Over the journey the header is glass on top of the film; once the
   stage has been scrolled past, journey.js adds .is-pinned and it
   becomes the ordinary solid header the rest of the site uses.
   ============================================================= */

/* Sticky is not enough: a sticky header still occupies flow, so it would sit
   *above* the stage and read as a solid bar rather than floating on the film.
   Fixed takes it out of flow, the journey starts at the top of the viewport,
   and everything after the stage scrolls under it exactly as a sticky header
   would elsewhere on the site. */
body.has-journey .site-header {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  background: transparent;
  border-bottom: 1px solid rgba(255, 255, 255, 0.12);
  box-shadow: none;
  transition: background 0.35s ease, border-color 0.35s ease, box-shadow 0.35s ease;
}

body.has-journey .site-header .header-main { border-bottom: none; }

body.has-journey .site-header .header-nav {
  background: transparent;
  border-bottom: none;
}

body.has-journey .site-header .header-search-form,
body.has-journey .site-header .nav-categories-toggle {
  background: rgba(255, 255, 255, 0.07);
  border-color: rgba(255, 255, 255, 0.16);
  backdrop-filter: blur(10px);
}

body.has-journey .site-header .header-search-input,
body.has-journey .site-header .header-search-input::placeholder,
body.has-journey .site-header .header-search-category {
  color: var(--paper);
}

body.has-journey .site-header .header-action-btn:hover {
  background: rgba(255, 255, 255, 0.08);
}

/* --color-text-muted is tuned for a flat dark panel, not for photography.
   Over the film the whole header lifts to paper and picks up a shadow. */
body.has-journey .site-header:not(.is-pinned) .header-action-label {
  color: rgba(244, 240, 228, 0.72);
}

body.has-journey .site-header:not(.is-pinned) .header-action-main,
body.has-journey .site-header:not(.is-pinned) .cart-total,
body.has-journey .site-header:not(.is-pinned) .site-logo-text,
body.has-journey .site-header:not(.is-pinned) .primary-nav > ul > li > a,
body.has-journey .site-header:not(.is-pinned) .nav-categories-toggle {
  color: var(--ink);
}

body.has-journey .site-header:not(.is-pinned) .site-logo-subtitle {
  color: rgba(244, 240, 228, 0.6);
}

body.has-journey .site-header:not(.is-pinned) .site-logo-text span,
body.has-journey .site-header:not(.is-pinned) .primary-nav > ul > li.current-menu-item > a {
  color: var(--color-accent);
}

body.has-journey .site-header:not(.is-pinned) .header-main,
body.has-journey .site-header:not(.is-pinned) .header-nav {
  text-shadow: 0 1px 14px rgba(4, 8, 5, 0.75);
}

body.has-journey .site-header:not(.is-pinned) .header-action-btn,
body.has-journey .site-header:not(.is-pinned) .header-top-link {
  color: var(--ink);
}

/* Scrolled past — back to the solid header. */
body.has-journey .site-header.is-pinned {
  background: var(--color-bg);
  border-bottom-color: var(--color-border);
  box-shadow: 0 2px 24px rgba(0, 0, 0, 0.45);
}

body.has-journey .site-header.is-pinned .header-nav { border-bottom: none; }

body.has-journey .site-header.is-pinned .header-search-form,
body.has-journey .site-header.is-pinned .nav-categories-toggle {
  background: var(--color-surface);
  border-color: var(--color-border);
  backdrop-filter: none;
}

body.has-journey .site-header.is-pinned .header-search-input,
body.has-journey .site-header.is-pinned .header-search-category {
  color: var(--color-text);
}
