/* ==========================================================================
   AURELLE ATELIER — motion.css
   S312 Stage 3 (w3c). Companion stylesheet to motion.js.
   Calm = slow, one-directional, settling (design-tokens.md §5).

   Progressive-enhancement contract:
   - NOTHING in this file hides content unless BOTH are true:
     (a) html carries the `js-motion` gate class (added by motion.js
         before first paint), and
     (b) the element carries an `m-*` class that only motion.js applies.
     If JS fails or motion.js is not loaded, no selector here matches and
     every element renders fully visible. No flash of hidden content.
   - Every var() carries a literal fallback so this file is safe even on
     a page that loads without main.css.
   - `html.m-reduced` mirrors the `prefers-reduced-motion: reduce` media
     query exactly: motion.js sets it at load, on live OS-setting change,
     and under the `?reduced-motion` QA flag.
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. REVEAL LAYER — opacity/translate fades, long ease-out, JS-applied
   -------------------------------------------------------------------------- */

html.js-motion .m-reveal {
  opacity: 0;
  transform: translateY(24px);
  transition:
    opacity var(--dur-reveal, 900ms) var(--ease-out-long, cubic-bezier(0.16, 1, 0.3, 1)),
    transform var(--dur-reveal, 900ms) var(--ease-out-long, cubic-bezier(0.16, 1, 0.3, 1));
  transition-delay: var(--m-delay, 0ms); /* motion.js staggers siblings 90ms, capped 450ms */
}

html.js-motion .m-reveal.m-in {
  opacity: 1;
  transform: none;
}

/* --------------------------------------------------------------------------
   2. MEDIA LOAD FADE — images settle up from the wine blur-up ground.
   `m-media` is only applied by motion.js to images that have NOT yet
   loaded; loaded/cached images are never touched. 4s JS failsafe adds
   `m-loaded` even if load/error never fire.
   -------------------------------------------------------------------------- */

html.js-motion .media-frame > img.m-media {
  opacity: 0;
  transition: opacity 700ms var(--ease-out-long, cubic-bezier(0.16, 1, 0.3, 1));
}

html.js-motion .media-frame > img.m-media.m-loaded {
  opacity: 1;
}

/* --------------------------------------------------------------------------
   3. PARALLAX HINTS — hero media + editorial bands only (spec §5).
   main.css already hints [data-parallax] > *; this covers hosts that
   shipped without the attribute, which motion.js drives as fallback.
   -------------------------------------------------------------------------- */

html.js-motion .hero__media > *,
html.js-motion .band__media > * {
  will-change: transform;
}

/* --------------------------------------------------------------------------
   4. REDUCED MOTION — full neutralisation, two triggers, identical rules:
   the OS media query, and html.m-reduced (set by motion.js at load, on
   live change, and under the ?reduced-motion QA flag).
   -------------------------------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
  html.js-motion .m-reveal,
  html.js-motion .m-reveal.m-in {
    opacity: 1 !important;
    transform: none !important;
    transition: none !important;
  }

  html.js-motion .media-frame > img.m-media {
    opacity: 1 !important;
    transition: none !important;
  }

  html.js-motion .hero__media > *,
  html.js-motion .band__media > *,
  html.js-motion [data-parallax] > * {
    transform: none !important;
    will-change: auto;
  }
}

html.m-reduced .m-reveal,
html.m-reduced .m-reveal.m-in {
  opacity: 1 !important;
  transform: none !important;
  transition: none !important;
}

html.m-reduced .media-frame > img.m-media {
  opacity: 1 !important;
  transition: none !important;
}

html.m-reduced .hero__media > *,
html.m-reduced .band__media > *,
html.m-reduced [data-parallax] > * {
  transform: none !important;
  will-change: auto;
}

/* Legacy .reveal safety under m-reduced: main.css only neutralises .reveal
   inside its own media-query block; the QA flag / live-change path needs
   the class-based mirror too. Idempotent with main.js's is-visible. */
html.m-reduced .reveal {
  opacity: 1 !important;
  transform: none !important;
  transition: none !important;
}
