/**
 * ROYA - Scroll motion
 *
 * One shared vocabulary for every "enters with an effect" note on the client's
 * fix list (2026-09-23). A template marks an element with
 *
 *     data-roya-reveal="zoom|right|left|up"      the entrance
 *     data-roya-reveal-delay="240"               milliseconds, optional
 *
 * and motion.js adds `is-revealed` when it crosses into view. Nothing else in
 * the theme should write its own scroll animation.
 *
 * DIRECTIONS ARE PHYSICAL, NOT LOGICAL. "right" means the element flies in
 * from the visual right of the screen, in an RTL document as in an LTR one -
 * the client describes what they see, and a logical property would silently
 * mirror it (the mistake this project has already shipped twice).
 *
 * The hidden state hangs off `.roya-motion` on <html>, which a tiny inline
 * script in the head sets and then removes again after four seconds if
 * motion.js never reported in. Without JavaScript, or with it broken, every
 * marked element is simply visible.
 */

/* ==========================================================================
   The reveal
   ========================================================================== */

.roya-motion [data-roya-reveal] {
	opacity: 0;
	transition:
		opacity 900ms ease,
		transform 900ms cubic-bezier(0.22, 0.61, 0.36, 1);
	transition-delay: var(--roya-reveal-delay, 0ms);
}

/* Gentle zoom in: the picture grows into place rather than snapping to it.
   Starts BELOW 1 - "זום אין" is a zoom in, so the mark has to get bigger. */
.roya-motion [data-roya-reveal="zoom"] {
	transform: scale(0.94);
}

.roya-motion [data-roya-reveal="right"] {
	transform: translateX(4.5rem);
}

.roya-motion [data-roya-reveal="left"] {
	transform: translateX(-4.5rem);
}

.roya-motion [data-roya-reveal="up"] {
	transform: translateY(2rem);
}

.roya-motion [data-roya-reveal].is-revealed {
	opacity: 1;
	transform: none;
}

/*
 * Phones get no sideways travel. A 72px slide on a full-width block is 72px of
 * horizontal overflow while it runs, which is exactly what health.js fails a
 * page for - and on a 375 screen the gesture reads as a glitch rather than as
 * choreography. The fade stays; it just arrives from below.
 */
@media (max-width: 767px) {
	.roya-motion [data-roya-reveal="right"],
	.roya-motion [data-roya-reveal="left"] {
		transform: translateY(1.5rem);
	}
}

/*
 * Sections whose children travel sideways have to clip: the slide happens
 * outside the container's own margins at every width under 1440.
 * `clip`, not `hidden` - hidden would make each one a scroll container.
 */
.roya-services,
.roya-about-statement,
.roya-about-process,
.roya-materials {
	overflow-x: clip;
}

/* A visitor who asked for less motion gets none of it - motion.js reveals
   everything at once, and this makes sure nothing is mid-transform when it
   does. */
@media (prefers-reduced-motion: reduce) {
	.roya-motion [data-roya-reveal] {
		opacity: 1;
		transform: none;
		transition: none;
	}
}

/* Paper has no scroll position, so nothing would ever trigger. */
@media print {
	.roya-motion [data-roya-reveal] {
		opacity: 1;
		transform: none;
	}
}


/* ==========================================================================
   The writing effect
   Home "אודות" and About "הסיפור שלנו": the copy is written out as the
   section arrives. motion.js wraps each character in its own span; the
   characters keep their layout from the first frame (opacity, not display),
   so nothing reflows and the reader's eye has nothing to chase.
   ========================================================================== */

.roya-motion .roya-type__char {
	opacity: 0;
	transition: opacity 90ms linear;
}

.roya-motion .roya-type__char.is-typed {
	opacity: 1;
}

@media (prefers-reduced-motion: reduce) {
	.roya-motion .roya-type__char {
		opacity: 1;
		transition: none;
	}
}

@media print {
	.roya-motion .roya-type__char {
		opacity: 1;
	}
}
