/* ==========================================================================
   FUSION CNC — MOTION SYSTEM

   The brand guide asks for "gentle fade, lift and reveal" and forbids heavy
   or playful motion. Everything here is opacity, transform and clip-path
   only. No bounce, no spring, no rotation, no bezier overshoot.

   SAFETY MODEL: elements are visible by default (see base.css). The hidden
   start state applies ONLY under .js-reveal-ready, which site.js adds after
   confirming IntersectionObserver exists and reduced-motion is off. A script
   error therefore leaves the page readable rather than blank.
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. SCROLL REVEALS
   -------------------------------------------------------------------------- */
.js-reveal-ready [data-reveal]{
  opacity: 0;
  transform: translateY(22px);
  transition: opacity var(--dur-4) var(--ease),
              transform var(--dur-4) var(--ease);
  will-change: opacity, transform;
}
.js-reveal-ready [data-reveal="fade"] { transform: none; }
.js-reveal-ready [data-reveal="left"] { transform: translateX(-26px); }
.js-reveal-ready [data-reveal="right"]{ transform: translateX(26px); }
.js-reveal-ready [data-reveal="scale"]{ transform: scale(0.97); }

/* Image wipe — the frame opens left-to-right while the picture inside
   settles back from a slight over-scale. Reads as a photograph being
   revealed rather than a box fading in. */
.js-reveal-ready [data-reveal="clip"]{
  opacity: 1;
  transform: none;
  clip-path: inset(0 100% 0 0);
  transition: clip-path 1.1s var(--ease);
}
.js-reveal-ready [data-reveal="clip"] img{
  transform: scale(1.14);
  transition: transform 1.4s var(--ease);
}
.js-reveal-ready [data-reveal="clip"][data-revealed]{ clip-path: inset(0 0 0 0); }
.js-reveal-ready [data-reveal="clip"][data-revealed] img{ transform: scale(1); }

.js-reveal-ready [data-reveal][data-revealed]{
  opacity: 1;
  transform: none;
  will-change: auto;
}

/* --------------------------------------------------------------------------
   2. STAGGERED GROUPS
   Children of [data-reveal-group] cascade instead of arriving together.
   site.js sets --i on each child; the group's own delay-step is tunable
   via data-stagger (default 90ms).
   -------------------------------------------------------------------------- */
.js-reveal-ready [data-reveal-group] > *{
  opacity: 0;
  transform: translateY(26px);
  transition: opacity var(--dur-4) var(--ease),
              transform var(--dur-4) var(--ease);
  transition-delay: calc(var(--i, 0) * var(--stagger, 90ms));
}
.js-reveal-ready [data-reveal-group][data-revealed] > *{
  opacity: 1;
  transform: none;
}

/* --------------------------------------------------------------------------
   3. MASKED LINE REVEAL — section headings
   site.js splits each heading on its <br> into .line > .line__in. The outer
   span clips; the inner one rises from beneath it. This is the single most
   "premium" motion on the page, so it is reserved for h2s only — using it
   everywhere would cheapen it.
   -------------------------------------------------------------------------- */
.split-line{
  display: block;
  overflow: hidden;
  padding-bottom: 0.06em;   /* room for descenders inside the clip */
  margin-bottom: -0.06em;
}
.split-line__in{
  display: block;
  transform: translateY(105%);
  transition: transform 1s var(--ease);
  transition-delay: calc(var(--line, 0) * 110ms);
}
[data-revealed] .split-line__in,
.split-heading[data-revealed] .split-line__in{ transform: translateY(0); }

/* Without JS or with reduced motion the heading is simply upright. */
@media (prefers-reduced-motion: reduce){
  .split-line__in{ transform: none !important; transition: none; }
}

/* --------------------------------------------------------------------------
   4. SCROLL PROGRESS
   A 2px orange rule across the very top of the viewport. Gives the long
   home page a sense of position without adding furniture.
   -------------------------------------------------------------------------- */
.scroll-progress{
  position: fixed;
  top: 0; left: 0;
  height: 2px;
  width: 100%;
  transform: scaleX(0);
  transform-origin: left center;
  background: var(--brand);
  z-index: calc(var(--z-header) + 1);
  pointer-events: none;
}

/* Hero slideshow sizing/crossfade now lives entirely in css/home.css, next
   to the rest of the hero rules — kept in one place since the image-only
   redesign made the old absolute-positioned, parallax-oversized version
   here obsolete (it was fighting the current rules for position/z-index). */

/* --------------------------------------------------------------------------
   6. PARALLAX
   Applied by site.js via translate3d on a --py custom property. Kept to
   small amplitudes: this should register as depth, not as movement.
   -------------------------------------------------------------------------- */
[data-parallax]{ will-change: transform; }
@media (prefers-reduced-motion: reduce){
  [data-parallax]{ transform: none !important; }
}

/* --------------------------------------------------------------------------
   7. STAT VALUE — masked digit rise
   Same clip-and-rise language as the headings, so the capability strip reads
   as part of one motion system rather than a separate effect.
   -------------------------------------------------------------------------- */
.stat__value{ overflow: hidden; }
.js-reveal-ready .stat__value > span{
  display: block;
  transform: translateY(100%);
  transition: transform 0.9s var(--ease);
}
.js-reveal-ready .stat[data-revealed] .stat__value > span{ transform: translateY(0); }
@media (prefers-reduced-motion: reduce){
  .js-reveal-ready .stat__value > span{ transform: none; }
}

/* The hero entrance stagger and the scroll cue live in home.css, next to the
   elements they animate. */
