/* ══════════════════════════════════════════════════════════════════════════
   MOTION — tiered, and switched on only by script.

   Tier 1 (translate/scale/rotate entrances) is removed entirely under
   `prefers-reduced-motion: reduce`. Tier 2 (small pops, the Célpakk swap) drops
   to a short cross-fade. Tier 3 (colour, focus, opacity feedback) always runs.

   Nothing on this page animates forever: there is no marquee, no auto-carousel
   and no infinite spin, so no element needs a pause control under WCAG 2.2.2.

   The pre-animation state lives behind `.rv-on`, which script adds only when
   motion is allowed AND IntersectionObserver exists — so with JS off, or with
   reduced motion on, every element renders in its final state and nothing can
   be left invisible.
   ══════════════════════════════════════════════════════════════════════════ */

:root {
  --ease-out: cubic-bezier(0.22, 0.61, 0.36, 1);
  --rv-dur: 0.62s;
}

/* ── Tier 1 · scroll reveals ─────────────────────────────────────────────── */

.rv-on .rv {
  opacity: 0;
  transform: translateY(26px);
  will-change: opacity, transform;
}
.rv-on .rv.is-in {
  opacity: 1;
  transform: none;
  transition:
    opacity var(--rv-dur) var(--ease-out) var(--rv-d, 0s),
    transform var(--rv-dur) var(--ease-out) var(--rv-d, 0s);
  will-change: auto;
}

/* Packs are already centred with translateX(-50%), so they cannot carry a
   second transform — the lift is applied to their container instead. */
.rv-on .rv-pack { opacity: 0; transform: translateY(40px) scale(0.97); }
.rv-on .rv-pack.is-in {
  opacity: 1; transform: none;
  transition:
    opacity 0.78s var(--ease-out) var(--rv-d, 0s),
    transform 0.78s var(--ease-out) var(--rv-d, 0s);
}

/* The hero's pressed-on sticker is gone with the hero recomposition: on a
   saturated first screen it was a fourth object competing in a composition
   already read as over-composed. Its arrival animation goes with it. */

/* The seal turns once as it arrives, then stops. */
.rv-on .stamp,
.rv-on .say-mark { opacity: 0; }
.rv-on .stamp.is-in,
.rv-on .say-mark.is-in {
  opacity: 1;
  animation: seal-on 0.9s var(--ease-out) 0.3s both;
}
@keyframes seal-on {
  from { opacity: 0; transform: rotate(-95deg) scale(0.72); }
  to   { opacity: 1; transform: none; }
}

/* ── Tier 1 · the hero ────────────────────────────────────────────────────
   The hero owns its whole turn in home.css: the pack crossing, the name
   being printed and the board's stagger are one choreographed event and
   splitting them across two files is how the last hero ended up with a
   price and a name fading on different curves. Nothing here.
   ──────────────────────────────────────────────────────────────────────── */

/* The mark scales, not the button — the button IS the tap target and resizing
   it under the pointer would move the target out from under the finger. */
/* The rotation's dots and its pause button are gone; the hero's chooser owns
   its own hover and pressed states in home.css. */

/* ── Tier 1 · the brand rail ──────────────────────────────────────────────
   The track holds N identical sequences and travels exactly ONE sequence
   width, so the frame at the end of a cycle is pixel-identical to the frame at
   the start and the reset is invisible. Linear and infinite, so the drift
   never eases, never pauses between cycles and never restarts visibly.

   Both values come from measurement, not from a guess: `--rail-w` is the real
   rendered width of one sequence and `--rail-t` is derived from it at a fixed
   speed, so the marks move at the same pace whatever the catalogue size.
   The old rule translated -50%, which is only correct for exactly two
   sequences — and two sequences of five marks are narrower than a 1920
   viewport, which is why a blank stretch crossed the band once per cycle. */
.rail-track {
  animation: rail-drift var(--rail-t, 42s) linear infinite;
  will-change: transform;
}
.rail-track.is-paused,
.rail-track.is-hover { animation-play-state: paused; }
@keyframes rail-drift {
  from { transform: translate3d(0, 0, 0); }
  to   { transform: translate3d(calc(var(--rail-w, 0px) * -1), 0, 0); }
}
.bcard { transition: transform 0.18s var(--ease-out); }
.bcard:hover { transform: translateY(-2px); }

/* ── Tier 2 · interaction feedback ───────────────────────────────────────── */

/* Célpakk: the pack and its colour plate cross-fade between goals instead of
   cutting, so the answer reads as a change to one object. */
.plate-pack { transition: opacity 0.2s ease; }
.plate-pack.is-swapping { opacity: 0; }

.tile-pack { transition: transform 0.26s var(--ease-out); }
.tile:hover .tile-pack { transform: translateX(-50%) translateY(-10px); }
.tile-buy { transition: opacity 0.16s ease, transform 0.22s var(--ease-out); }
.tile:hover .tile-buy { transform: translateX(-50%) translateY(-4px); }

.chip { transition: transform 0.16s var(--ease-out), box-shadow 0.16s ease; }
.chip:hover { transform: translateY(-3px); box-shadow: 0 6px 0 rgba(46, 28, 21, 0.14); }

.faq-item[open] > p { animation: faq-open 0.28s var(--ease-out) both; }
@keyframes faq-open {
  from { opacity: 0; transform: translateY(-6px); }
  to   { opacity: 1; transform: none; }
}

/* ══ reduced motion ═════════════════════════════════════════════════════════
   `.rv-on` is never added, so no reveal can start. These rules cover the
   interaction layer: Tier 1 movement is dropped, Tier 2 becomes a short fade,
   Tier 3 (opacity and colour feedback) is kept — nothing teleports. */

@media (prefers-reduced-motion: reduce) {
  .rv, .rv-pack, .stamp, .say-mark { opacity: 1 !important; transform: none !important; animation: none !important; }

  /* The hero holds its first state — the script never starts the timer — and
     its own reduced-motion block in home.css stops every part of the turn.
     Nothing is lost: the field, the name, the board, both destinations and the
     product are all fully present in a held state. */
  .block-amber { transition: none; }

  /* The rail stops moving and SETTLES rather than becoming a sideways
     scroller. A track wider than its window with nothing moving it would put
     most of the manufacturers out of reach, but making it scroll horizontally
     answers that with a second problem: a strip of six logos that has to be
     dragged, and a scroll container whose width propagates to the document.
     Wrapping the marks into a still, centred block reaches every manufacturer
     at a glance and leaves nothing to scroll.

     The loop's duplicate sequence exists only to hide the seam of a moving
     track, so with nothing moving it is removed — otherwise every
     manufacturer would be listed twice. */
  .rail-track { animation: none; transform: none; width: 100%; }
  .rail-seq + .rail-seq { display: none; }
  .rail-seq {
    flex-wrap: wrap;
    justify-content: center;
    width: 100%;
    row-gap: 4px;
  }
  .rail-view { overflow: visible; -webkit-mask-image: none; mask-image: none; }
  .bcard { transition: none; }
  .bcard:hover { transform: none; }

  .tile:hover .tile-pack,
  .tile:hover .tile-buy { transform: translateX(-50%); }
  .chip:hover { transform: none; }
  .btn-pill:hover { transform: none; }

  .tile-buy { transition: opacity 0.15s ease; }        /* Tier 3 — kept */
  .plate-pack { transition: opacity 0.15s ease; }      /* Tier 3 — kept */
  .faq-item[open] > p { animation: faq-open-reduced 0.15s ease both; }
  @keyframes faq-open-reduced { from { opacity: 0; } to { opacity: 1; } }
}
