/* =========================================================
   TIVOLI — animations.css

   Deliberately does NOT hide [data-reveal] elements by default.
   Content must stay fully visible with CSS alone (no JS, or a
   blocked GSAP CDN) — animations.js is solely responsible for
   hiding-then-revealing elements at runtime, and it only does so
   after confirming GSAP + ScrollTrigger actually loaded. This file
   just supplies transition-friendly defaults and hover/parallax
   support, plus the reduced-motion kill switch.
   ========================================================= */

[data-parallax] {
	will-change: transform;
}

.btn {
	will-change: transform;
}

/* ETAP 26 — homepage refresh: benefits ticker (pure CSS marquee) +
   cart badge pulse. Both are transform-only, GPU-composited, and
   already fully covered by the blanket prefers-reduced-motion override
   below (animation-duration:0.001ms + animation-iteration-count:1) —
   neither declares any OTHER `transform` outside its own @keyframes, so
   unlike the hero dymki (see the long fill-mode:both explanation
   further down) no extra fill-mode override is needed here: forcing a
   single near-instant iteration simply reverts each to its natural,
   already-correct un-animated resting state (translateX(0) / scale(1)). */
.benefits-ticker__track {
	will-change: transform;
}

@keyframes tivoli-ticker-scroll {
	from { transform: translateX(0); }
	to   { transform: translateX(-50%); }
}

@keyframes tivoli-cart-pulse {
	0%   { transform: scale(1); }
	35%  { transform: scale(1.35); }
	65%  { transform: scale(0.92); }
	100% { transform: scale(1); }
}

/* ETAP 18D — hero pizza + dymki orbit animations. All plain CSS
   @keyframes (no JS toggle, no GSAP, no setInterval/setTimeout) —
   they run continuously straight from page load, on DIFFERENT
   elements than the ones GSAP's entrance timeline touches
   (animations.js), so there is no transform-property conflict. The
   blanket prefers-reduced-motion override at the bottom of this file
   already neutralises all five (animation-duration:0.001ms), no extra
   per-animation reduced-motion rule needed. Replaces the ETAP 17D
   drift/float/message-swap system removed this etap (old .is-floating/
   .is-drifting/.hero__chip-text — all orphaned once the corresponding
   hero.php elements were removed).

   ETAP 18E (§8) — "dopracuj, nie zmieniaj system": tylko durations
   wydłużone (pizza 45s→65s, orbit+counter 35s→50s, patrz sections.css)
   i jedna NOWA, w pełni niezależna 5. animacja dodana poniżej
   (tivoli-bubble-breathe, na osobnej właściwości `scale`, nie
   `transform`) — struktura/mechanizm pierwszych 4 nietknięte. */

/* §7 — the whole ring of 6 dymki orbits together as one unit. */
@keyframes tivoli-orbit-spin {
	from { transform: rotate(0deg); }
	to   { transform: rotate(360deg); }
}

/* §8 — per-item counter-rotation, SAME duration/speed as
   tivoli-orbit-spin, opposite direction, starting from -1×this item's
   own static placement angle (--angle, set inline per dymek in
   hero.php). At any moment t: parent's spin (t/50s×360°) + this
   item's static placement (--angle) + this counter's animated value
   (-angle - t/50s×360°) sums to exactly 0° — so the icon/text inside
   never appears tilted, no matter where on the circle it currently is. */
@keyframes tivoli-orbit-counter {
	from { transform: rotate(calc(-1 * var(--angle))); }
	to   { transform: rotate(calc(-1 * var(--angle) - 360deg)); }
}

/* §10 — gentle 3.5px up/down drift, independent of the rotation
   layers above (separate element = zero transform-property conflict).
   -50%/-50% baked into every keyframe is the dymek's own constant
   centering offset against its zero-size anchor point (.hero__orbit-item
   has width/height:0) — an animated `transform` fully replaces any
   static one, so the offset has to live inside the keyframes too. */
@keyframes tivoli-bubble-float {
	0%, 100% { transform: translate3d(-50%, -50%, 0); }
	50%      { transform: translate3d(-50%, calc(-50% - 3.5px), 0); }
}

/* ETAP 18E (§8) — subtle "breathing" on each dymek, scale 1→1.03→1,
   with ZERO position shift. Deliberately on the standalone `scale`
   CSS property (not `transform: scale(...)`) so it composes
   independently alongside tivoli-bubble-float's `transform:
   translate3d(...)` on the same element (browsers combine translate ×
   rotate × scale × transform around the same transform-origin) —
   no risk to the centering fix above. End keyframe (100%) equals the
   resting value (scale:1), so — same as the other four — the blanket
   reduced-motion override below freezes it correctly with zero extra
   per-animation rule. */
@keyframes tivoli-bubble-breathe {
	0%, 100% { scale: 1; }
	50%      { scale: 1.03; }
}

/* ---------- Reduced motion ---------- */
@media (prefers-reduced-motion: reduce) {
	*,
	*::before,
	*::after {
		animation-duration: 0.001ms !important;
		animation-iteration-count: 1 !important;
		transition-duration: 0.001ms !important;
		scroll-behavior: auto !important;
	}

	[data-parallax] {
		transform: none !important;
	}

	/* ETAP 18D (§12) — deliberately NOT an explicit `animation: none`
	   override for the hero animations (tivoli-orbit-spin/
	   tivoli-orbit-counter/tivoli-bubble-float, plus tivoli-bubble-breathe
	   added in ETAP 18E — 4 total; a 5th, tivoli-plate-spin, existed here
	   too until ETAP 26 removed it outright — see .hero__plate-img in
	   sections.css — so there's nothing left to freeze for the pizza
	   photo itself, only the still-orbiting dymki below): each one's own
	   end keyframe (100%/to) IS its correct static resting state (0°,
	   de-tilted, centered, scale:1) BY DESIGN, and the blanket
	   animation-duration:0.001ms + animation-iteration-count:1 above
	   forces a near-instant single iteration for all four.

	   CORRECTION (found by adversarial review after the first version of
	   this etap): forcing a single iteration is NOT enough on its own —
	   the default animation-fill-mode is "none", so once that one
	   iteration ends, the animated property reverts to its NON-animated
	   value (here: nothing, since .hero__orbit-counter/.hero__bubble/etc.
	   declare `transform` only inside their @keyframes), not the 100%
	   keyframe. That silently broke exactly the two things this comment
	   used to (wrongly) claim were safe: tivoli-orbit-counter's tilt
	   cancellation and tivoli-bubble-float's -50%/-50% centering. Fixed
	   by adding `animation-fill-mode: both;` directly on each of the
	   (originally 4, now 3 since ETAP 26 removed .hero__plate-img's
	   animation entirely) elements' own rules (sections.css) — NOT here, since fill-mode
	   isn't reduced-motion-specific, it must hold for normal playback
	   too (the "backwards" half of `both` also fixes a second bug: a
	   delayed .hero__bubble rendering un-centered and visibly jumping
	   into place once its animation-delay elapses, even at full motion).
	   With fill-mode:both in place on the elements themselves (a single
	   fill-mode value applies cyclically to every animation-name in a
	   comma-separated `animation` shorthand, so tivoli-bubble-breathe's
	   `scale` is covered by the same declaration as tivoli-bubble-float's
	   `transform` on .hero__bubble), this blanket duration/iteration-count
	   override now correctly freezes all four at their 100% keyframe — no
	   per-animation override needed here. */

	.pizza-card:hover .pizza-card__media img,
	.menu-preview__item:hover img {
		transform: none;
	}
}
