/* =========================================================
   Future Lens: motion
   Every rule here waits for the "motion" class on <html>, which the
   small script in each page's head adds only when the visitor hasn't
   asked their device for reduced motion. Without it (or without
   JavaScript) the site shows fully, with no movement.

   The idea: a camera. Things come into focus as you reach them,
   lines draw like a timeline, and pages change through an iris.
   ========================================================= */

/* The iris shutter animates this length; registering it lets it transition */
@property --iris {
  syntax: "<length>";
  inherits: false;
  initial-value: 0px;
}

@media screen and (prefers-reduced-motion: no-preference) {

  html.motion { scroll-behavior: smooth; interpolate-size: allow-keywords; }

  /* ---------- Arriving from another page: black frame with the aperture
     until the iris opens (no flash of the page underneath) ---------- */
  html.iris-in body::after {
    content: "";
    position: fixed;
    inset: 0;
    z-index: 299;
    background: #131513 url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23A3B598' stroke-width='0.33' stroke-linecap='round'%3E%3Ccircle cx='12' cy='12' r='10'/%3E%3Cline x1='14.31' y1='8' x2='20.05' y2='17.94'/%3E%3Cline x1='9.69' y1='8' x2='21.17' y2='8'/%3E%3Cline x1='7.38' y1='12' x2='13.12' y2='2.06'/%3E%3Cline x1='9.69' y1='16' x2='3.95' y2='6.06'/%3E%3Cline x1='14.31' y1='16' x2='2.83' y2='16'/%3E%3Cline x1='16.62' y1='12' x2='10.88' y2='21.94'/%3E%3C/svg%3E") center / 72px no-repeat;
  }

  /* ---------- Iris shutter (page transitions) ---------- */
  .shutter {
    --iris: 150vmax;
    position: fixed;
    inset: 0;
    z-index: 300;
    display: grid;
    place-items: center;
    visibility: hidden;
    pointer-events: none;
    background: var(--studio-black);
    -webkit-mask: radial-gradient(circle at 50% 50%, transparent var(--iris), #000 calc(var(--iris) + 1px));
    mask: radial-gradient(circle at 50% 50%, transparent var(--iris), #000 calc(var(--iris) + 1px));
    transition: --iris 0.42s cubic-bezier(0.7, 0, 0.3, 1);
  }
  .shutter.is-active { visibility: visible; pointer-events: auto; }
  .shutter.is-closed { --iris: 0px; }
  .shutter.is-opening { transition: --iris 0.8s cubic-bezier(0.2, 0.7, 0.1, 1); }
  .shutter.no-anim,
  .shutter.no-anim .shutter-mark { transition: none; }

  .shutter-mark {
    width: 72px;
    height: 72px;
    fill: none;
    stroke: var(--sage);
    stroke-width: 0.33;
    stroke-linecap: round;
    opacity: 0;
    rotate: -60deg;
    scale: 0.8;
    transition: opacity 0.3s ease, rotate 0.6s var(--ease-out), scale 0.6s var(--ease-out);
  }
  .shutter.is-closed .shutter-mark { opacity: 1; rotate: 0deg; scale: 1; }
  .shutter.is-opening .shutter-mark { rotate: 50deg; scale: 1.4; }

  /* ---------- Header: hairline once you scroll, and a sage playhead
     that tracks how far down the page you are ---------- */
  html.motion .site-header { transition: box-shadow 0.3s ease; }
  html.motion .site-header.is-scrolled { box-shadow: 0 1px 0 var(--hairline-soft); }
  html.motion .site-header::after {
    content: "";
    position: absolute;
    left: 0;
    right: 0;
    bottom: -1px;
    height: 1px;
    background: var(--sage);
    opacity: 0.75;
    transform-origin: left center;
    transform: scaleX(var(--scroll-p, 0));
  }

  /* Mobile menu drops in, links follow */
  html.motion .mobile-menu[open] ul { animation: fl-menu 0.35s var(--ease-out) both; }
  html.motion .mobile-menu[open] li { animation: fl-rise 0.5s var(--ease-out) both; --rise: 8px; }
  html.motion .mobile-menu[open] li:nth-child(2) { animation-delay: 0.04s; }
  html.motion .mobile-menu[open] li:nth-child(3) { animation-delay: 0.08s; }
  html.motion .mobile-menu[open] li:nth-child(4) { animation-delay: 0.12s; }
  html.motion .mobile-menu[open] li:nth-child(5) { animation-delay: 0.16s; }

  /* ---------- Page load: the first screen focuses in ---------- */
  html.motion :is(.hero-copy, .page-hero-copy, .book-intro, .notfound .wrap) > *,
  html.motion .legal-inner > :nth-child(-n+4) {
    animation: fl-rise 1s var(--ease-out) both;
    animation-delay: calc(var(--load-base, 0s) + 0.15s + var(--li, 0) * 0.08s);
  }
  html.motion :is(.hero-copy, .page-hero-copy, .book-intro, .notfound .wrap, .legal-inner) > h1 ~ * {
    animation-delay: calc(var(--load-base, 0s) + 0.45s + var(--li, 0) * 0.08s);
  }
  html.motion :is(.hero-copy, .page-hero-copy, .book-intro, .notfound .wrap, .legal-inner) > .eyebrow {
    animation-name: fl-wipe;
    animation-duration: 0.9s;
    animation-timing-function: cubic-bezier(0.6, 0, 0.2, 1);
  }
  html.motion :is(.hero-copy, .page-hero-copy, .book-intro, .notfound .wrap, .legal-inner) > h1 { animation: none; }
  html.motion :is(.hero-copy, .page-hero-copy, .book-intro, .notfound .wrap, .legal-inner) > h1:not([data-split]) { opacity: 0; }

  :is(.hero-copy, .page-hero-copy, .book-intro, .notfound .wrap, .legal-inner) > :nth-child(2) { --li: 1; }
  :is(.hero-copy, .page-hero-copy, .book-intro, .notfound .wrap, .legal-inner) > :nth-child(3) { --li: 2; }
  :is(.hero-copy, .page-hero-copy, .book-intro, .notfound .wrap, .legal-inner) > :nth-child(4) { --li: 3; }
  :is(.hero-copy, .page-hero-copy, .book-intro, .notfound .wrap, .legal-inner) > :nth-child(5) { --li: 4; }
  :is(.hero-copy, .page-hero-copy, .book-intro, .notfound .wrap, .legal-inner) > :nth-child(6) { --li: 5; }
  :is(.hero-copy, .page-hero-copy, .book-intro, .notfound .wrap, .legal-inner) > :nth-child(7) { --li: 6; }
  :is(.hero-copy, .page-hero-copy, .book-intro, .notfound .wrap, .legal-inner) > :nth-child(8) { --li: 7; }
  :is(.hero-copy, .page-hero-copy, .book-intro, .notfound .wrap, .legal-inner) > :nth-child(n+9) { --li: 8; }

  /* Headline: each word pulls into focus in turn */
  .fl-word { display: inline-block; }
  html.motion .fl-word {
    animation: fl-word 1.1s var(--ease-out) both;
    animation-delay: calc(var(--load-base, 0s) + 0.2s + var(--wi, 0) * 0.055s);
  }

  /* Reel card rises; its play button arrives last */
  html.motion :is(.hero-media, .page-hero-media) .reel-card {
    --rise: 56px;
    animation: fl-rise 1.3s var(--ease-out) both;
    animation-delay: calc(var(--load-base, 0s) + 0.35s);
  }
  html.motion :is(.hero-media, .page-hero-media) .reel-play {
    animation: fl-pop-soft 0.8s var(--ease-out) both;
    animation-delay: calc(var(--load-base, 0s) + 1.05s);
  }
  html.motion .book-flow > .qualifier {
    --rise: 40px;
    animation: fl-rise 1.1s var(--ease-out) both;
    animation-delay: calc(var(--load-base, 0s) + 0.3s);
  }

  /* Scroll-linked hero: the aperture turns and opens as you scroll away,
     the reel card drifts up a little faster than the page */
  html.motion .hero-aperture {
    rotate: calc(var(--hero-p, 0) * 50deg);
    scale: calc(1 + var(--hero-p, 0) * 0.14);
  }
  html.motion .hero-media .reel-card { transform: translateY(calc(var(--hero-p, 0) * -40px)); }

  /* ---------- Scroll reveals ----------
     motion.js tags elements below the first screen with data-reveal and
     adds .is-in as each one reaches the viewport. They wait slightly
     soft and faint, like a lens before focus, rather than invisible. */
  html.motion [data-reveal].is-in {
    animation-duration: 0.95s;
    animation-timing-function: var(--ease-out);
    animation-delay: var(--d, 0ms);
    animation-fill-mode: both;
  }

  html.motion [data-reveal="rise"]:not(.is-in) { opacity: 0.12; translate: 0 28px; filter: blur(6px); }
  html.motion [data-reveal="rise"].is-in { animation-name: fl-rise; }

  html.motion [data-reveal="focus"]:not(.is-in) { opacity: 0.12; translate: 0 12px; filter: blur(14px); }
  html.motion [data-reveal="focus"].is-in { animation-name: fl-focus; animation-duration: 1.2s; }

  html.motion [data-reveal="wipe"]:not(.is-in) { opacity: 0; }
  html.motion [data-reveal="wipe"].is-in {
    animation-name: fl-wipe;
    animation-duration: 0.9s;
    animation-timing-function: cubic-bezier(0.6, 0, 0.2, 1);
  }

  html.motion [data-reveal="shutter"]:not(.is-in) { opacity: 0; }
  html.motion [data-reveal="shutter"].is-in {
    animation-name: fl-shutter;
    animation-duration: 1.2s;
    animation-timing-function: cubic-bezier(0.7, 0, 0.2, 1);
  }

  /* Frames inside a rising card open like a shutter */
  html.motion :is(.case, .testimonial-video)[data-reveal]:not(.is-in) :is(.case-frame, .testimonial-frame) { clip-path: inset(100% 0 0 0); }
  html.motion :is(.case, .testimonial-video).is-in :is(.case-frame, .testimonial-frame) {
    animation: fl-shutter 1.2s cubic-bezier(0.7, 0, 0.2, 1) calc(var(--d, 0ms) + 0.1s) both;
  }

  /* Rows: the hairline draws left to right, then the row's columns follow */
  html.motion [data-reveal="row"] { position: relative; border-top-color: transparent; }
  html.motion [data-reveal="row"]::before {
    content: "";
    position: absolute;
    left: 0;
    right: 0;
    top: -1px;
    height: 1px;
    background: var(--hairline);
    transform-origin: left center;
  }
  html.motion .tried-row[data-reveal="row"]::before { background: var(--hairline-soft); }
  html.motion [data-reveal="row"]:not(.is-in)::before { scale: 0 1; }
  html.motion [data-reveal="row"].is-in::before { animation: fl-draw-x 1.2s var(--ease-out) var(--d, 0ms) both; }
  html.motion [data-reveal="row"]:not(.is-in) > * { opacity: 0.12; translate: 0 18px; filter: blur(5px); }
  html.motion [data-reveal="row"].is-in > * {
    --rise: 18px;
    animation: fl-rise 0.9s var(--ease-out) both;
    animation-delay: calc(var(--d, 0ms) + 0.12s + var(--ci, 0) * 0.14s);
  }
  [data-reveal="row"] > :nth-child(2) { --ci: 1; }
  [data-reveal="row"] > :nth-child(3) { --ci: 2; }

  /* The clock and check icons draw themselves */
  html.motion .tried-row[data-reveal] .tried-label svg > * { stroke-dasharray: 60; }
  html.motion .tried-row[data-reveal]:not(.is-in) .tried-label svg > * { stroke-dashoffset: 60; }
  html.motion .tried-row.is-in .tried-cost svg > * { animation: fl-stroke 1.1s var(--ease-out) calc(var(--d, 0ms) + 0.45s) both; }
  html.motion .tried-row.is-in .tried-fix svg > * { animation: fl-stroke 0.9s var(--ease-out) calc(var(--d, 0ms) + 0.7s) both; }

  /* Process: the timeline draws, each step's dot lands, then its text */
  html.motion .steps[data-reveal] { position: relative; border-top-color: transparent; }
  html.motion .steps[data-reveal]::before {
    content: "";
    position: absolute;
    left: 0;
    right: 0;
    top: -1px;
    height: 1px;
    background: var(--hairline);
    transform-origin: left center;
  }
  html.motion .steps[data-reveal]:not(.is-in)::before { scale: 0 1; }
  html.motion .steps.is-in::before { animation: fl-draw-x 1.4s var(--ease-out) var(--d, 0ms) both; }
  html.motion .steps[data-reveal]:not(.is-in) .step::before { scale: 0; }
  html.motion .steps.is-in .step::before { animation: fl-pop 0.55s var(--ease-out) both; animation-delay: calc(var(--d, 0ms) + 0.2s + var(--si, 0) * 0.22s); }
  html.motion .steps[data-reveal]:not(.is-in) .step > * { opacity: 0.12; translate: 0 18px; filter: blur(5px); }
  html.motion .steps.is-in .step > * {
    --rise: 18px;
    animation: fl-rise 0.9s var(--ease-out) both;
    animation-delay: calc(var(--d, 0ms) + 0.3s + var(--si, 0) * 0.22s);
  }
  .step:nth-child(2) { --si: 1; }
  .step:nth-child(3) { --si: 2; }
  .step:nth-child(4) { --si: 3; }

  /* Iris divider: the ring turns in, the hairlines draw outward from it */
  html.motion [data-reveal="iris"]::before { transform-origin: right center; }
  html.motion [data-reveal="iris"]::after { transform-origin: left center; }
  html.motion [data-reveal="iris"]:not(.is-in)::before,
  html.motion [data-reveal="iris"]:not(.is-in)::after { scale: 0 1; }
  html.motion [data-reveal="iris"].is-in::before,
  html.motion [data-reveal="iris"].is-in::after { animation: fl-draw-x 1.3s var(--ease-out) calc(var(--d, 0ms) + 0.2s) both; }
  html.motion [data-reveal="iris"]:not(.is-in) svg { opacity: 0; scale: 0.3; rotate: -120deg; }
  html.motion [data-reveal="iris"].is-in svg { animation: fl-ring 0.9s var(--ease-out) var(--d, 0ms) both; }

  /* Price: a sage underline draws under it */
  html.motion .pricing-panel[data-reveal] .price {
    background: linear-gradient(var(--sage), var(--sage)) no-repeat left bottom / 0% 1px;
    padding-bottom: 2px;
  }
  html.motion .pricing-panel.is-in .price { animation: fl-underline 1s var(--ease-out) calc(var(--d, 0ms) + 0.7s) both; }

  /* Count-ups keep their width so nothing around them shifts */
  .fl-count-num { display: inline-block; text-align: left; font-variant-numeric: tabular-nums; }

  /* ---------- Hover: cards lift, a sage line runs across the top ---------- */
  html.motion :is(.card, .pair) { transition: transform 0.45s var(--ease-out), background-color 0.45s ease; }
  html.motion :is(.card, .pair)::after {
    content: "";
    position: absolute;
    left: 0;
    right: 0;
    top: 0;
    height: 1px;
    background: var(--sage);
    scale: 0 1;
    transform-origin: left center;
    transition: scale 0.6s var(--ease-out);
  }
  html.motion :is(.card, .pair):hover { transform: translateY(-4px); }
  html.motion :is(.card, .pair):hover::after { scale: 1 1; }

  /* Buttons: a soft sheen crosses on hover, a slight press on click */
  html.motion .btn-primary { position: relative; overflow: hidden; isolation: isolate; }
  html.motion .btn-primary::after {
    content: "";
    position: absolute;
    inset: 0;
    z-index: -1;
    background: linear-gradient(110deg, transparent 30%, rgba(255, 255, 255, 0.3) 50%, transparent 70%);
    translate: -110% 0;
  }
  html.motion .btn-primary:hover::after { translate: 110% 0; transition: translate 0.8s var(--ease-out); }
  html.motion .btn:active { scale: 0.98; }

  /* Reel play button: a sage ring ripples out on hover (once a video is in) */
  html.motion .reel-play::after {
    content: "";
    position: absolute;
    inset: -1px;
    border: 1px solid var(--sage);
    border-radius: 50%;
    opacity: 0;
    pointer-events: none;
  }
  html.motion .reel-play:not(:disabled):hover::after { animation: fl-ping 1.1s var(--ease-out); }

  /* ---------- Booking form: steps slide in the direction you're going ---------- */
  html.motion .q-step.is-active { animation: fl-step-in 0.5s var(--ease-out) both; }
  html.motion .qualifier[data-dir="back"] .q-step.is-active { animation-name: fl-step-back; }
  html.motion .q-bar span { position: relative; overflow: hidden; }
  html.motion .q-bar span.is-done { background: var(--hairline); }
  html.motion .q-bar span::after {
    content: "";
    position: absolute;
    inset: 0;
    background: var(--sage);
    transform-origin: left center;
    scale: 0 1;
    transition: scale 0.5s var(--ease-out);
  }
  html.motion .q-bar span.is-done::after { scale: 1 1; }
  html.motion .q-result:not([hidden]) { animation: fl-rise 0.8s var(--ease-out) both; }
  html.motion .lead-form.is-sent .form-status { animation: fl-rise 0.7s var(--ease-out) both; }

  /* FAQ answers open smoothly where the browser supports it */
  html.motion .faq-list details::details-content {
    block-size: 0;
    overflow: clip;
    transition: block-size 0.45s var(--ease-out), content-visibility 0.45s allow-discrete;
  }
  html.motion .faq-list details[open]::details-content { block-size: auto; }

  /* ---------- Ticker ---------- */
  html.motion .ticker.is-moving .ticker-track { will-change: transform; }

  /* Phones: the process timeline runs down the left edge */
  @media (max-width: 600px) {
    html.motion .steps[data-reveal] { border-left-color: transparent; }
    html.motion .steps[data-reveal]::before {
      left: -1px;
      right: auto;
      top: 0;
      bottom: 0;
      width: 1px;
      height: auto;
      transform-origin: center top;
    }
    html.motion .steps[data-reveal]:not(.is-in)::before { scale: 1 0; }
    html.motion .steps.is-in::before { animation-name: fl-draw-y; }
  }
}

/* ---------- Keyframes ---------- */
@keyframes fl-rise {
  from { opacity: 0.12; translate: 0 var(--rise, 28px); filter: blur(6px); }
  to   { opacity: 1; translate: none; filter: none; }
}
@keyframes fl-focus {
  from { opacity: 0.12; translate: 0 12px; filter: blur(14px); }
  to   { opacity: 1; translate: none; filter: none; }
}
@keyframes fl-word {
  from { opacity: 0; translate: 0 0.25em; filter: blur(12px); }
  to   { opacity: 1; translate: none; filter: none; }
}
@keyframes fl-wipe {
  from { opacity: 1; clip-path: inset(0 100% 0 0); }
  to   { opacity: 1; clip-path: inset(0 0 0 0); }
}
@keyframes fl-shutter {
  from { opacity: 1; clip-path: inset(100% 0 0 0); }
  to   { opacity: 1; clip-path: inset(0 0 0 0); }
}
@keyframes fl-draw-x {
  from { scale: 0 1; }
  to   { scale: 1 1; }
}
@keyframes fl-draw-y {
  from { scale: 1 0; }
  to   { scale: 1 1; }
}
@keyframes fl-pop {
  0%   { scale: 0; }
  60%  { scale: 1.4; }
  100% { scale: 1; }
}
@keyframes fl-pop-soft {
  from { opacity: 0; scale: 0.6; }
  to   { opacity: 1; scale: 1; }
}
@keyframes fl-ring {
  from { opacity: 0; scale: 0.3; rotate: -120deg; }
  to   { opacity: 1; scale: 1; rotate: 0deg; }
}
@keyframes fl-stroke {
  from { stroke-dashoffset: 60; }
  to   { stroke-dashoffset: 0; }
}
@keyframes fl-underline {
  from { background-size: 0% 1px; }
  to   { background-size: 100% 1px; }
}
@keyframes fl-ping {
  from { opacity: 0.9; scale: 1; }
  to   { opacity: 0; scale: 1.5; }
}
@keyframes fl-menu {
  from { opacity: 0; translate: 0 -8px; }
  to   { opacity: 1; translate: none; }
}
@keyframes fl-step-in {
  from { opacity: 0; translate: 32px 0; }
  to   { opacity: 1; translate: none; }
}
@keyframes fl-step-back {
  from { opacity: 0; translate: -32px 0; }
  to   { opacity: 1; translate: none; }
}
