/**
 * BEASTMODE DEVELOPMENT — motion.css
 * ----------------------------------------------------------------------------
 * Performance hygiene, view-transition wiring, reveal/odometer masking
 * primitives, the custom cursor, the page-transition curtain, and the full
 * prefers-reduced-motion fallback.
 *
 * Every color below reads from the locked --bmd-* tokens (owned by the type
 * lane's tokens.css) with a literal fallback so this file never breaks if it
 * happens to load before tokens.css, and never invents a new color of its
 * own — the fallbacks are just the same locked hex values, not new ones.
 *
 * Signature easing: cubic-bezier(0.16, 0, 0.3, 1) → written out as
 * cubic-bezier(0.16, 1, 0.3, 1) everywhere below (CSS needs no polyfill for
 * this — only GSAP's core, lacking the premium CustomEase plugin, needed the
 * hand-rolled solver in motion.js).
 */

:root {
  --bmd-ease: cubic-bezier(0.16, 1, 0.3, 1);
  --bmd-dur-s: 0.8s;
  --bmd-dur-m: 1.1s;
  --bmd-dur-l: 1.4s;
}

/* ---------------------------------------------------------------------------
 * 1. Performance hygiene — will-change / contain / transform-style
 *
 * `contain` is applied only to elements that are THEMSELVES the thing being
 * pinned/animated, never to an ancestor of a pinned element: `contain:
 * layout` (like `transform` or `filter`) makes an element a containing
 * block for fixed-position descendants, which would silently break
 * ScrollTrigger's `position:fixed` pin if it landed on a pin's ancestor.
 * Scoped to the pinned element itself, it only isolates that element's own
 * children — safe, and it keeps pin/scrub layout recalculation from
 * rippling out to the rest of the page.
 * ------------------------------------------------------------------------- */

[data-pin],
[data-stepper],
[data-marquee],
[data-drag] {
  contain: layout style;
}

[data-parallax],
[data-scrub],
.bmd-unit,
[data-marquee] > *,
[data-drag] > *,
.bmd-progress-hair,
.bmd-cursor__ring {
  transform: translateZ(0); /* own compositor layer up front, no first-move jank */
  backface-visibility: hidden;
}

[data-pin] {
  transform-style: flat;
}

/* ---------------------------------------------------------------------------
 * 2. Cross-document View Transitions
 * ------------------------------------------------------------------------- */

@view-transition {
  navigation: auto;
}

/* Persistent shared element — identical on every page, so a plain static
   name is enough (no per-navigation JS needed). See docs on the lead's
   header markup: add data-vt="logo" to the logo link/mark. */
[data-vt="logo"] {
  view-transition-name: bmd-logo;
}

::view-transition-group(*) {
  animation-duration: var(--bmd-dur-m);
  animation-timing-function: var(--bmd-ease);
}
::view-transition-old(root),
::view-transition-new(root) {
  animation-duration: var(--bmd-dur-s);
  animation-timing-function: var(--bmd-ease);
}
::view-transition-group(bmd-logo) {
  animation-duration: var(--bmd-dur-l);
}
/* Any dynamically-named "hero" continuity (transitions.js assigns
   bmd-<data-vt-share> to the one activated element right before nav). */
::view-transition-group(bmd-hero) {
  animation-duration: var(--bmd-dur-l);
}

/* ---------------------------------------------------------------------------
 * 3. data-reveal — split-text line masks / word / char units
 * ------------------------------------------------------------------------- */

.bmd-split {
  display: inline;
}
.bmd-split--lines {
  display: block;
}

.bmd-mask {
  display: inline-block;
  overflow: hidden;
  vertical-align: top;
}
.bmd-mask--line {
  display: block;
  overflow: hidden;
}

.bmd-unit {
  display: inline-block;
  will-change: transform, opacity;
}

/* ---------------------------------------------------------------------------
 * 4. data-counter — odometer digit roll
 * ------------------------------------------------------------------------- */

.bmd-odo {
  display: inline-flex;
  align-items: baseline;
  font-variant-numeric: tabular-nums;
}
.bmd-odo-col {
  display: inline-block;
  height: 1em;
  overflow: hidden;
  position: relative;
  vertical-align: baseline;
  line-height: 1;
}
.bmd-odo-strip {
  display: block;
  will-change: transform;
}
.bmd-odo-digit {
  display: block;
  height: 1em;
  line-height: 1;
  text-align: center;
}

/* ---------------------------------------------------------------------------
 * 5. data-stepper — numbered 01/02/03 — /03 pinned sequence
 * ------------------------------------------------------------------------- */

[data-stepper] {
  position: relative;
  height: 100vh;
  overflow: hidden;
}
[data-stepper-panel] {
  position: absolute;
  inset: 0;
  opacity: 0;
  pointer-events: none;
  transition: opacity var(--bmd-dur-s) var(--bmd-ease);
  will-change: opacity;
}
[data-stepper-panel].is-active {
  opacity: 1;
  pointer-events: auto;
}
[data-stepper-dot] {
  opacity: 0.35;
  transition: opacity 0.5s var(--bmd-ease);
}
[data-stepper-dot].is-active {
  opacity: 1;
}
[data-stepper-progress] {
  transform-origin: left center;
  transform: scaleX(0);
}
/* Below the ~900px breakpoint each panel's image + title + body stack in one
   column (see .split in layout.css) and no longer fit inside a 100vh pinned
   box -- a phone would either clip the top of the heading under the fixed
   nav or crop the figure. motion.js detects that width and adds this same
   "is-reduced-static" class it uses for prefers-reduced-motion, so narrow
   viewports get the identical honest fallback: every panel laid out in
   normal flow, fully visible, nothing pinned or cropped. */
[data-stepper].is-reduced-static {
  height: auto;
  overflow: visible;
}
[data-stepper-panel].is-reduced-static {
  position: static;
  opacity: 1;
  pointer-events: auto;
  transition: none;
}
[data-stepper].is-reduced-static [data-stepper-progress] {
  transform: scaleX(1);
}
[data-stepper-panel].is-reduced-static + [data-stepper-panel].is-reduced-static {
  margin-top: var(--space-8, 4rem);
  padding-top: var(--space-8, 4rem);
  border-top: 1px solid var(--bmd-hairline, rgba(255, 255, 255, 0.09));
}
/* the persistent 01/06 numeral + hairline read as chrome for a single
   pinned moment; once every panel is stacked and permanently visible they
   would just repeat the same "06 / 06" six times, so hide that instance
   and let each panel's own in-markup index (baked into its heading area)
   carry the numbering instead. */
[data-stepper].is-reduced-static > .stepper__head,
[data-stepper].is-reduced-static > .stepper__bar,
[data-stepper].is-reduced-static > .stepper__dots {
  display: none;
}

/* ---------------------------------------------------------------------------
 * 6. Global scroll-progress hairline
 * ------------------------------------------------------------------------- */

.bmd-progress-hair {
  position: fixed;
  top: 0;
  right: 0;
  width: 2px;
  height: 100%;
  transform-origin: top center;
  transform: scaleY(0);
  background: linear-gradient(var(--bmd-red, #ED1C24), var(--bmd-red-deep, #B4141A));
  box-shadow: 0 0 8px var(--bmd-red-glow, rgba(237, 28, 36, 0.35));
  z-index: 9998;
  pointer-events: none;
}

/* ---------------------------------------------------------------------------
 * 7. data-marquee / data-drag interaction state
 * ------------------------------------------------------------------------- */

[data-marquee] {
  cursor: grab;
}
[data-marquee].is-dragging,
[data-drag].is-dragging {
  cursor: grabbing;
}
[data-drag] {
  cursor: grab;
}

/* ---------------------------------------------------------------------------
 * 8. Custom cursor (see cursor.js)
 * ------------------------------------------------------------------------- */

.bmd-cursor {
  position: fixed;
  top: 0;
  left: 0;
  width: 0;
  height: 0;
  pointer-events: none;
  z-index: 10000;
  transform: translate3d(-100px, -100px, 0);
}
.bmd-cursor__ring {
  position: absolute;
  top: -16px;
  left: -16px;
  width: 32px;
  height: 32px;
  border-radius: 50%;
  border: 1.5px solid rgba(242, 244, 245, 0.55);
  display: flex;
  align-items: center;
  justify-content: center;
  opacity: 0;
  --bmd-cursor-scale: 0.8;
  transform: scale(var(--bmd-cursor-scale));
  transition:
    opacity 0.3s var(--bmd-ease),
    transform 0.5s var(--bmd-ease),
    border-color 0.3s ease,
    background-color 0.3s ease;
}
.bmd-cursor.is-visible .bmd-cursor__ring {
  opacity: 1;
  --bmd-cursor-scale: 1;
}
.bmd-cursor.is-labeled .bmd-cursor__ring {
  --bmd-cursor-scale: 2;
  border-color: var(--bmd-red, #ED1C24);
  background: rgba(237, 28, 36, 0.08);
}
.bmd-cursor.is-pressed .bmd-cursor__ring {
  --bmd-cursor-scale: 0.85;
}
.bmd-cursor__label {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 9px;
  letter-spacing: 0.08em;
  color: var(--bmd-white, #F2F4F5);
  opacity: 0;
  transition: opacity 0.25s ease;
  white-space: nowrap;
}
.bmd-cursor.is-labeled .bmd-cursor__label {
  opacity: 1;
}

/* The native pointer stays visible. The ring is a companion that trails it,
   not a replacement — a business site should never take the cursor away. */
html.has-bmd-cursor [data-drag],
html.has-bmd-cursor [data-marquee] {
  cursor: grab;
}
html.has-bmd-cursor [data-drag]:active,
html.has-bmd-cursor [data-marquee]:active {
  cursor: grabbing;
}

/* ---------------------------------------------------------------------------
 * 9. Page-transition curtain (JS fallback for browsers without cross-doc
 *    View Transitions — see transitions.js)
 * ------------------------------------------------------------------------- */

.bmd-curtain {
  position: fixed;
  inset: 0;
  background: var(--bmd-void, #08090A);
  opacity: 0;
  pointer-events: none;
  z-index: 99999;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: opacity var(--bmd-dur-m) var(--bmd-ease);
}
.bmd-curtain.is-covering {
  opacity: 1;
  pointer-events: all;
}
.bmd-curtain.no-transition {
  transition: none !important;
}
.bmd-curtain__bar {
  width: 0;
  max-width: 120px;
  height: 1px;
  background: var(--bmd-red, #ED1C24);
  transition: width 1.1s var(--bmd-ease);
}
.bmd-curtain.is-covering .bmd-curtain__bar {
  width: 120px;
}

/* ---------------------------------------------------------------------------
 * 10. prefers-reduced-motion — a genuinely good static site
 *
 * JS independently checks the same media query and skips creating pins,
 * scrubs, parallax, magnet, marquee-autoplay and split-text stagger
 * animations in the first place. This block is the belt to that suspender:
 * it holds even if JS is slow, errors, or hasn't run yet, and it is what
 * governs the very first paint before any script executes.
 * ------------------------------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
  ::view-transition-group(*),
  ::view-transition-old(*),
  ::view-transition-new(*) {
    animation: none !important;
  }

  .bmd-unit {
    transform: none !important;
    opacity: 1 !important;
  }

  [data-stepper] {
    height: auto !important;
    overflow: visible !important;
  }
  [data-stepper-panel] {
    position: static !important;
    opacity: 1 !important;
    pointer-events: auto !important;
    transition: none !important;
  }
  [data-stepper-progress] {
    transform: scaleX(1) !important;
  }
  [data-stepper-panel] + [data-stepper-panel] {
    margin-top: var(--space-8, 4rem) !important;
    padding-top: var(--space-8, 4rem) !important;
    border-top: 1px solid var(--bmd-hairline, rgba(255, 255, 255, 0.09)) !important;
  }
  [data-stepper] > .stepper__head,
  [data-stepper] > .stepper__bar,
  [data-stepper] > .stepper__dots {
    display: none !important;
  }

  [data-parallax],
  [data-scrub] {
    transform: none !important;
  }

  .bmd-odo-strip {
    transition: none !important;
  }

  [data-marquee] [data-marquee-clone] {
    display: none !important;
  }
  [data-marquee] > * {
    transform: none !important;
    overflow-x: auto !important;
  }

  .bmd-cursor,
  .bmd-curtain,
  .bmd-progress-hair {
    display: none !important;
  }

  *,
  *::before,
  *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    scroll-behavior: auto !important;
  }
}
