/* ==========================================================================
   Flexodus — motion layer
   Loaded after style.css so it can extend without touching it.

   Everything here is additive: with JavaScript off, or with reduced motion
   requested, the page still reads correctly — elements simply start in their
   final state. motion.js adds `.js` to <html> before any hiding happens, so
   nothing is ever left invisible because a script failed to load.
   ========================================================================== */

/* --- reveal on scroll ---------------------------------------------------- */
.js .rv {
  opacity: 0;
  transform: translateY(26px);
  transition: opacity .8s var(--ease), transform .8s var(--ease);
}
.js .rv.is-in { opacity: 1; transform: none; }
.rv--d1 { transition-delay: .08s !important; }
.rv--d2 { transition-delay: .16s !important; }
.rv--d3 { transition-delay: .24s !important; }
.rv--d4 { transition-delay: .32s !important; }
/* hover transitions shouldn't inherit the reveal's stagger delay */
.js .rv.is-in.is-settled { transition-delay: 0s !important; }

/* --- hero headline: words rise in one after another ---------------------- */
.split .w { display: inline-block; overflow: hidden; vertical-align: top; padding-bottom: .08em; margin-bottom: -.08em; }
.split .w > span {
  display: inline-block; transform: translateY(105%);
  transition: transform .9s var(--ease); transition-delay: calc(var(--i) * 55ms + 120ms);
}
.split.is-in .w > span { transform: none; }

/* --- hero plate tilt (desktop pointers only; set by motion.js) ----------- */
.chart__plate { transform: rotateX(var(--rx, 0deg)) rotateY(var(--ry, 0deg)); }
.chart:hover .chart__plate { box-shadow: 0 2px 4px rgba(30,38,16,.04), 0 34px 70px rgba(30,38,16,.18); }
.chart__figs img { transition: transform .6s var(--ease); }
.chart:hover .chart__figs img:first-child { transform: translateX(-4px); }
.chart:hover .chart__figs img:last-child  { transform: translateX(4px); }

/* ==========================================================================
   Pinned sequence — the shared mechanism behind both scroll stories.

   A tall outer section provides the scroll distance; a sticky inner panel
   holds the visual still while the copy advances through it.
   ========================================================================== */
.seq { position: relative; }
.seq__stick {
  position: sticky; top: 0;
  height: 100vh; height: 100svh;
  display: grid; align-items: center;
  overflow: hidden;
}

/* ---- 1. the body-map story --------------------------------------------- */
.story { background: var(--olive-deep); color: #fff; }
.story .seq__stick { padding-block: 40px; }
.story__in {
  max-width: var(--max); margin: 0 auto; padding-inline: var(--pad);
  display: grid; grid-template-columns: 1fr 1fr; gap: clamp(24px, 5vw, 70px);
  align-items: center; width: 100%;
}
.story__figs { position: relative; }
.story__plate {
  background: #fff; border-radius: 30px; padding: 28px 20px;
  display: flex; gap: 5%; align-items: center; justify-content: center;
  box-shadow: 0 30px 80px rgba(0,0,0,.3);
}
.story__plate img {
  height: clamp(230px, 46vh, 440px); width: auto;
  /* the map "comes alive" as the story moves on — set by motion.js */
  filter: saturate(var(--sat, .25));
  transition: filter .9s ease;
}

/* one callout per step, accumulating */
.story__tags { position: absolute; inset: 0; pointer-events: none; }
.story__tag {
  position: absolute; display: inline-flex; align-items: center; gap: 8px;
  font-family: var(--mono); font-size: 11px; letter-spacing: .04em;
  background: #fff; color: var(--olive-deep);
  border-radius: 999px; padding: 8px 14px; white-space: nowrap;
  box-shadow: 0 12px 30px rgba(0,0,0,.28);
  opacity: 0; transform: translateY(12px) scale(.94);
  transition: opacity .5s ease, transform .55s var(--ease);
}
.story__tag b { font-family: var(--display); font-size: 11px; letter-spacing: 0; }
.story__tag.is-on { opacity: 1; transform: none; }
.story__tag--1 { top: 22%;  left: -7%; }
.story__tag--2 { top: 30%;  right: -8%; }
.story__tag--3 { top: 46%;  left: -9%; }
.story__tag--4 { top: 56%; right: -7%; }
.story__tag--warn { background: #FDEDE8; color: #8A3E14; }

.story__steps { position: relative; min-height: 270px; }
.story__step {
  position: absolute; inset: 0;
  opacity: 0; transform: translateY(18px);
  transition: opacity .5s ease, transform .6s var(--ease);
  pointer-events: none;
}
.story__step.is-on { opacity: 1; transform: none; pointer-events: auto; }
.story__step .eyebrow { color: var(--yellow); }
.story__step h2 { color: #fff; margin-bottom: 14px; }
.story__step p { color: rgba(255,255,255,.78); font-size: clamp(15px, 1.7vw, 18px); max-width: 44ch; }

.story__rail, .tour__rail { display: flex; gap: 7px; margin-top: 26px; }
.story__pip, .tour__pip { position: relative; width: 38px; height: 3px; border-radius: 2px; overflow: hidden; }
.story__pip { background: rgba(255,255,255,.2); }
.tour__pip { background: var(--rule); }
.story__pip::after, .tour__pip::after {
  content: ''; position: absolute; inset: 0; transform: scaleX(0); transform-origin: 0 50%;
  transition: transform .5s var(--ease);
}
.story__pip::after { background: var(--yellow); }
.tour__pip::after { background: var(--olive); }
.story__pip.is-on::after, .tour__pip.is-on::after,
.story__pip.is-past::after, .tour__pip.is-past::after { transform: scaleX(1); }

@media (max-width: 880px) {
  .story__in { grid-template-columns: 1fr; gap: 18px; }
  .story__plate { padding: 18px 14px; border-radius: 22px; }
  .story__plate img { height: clamp(170px, 30vh, 260px); }
  .story__steps { min-height: 200px; }
  .story__step h2 { font-size: clamp(26px, 7vw, 34px); }
  .story__tag { font-size: 9.5px; padding: 5px 10px; }
  .story__tag--1, .story__tag--3 { left: -2%; }
  .story__tag--2, .story__tag--4 { right: -2%; }
}

/* ---- 2. the phone tour -------------------------------------------------- */
.tour { background: var(--paper); }
.tour__in {
  max-width: var(--max); margin: 0 auto; padding-inline: var(--pad);
  display: grid; grid-template-columns: 1fr 1fr; gap: clamp(24px, 6vw, 80px);
  align-items: center; width: 100%;
}
.tour__kicker { color: var(--olive); margin-bottom: 26px; }
.tour__device { justify-self: center; display: flex; flex-direction: column; align-items: center; gap: 22px; }

/* a simple device frame, drawn in CSS so it scales with no extra image */
.phone {
  position: relative; width: min(300px, 70vw);
  padding: 11px; border-radius: 48px;
  background: linear-gradient(145deg, #2a2f22, #10130c);
  box-shadow: 0 0 0 1.5px #3c4330 inset, 0 40px 80px rgba(30,38,16,.3), 0 8px 20px rgba(30,38,16,.18);
  animation: float 7s ease-in-out infinite;
}
.phone::before {   /* side button */
  content: ''; position: absolute; right: -3px; top: 22%; width: 3px; height: 64px; border-radius: 0 3px 3px 0; background: #1a1e14;
}
.phone__screen { position: relative; aspect-ratio: 760 / 1651; border-radius: 38px; overflow: hidden; background: var(--paper); }
.phone__screen img {
  position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover;
  opacity: 0; transform: translateY(14px) scale(1.02);
  transition: opacity .55s ease, transform .7s var(--ease);
}
.phone__screen img.is-on { opacity: 1; transform: none; }
@keyframes float { 0%, 100% { translate: 0 0; } 50% { translate: 0 -10px; } }

/* tab indicator, echoing the app's bottom bar */
.tabs {
  position: relative; display: grid; grid-template-columns: repeat(4, 1fr);
  background: #fff; border: 1px solid var(--rule); border-radius: 999px; padding: 5px;
  box-shadow: var(--shadow-sm); width: min(300px, 70vw);
}
.tabs__t {
  position: relative; z-index: 1; text-align: center; padding: 8px 0;
  font-family: var(--mono); font-size: 10px; letter-spacing: .12em; text-transform: uppercase; color: var(--muted);
  transition: color .4s ease;
}
.tabs__t.is-on { color: #fff; }
.tabs__ink {
  position: absolute; z-index: 0; top: 5px; bottom: 5px; left: 5px; width: calc((100% - 10px) / 4);
  border-radius: 999px; background: var(--olive);
  transform: translateX(calc(var(--tab, 0) * 100%)); transition: transform .55s var(--ease);
}

.tour__steps { position: relative; min-height: 270px; }
.tour__step {
  position: absolute; inset: 0;
  opacity: 0; transform: translateY(18px);
  transition: opacity .5s ease, transform .6s var(--ease);
  pointer-events: none;
}
.tour__step.is-on { opacity: 1; transform: none; pointer-events: auto; }
.tour__step h3 { font-size: clamp(26px, 3.4vw, 40px); margin-bottom: 14px; }
.tour__step p { color: var(--muted); font-size: clamp(15px, 1.7vw, 17.5px); max-width: 44ch; }

@media (max-width: 880px) {
  .tour__in { grid-template-columns: 1fr; gap: 16px; }
  .tour__in > div:first-child { order: 2; }
  .tour__kicker { display: none; }
  .phone { width: min(190px, 46vw); padding: 7px; border-radius: 32px; }
  .phone__screen { border-radius: 26px; }
  .tabs { width: min(260px, 70vw); }
  .tour__device { gap: 12px; }
  .tour__steps { min-height: 210px; }
  .tour__step h3 { font-size: 24px; margin-bottom: 8px; }
  .tour__step p { font-size: 14.5px; }
  .tour__rail { margin-top: 12px; }
}
@media (max-height: 700px) and (max-width: 880px) {
  .phone { width: min(150px, 40vw); }
}

/* --- counting numbers ---------------------------------------------------- */
.count { font-variant-numeric: tabular-nums; }

/* ==========================================================================
   Reduced motion.
   Scroll-jacking is a genuine accessibility problem — it causes nausea for
   some people, and it's an outright barrier for others. Anyone who has asked
   their OS for less motion gets the whole page laid out statically, with
   every step of both sequences visible at once rather than hidden.
   ========================================================================== */
@media (prefers-reduced-motion: reduce) {
  .js .rv { opacity: 1; transform: none; transition: none; }
  .split .w > span { transform: none; transition: none; }
  .hl { background-size: 100% 100%; transition: none; }
  .tag, .phone, .close__glow { animation: none; }
  .chart__plate { transform: none !important; }

  .seq__stick { position: static; height: auto; padding-block: clamp(48px, 8vw, 90px); }
  .seq { height: auto !important; }

  .story__steps, .tour__steps { min-height: 0; }
  .story__step, .tour__step {
    position: static; opacity: 1; transform: none; pointer-events: auto;
    margin-bottom: 34px; transition: none;
  }
  .story__plate img { filter: none; }
  .story__figs { display: flex; flex-direction: column; gap: 20px; }
  .story__plate { width: 100%; }
  .story__tag { position: static; opacity: 1; transform: none; margin: 5px; transition: none; }
  .story__tags {
    position: static; display: flex; flex-wrap: wrap;
    justify-content: center; margin: 0; inset: auto;
  }

  .tour__device { display: grid; grid-template-columns: repeat(2, 1fr); gap: 16px; }
  .phone { width: auto; display: contents; }
  .phone::before { display: none; }
  .phone__screen { display: contents; }
  .phone__screen img { position: static; opacity: 1; transform: none; height: auto; border-radius: 22px; transition: none; box-shadow: var(--shadow-lg); }
  .tabs { display: none; }

  .story__rail, .tour__rail { display: none; }
}
