/* =============================================================
   STERE MOTION SYSTEM — v1
   Single source of truth for scroll reveals and micro-interactions.

   Pairs with /motion.js, which annotates the client-rendered DOM
   with the data-attributes below. Nothing here changes layout,
   typography, spacing, colour or content — motion only.

   Contract
   --------
   [data-reveal="<variant>"]   armed, waiting to enter the viewport
   [data-revealed]             playing its reveal
   --reveal-delay              per-element stagger offset
   [data-motion~="<token>"]    opt-in micro-interaction

   Both reveal attributes are stripped by motion.js once the transition
   finishes, so played content is plain markup again — it cannot be
   re-hidden, and it holds no compositor layer.

   No-JS safety: every hiding rule requires html.motion, which only
   /motion.js sets. If the script never runs, the page renders as-is.
   ============================================================= */

:root {
  /* Signature easing — the "premium decelerate" used site-wide. */
  --motion-ease: cubic-bezier(0.22, 1, 0.36, 1);
  --motion-ease-inout: cubic-bezier(0.65, 0, 0.35, 1);

  --motion-dur-reveal: 800ms;
  --motion-dur-word: 680ms;
  --motion-dur-hover: 300ms;
  --motion-dur-press: 120ms;

  /* Reveal displacements */
  --motion-shift-y: 40px;
  --motion-shift-x: 50px;
  --motion-blur: 6px;

  /* Hover lift */
  --motion-lift: -8px;
  --motion-lift-scale: 1.02;
  --motion-lift-sm: -2px;
}

/* =============================================================
   1. SECTION / CARD / IMAGE REVEALS
   ============================================================= */

html.motion [data-reveal] {
  opacity: 1;
  transition-property: opacity, transform, filter;
  transition-duration: var(--motion-dur-reveal);
  transition-timing-function: var(--motion-ease);
  transition-delay: var(--reveal-delay, 0ms);
}

/* Promote only what is about to move: motion.js marks an element "near"
   the first time it touches the viewport, well before it plays. A long
   page therefore holds a handful of layers rather than one per armed
   element, and data-reveal is stripped on settle so each layer is
   released the instant its reveal ends. */
html.motion [data-reveal][data-motion-near],
html.motion [data-reveal][data-motion-onload],
html.motion [data-reveal][data-revealed] {
  will-change: opacity, transform;
}

html.motion [data-reveal="fade"] {
  transform: none;
}

html.motion [data-reveal="fade-up"] {
  transform: translate3d(0, var(--motion-shift-y), 0);
}

html.motion [data-reveal="rise"] {
  transform: translate3d(0, 18px, 0);
}

html.motion [data-reveal="fade-left"] {
  transform: translate3d(calc(-1 * var(--motion-shift-x)), 0, 0);
  filter: blur(var(--motion-blur));
}

html.motion [data-reveal="fade-right"] {
  transform: translate3d(var(--motion-shift-x), 0, 0);
  filter: blur(var(--motion-blur));
}

html.motion [data-reveal="zoom"] {
  transform: scale3d(0.96, 0.96, 1);
  filter: blur(4px);
}

html.motion [data-reveal="fade-down"] {
  transform: translate3d(0, -14px, 0);
}

html.motion [data-reveal][data-revealed] {
  opacity: 1;
  transform: none;
  filter: none;
}

/* Cards slide in horizontally; keep that off the page's scroll width. */
html.motion main {
  overflow-x: clip;
}

/* =============================================================
   2. HEADINGS — word-level reveal (never per letter)
   ============================================================= */

html.motion [data-reveal="words"] {
  opacity: 1;
}

html.motion [data-motion-word] {
  display: inline-block;
  opacity: 0;
  transform: translate3d(0, 0.42em, 0);
  transition: opacity var(--motion-dur-word) var(--motion-ease),
    transform var(--motion-dur-word) var(--motion-ease);
  transition-delay: var(--reveal-delay, 0ms);
}

html.motion [data-revealed] [data-motion-word] {
  opacity: 1;
  transform: none;
}

/* =============================================================
   3. NAVIGATION
   ============================================================= */

/* Depth on scroll. Glass/tint stays owned by each page's own header
   logic (inline styles) — we only add what it does not set. */
html.motion header[data-motion-nav] {
  transition: background var(--dur-base) var(--ease-out),
    border-color var(--dur-base) var(--ease-out),
    backdrop-filter var(--dur-base) var(--ease-out),
    box-shadow var(--motion-dur-hover) var(--motion-ease);
}

html.motion header[data-motion-nav][data-motion-scrolled] {
  box-shadow: 0 6px 24px -12px rgba(6, 32, 59, 0.28);
}

/* Compact-on-scroll. The single deliberate height animation in the
   system: it is one sticky element, transform cannot substitute for it
   without distorting text, and it is opt-out by setting --motion-nav-h
   equal to --motion-nav-h-scrolled.

   The !important pair is required because the bar carries its height
   as an inline style from the template. */
html.motion header[data-motion-nav]>div {
  height: var(--motion-nav-h, 66px) !important;
  transition: height var(--motion-dur-hover) var(--motion-ease);
}

html.motion header[data-motion-nav][data-motion-scrolled]>div {
  height: var(--motion-nav-h-scrolled, 58px) !important;
}

/* Animated underline on the current menu item. */
html.motion header nav>a,
html.motion header nav>div>a {
  position: relative;
}

html.motion header nav a[data-motion-current]::after {
  content: "";
  position: absolute;
  left: 14px;
  right: 14px;
  bottom: 4px;
  height: 2px;
  border-radius: 2px;
  background: currentColor;
  opacity: 0.9;
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform 620ms var(--motion-ease) 260ms;
}

html.motion header nav a[data-motion-current][data-motion-underline]::after {
  transform: scaleX(1);
}

/* =============================================================
   4. LINKS — animated underline (footer + inline prose)
   ============================================================= */

html.motion footer a {
  position: relative;
}

html.motion footer li>a::after,
html.motion a[data-motion~="underline"]::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: -3px;
  height: 1px;
  background: currentColor;
  transform: scaleX(0);
  transform-origin: right center;
  transition: transform var(--motion-dur-hover) var(--motion-ease);
}

html.motion footer li>a:hover::after,
html.motion footer li>a:focus-visible::after,
html.motion a[data-motion~="underline"]:hover::after,
html.motion a[data-motion~="underline"]:focus-visible::after {
  transform: scaleX(1);
  transform-origin: left center;
}

/* =============================================================
   4b. PRESS STATES
   Owned here rather than as a style-active attribute on purpose. The
   runtime compiles style-* into shared `.scpN:pseudo { … !important }`
   rules whose cascade order follows first use across the whole
   document, so an :active rule registered by an early element can land
   *before* a later element's :hover and lose. A rule with more
   specificity than `.scpN:active` wins regardless of that ordering.
   ============================================================= */

html.motion [data-motion~="press"]:active,
html.motion [data-motion~="press-card"]:active {
  transition-duration: var(--motion-dur-press) !important;
}

html.motion [data-motion~="press"]:active {
  transform: translateY(0) scale(0.98) !important;
}

/* Cards press back toward the page without losing their lift entirely. */
html.motion [data-motion~="press-card"]:active {
  transform: translateY(-2px) scale(1) !important;
}

/* =============================================================
   5. IMAGES — hover zoom inside their existing clipping frame
   ============================================================= */

html.motion main img {
  transition: transform 620ms var(--motion-ease);
}

html.motion main img:hover,
html.motion main article:hover img {
  transform: scale(1.03);
}

/* =============================================================
   6. ICONS — subtle scale inside interactive elements
   ============================================================= */

html.motion main a>svg,
html.motion main button>svg {
  transition: transform var(--motion-dur-hover) var(--motion-ease);
}

html.motion main a:hover>svg,
html.motion main button:hover>svg {
  transform: scale(1.09);
}

/* =============================================================
   7. INPUTS — animated border/ring
   ============================================================= */

html.motion input,
html.motion textarea,
html.motion select {
  transition: border-color var(--motion-dur-hover) var(--motion-ease),
    box-shadow var(--motion-dur-hover) var(--motion-ease),
    background-color var(--motion-dur-hover) var(--motion-ease);
}

/* =============================================================
   8. FLOATING — hero illustrations
   ============================================================= */

@keyframes motion-float {

  0%,
  100% {
    transform: translate3d(0, 0, 0);
  }

  50% {
    transform: translate3d(0, -8px, 0);
  }
}

/* Starts only once any reveal on this element has finished (data-reveal
   is removed on settle), so the loop never overrides a running transition. */
html.motion [data-motion~="float"]:not([data-reveal]) {
  animation: motion-float 6s var(--motion-ease-inout) infinite;
  will-change: transform;
}

/* =============================================================
   9. ACCORDION PRIMITIVE
   Height-free disclosure: the row track collapses from 0fr to 1fr,
   so no width/height/margin is animated. Ready for future FAQ UI.
   ============================================================= */

html.motion [data-motion-accordion-panel] {
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows 420ms var(--motion-ease);
}

html.motion [data-motion-accordion-panel]>* {
  overflow: hidden;
  opacity: 0;
  transition: opacity 280ms var(--motion-ease);
}

html.motion [data-motion-accordion-panel][data-open] {
  grid-template-rows: 1fr;
}

html.motion [data-motion-accordion-panel][data-open]>* {
  opacity: 1;
  transition-delay: 120ms;
}

html.motion [data-motion-chevron] {
  transition: transform var(--motion-dur-hover) var(--motion-ease);
}

html.motion [data-motion-chevron][data-open] {
  transform: rotate(180deg);
}

/* =============================================================
   10. ACCESSIBILITY — prefers-reduced-motion
   Everything stays visible and reachable; only movement is removed.
   ============================================================= */

@media (prefers-reduced-motion: reduce) {

  html.motion [data-reveal],
  html.motion [data-motion-word] {
    opacity: 1 !important;
    transform: none !important;
    filter: none !important;
    transition: none !important;
    will-change: auto !important;
  }

  html.motion [data-motion~="float"] {
    animation: none !important;
  }

  html.motion header[data-motion-nav]>div,
  html.motion header[data-motion-nav][data-motion-scrolled]>div {
    height: var(--motion-nav-h, 66px);
    transition: none;
  }

  html.motion main img:hover,
  html.motion main article:hover img,
  html.motion main a:hover>svg,
  html.motion main button:hover>svg {
    transform: none;
  }

  html.motion [data-motion-accordion-panel] {
    transition: none;
  }
}