/* TAK Studio — shared motion layer.
   Canonical copy lives in the root hub theme (rebuilto-child); the arch and
   tech themes carry byte-identical copies. Edit here, then re-copy.

   Everything is gated on html.motion, which motion.js sets only when JS runs
   and prefers-reduced-motion is NOT requested. Without the gate this file is
   inert and every element is fully visible. Only opacity, transform, rotate
   and clip-path are animated — never layout properties.

   Fallback values keep the layer working on installs without tokens.css. */

:root {
  --mo-ease: var(--ease-enter, cubic-bezier(0.22, 1, 0.36, 1));
  --mo-dur: 600ms;
  --mo-rise: 18px;
  --mo-stagger: 70ms;
}

/* ---------------------------------------------------------------- *
 *  Scroll reveals — data-reveal / data-reveal-group (see motion.js)
 * ---------------------------------------------------------------- */

html.motion [data-reveal] {
  opacity: 0;
  transition:
    opacity var(--mo-dur) var(--mo-ease),
    transform var(--mo-dur) var(--mo-ease);
  transition-delay: calc(var(--i, 0) * var(--mo-stagger));
}

html.motion [data-reveal=""],
html.motion [data-reveal="rise"] { transform: translateY(var(--mo-rise)); }

html.motion [data-reveal="settle"] { transform: scale(1.04); }

html.motion [data-reveal="clip"] {
  clip-path: inset(0 0 12% 0);
  transition:
    opacity var(--mo-dur) var(--mo-ease),
    clip-path var(--mo-dur) var(--mo-ease);
  transition-delay: calc(var(--i, 0) * var(--mo-stagger));
}

html.motion [data-reveal].is-in {
  opacity: 1;
  transform: none;
}
html.motion [data-reveal="clip"].is-in { clip-path: inset(0); }

/* The "+" brand motif turns into place just after its parent lands.
   The standalone `rotate` property leaves the existing baseline
   transform on .plus untouched; older browsers simply skip the turn. */
html.motion [data-reveal] .plus {
  opacity: 0;
  rotate: -90deg;
  transition:
    opacity 500ms var(--ease-enter, cubic-bezier(0.22, 1, 0.36, 1)),
    rotate 500ms var(--ease-enter, cubic-bezier(0.22, 1, 0.36, 1));
  transition-delay: calc(var(--i, 0) * var(--mo-stagger) + 120ms);
}
html.motion [data-reveal].is-in .plus {
  opacity: 1;
  rotate: 0deg;
}

/* ---------------------------------------------------------------- *
 *  First-load hero choreography (front pages with a .hero section).
 *  Keyframes declare only `from`: the resting state is the element's
 *  own, so nothing lingers once the entrance completes.
 * ---------------------------------------------------------------- */

@keyframes mo-rise {
  from { opacity: 0; transform: translateY(var(--mo-rise-d, 14px)); }
}
@keyframes mo-fade {
  from { opacity: 0; }
}
@keyframes mo-drop {
  from { opacity: 0; transform: translateY(-10px); }
}
@keyframes mo-settle {
  from { transform: scale(1.05); }
}

html.motion .site-header {
  animation: mo-drop 400ms var(--ease-out, cubic-bezier(0.25, 1, 0.5, 1)) 100ms both;
}

html.motion .hero .hero__eyebrow {
  --mo-rise-d: 14px;
  animation: mo-rise 560ms var(--mo-ease) 120ms both;
}
html.motion .hero h1 {
  --mo-rise-d: 18px;
  animation: mo-rise 620ms var(--mo-ease) 220ms both;
}
html.motion .hero .hero__lead {
  --mo-rise-d: 14px;
  animation: mo-rise 560ms var(--mo-ease) 320ms both;
}
html.motion .hero .hero__actions {
  --mo-rise-d: 12px;
  animation: mo-rise 520ms var(--mo-ease) 420ms both;
}
html.motion .hero .hero__cap {
  animation: mo-fade 500ms var(--ease-standard, cubic-bezier(0.25, 0.46, 0.45, 0.94)) 700ms both;
}

/* The active slide's image settles from a gentle zoom; it re-runs on
   each crossfade, pairing with the existing 1.2s opacity transition. */
html.motion .hero .hero__slide[data-active="true"] img {
  animation: mo-settle 1200ms var(--ease-out, cubic-bezier(0.25, 1, 0.5, 1)) both;
}

/* ---------------------------------------------------------------- *
 *  Micro-interactions
 * ---------------------------------------------------------------- */

html.motion .btn:active { transform: scale(0.98); }

/* ---------------------------------------------------------------- *
 *  Reduced motion: belt-and-suspenders. motion.js never sets the
 *  gate under prefers-reduced-motion, but if the preference changes
 *  mid-session this neutralises everything above instantly.
 * ---------------------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
  html.motion [data-reveal],
  html.motion [data-reveal] .plus,
  html.motion .site-header,
  html.motion .hero .hero__eyebrow,
  html.motion .hero h1,
  html.motion .hero .hero__lead,
  html.motion .hero .hero__actions,
  html.motion .hero .hero__cap,
  html.motion .hero .hero__slide[data-active="true"] img {
    animation: none !important;
    transition: none !important;
    opacity: 1 !important;
    transform: none !important;
    rotate: none !important;
    clip-path: none !important;
  }
}
