/* Critical Point Vision Site: motion.css
 * Owned by motion-builder, paired with js/motion.js. Deliberately small:
 * the final-state safety net for data-motion="none" and for
 * prefers-reduced-motion before prefs.js has run, plus the handful of
 * structural rules the hero char reveal and the video play-fallback
 * button depend on. Initial "hidden, about to animate" states are set by
 * motion.js with gsap.set at init, never here, so a script failure
 * always leaves the page in its authored, visible state.
 */

/* Nav-height scroll offset for every section: used by CPS.scrollTo's
   scrollIntoView fallback under data-motion="none", and by any native
   #hash navigation regardless of motion level. */
[data-section] {
  scroll-margin-top: var(--nav-h);
}

/* Hero char reveal: each line clips its own characters as they rise in;
   the chars themselves are only ever created by motion.js at "some" or
   "full", never authored in HTML. */
.hero__line-wrap {
  overflow: hidden;
}

.hero__word,
.hero__char {
  display: inline-block;
}

/* Play-fallback button motion.js appends inside the video's parent when
   an autoplay attempt is rejected (muted autoplay blocked, or no usable
   source). 44px touch target, centered over the video. */
.play-fallback {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: 2.75rem;
  height: 2.75rem;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  border: none;
  border-radius: var(--radius-full);
  background: color-mix(in srgb, var(--foreground) 55%, transparent);
  color: var(--neutral-100, #fff);
  cursor: pointer;
}

.play-fallback:hover {
  background: color-mix(in srgb, var(--foreground) 70%, transparent);
}

.play-fallback svg {
  width: 1.25rem;
  height: 1.25rem;
}

/* Layers that scrub get a will-change hint; nothing else does. */
[data-anim="parallax"],
.hero__copy-inner {
  will-change: transform;
}

/* Final-state safety net: data-motion="none" (explicit, or the reduced-
   motion default from prefs.js) forces every animated element visible
   and untransformed, whether or not motion.js ever ran. */
html[data-motion="none"] [data-anim] {
  opacity: 1 !important;
  transform: none !important;
}

/* The connector-line paths in the builder section carry a baked
   stroke-dashoffset:1 in the static markup (so the "full" scrub has
   something to draw from). At "some" and "none" nothing ever animates
   that offset back to 0, so force it here instead. */
html[data-motion="none"] [data-anim="builder-link"],
html[data-motion="some"] [data-anim="builder-link"] {
  stroke-dashoffset: 0 !important;
}

/* Belt and braces: honour prefers-reduced-motion even on the frame before
   prefs.js has written data-motion, and even if prefs.js never runs. */
@media (prefers-reduced-motion: reduce) {
  html:not([data-motion]) [data-anim] {
    opacity: 1 !important;
    transform: none !important;
  }

  html:not([data-motion]) [data-anim="builder-link"] {
    stroke-dashoffset: 0 !important;
  }
}
