/* khedai-theme-v2-motion-v1 */
/* Motion animates transform (translate, scale, rotate), opacity and clip-path only,
   and reduced motion shows the final frame (AGENTS.md; the storefront motion test
   holds every stylesheet under static/ to it). */
/* Backwards only: a reveal holds its first frame until it starts and leaves nothing
   behind once it ends, so its clip never cuts a shadow at rest. */
[data-theme-motion] {
	animation-delay: var(--theme-motion-delay, 0ms);
	animation-fill-mode: backwards;
	animation-timing-function: cubic-bezier(0.22, 1, 0.36, 1);
}

[data-theme-motion='reveal-soft'] { animation-name: theme-reveal-soft; animation-duration: 900ms; }
[data-theme-motion='reveal-snap'] { animation-name: theme-reveal-snap; animation-duration: 620ms; }
[data-theme-motion='reveal-pop'] { animation-name: theme-reveal-pop; animation-duration: 760ms; }
[data-theme-motion='reveal-measure'] { animation-name: theme-reveal-measure; animation-duration: 820ms; }
[data-theme-motion='reveal-orbit'] { animation-name: theme-reveal-orbit; animation-duration: 980ms; }
[data-theme-motion='reveal-quiet'] { animation-name: theme-reveal-quiet; animation-duration: 1100ms; }
[data-theme-motion='reveal-step'] { animation-name: theme-reveal-step; animation-duration: 720ms; }
[data-theme-motion^='media-'] { animation-name: theme-media-enter; animation-duration: 1100ms; }
[data-theme-motion='media-cut'] { animation-name: theme-media-cut; animation-duration: 720ms; }
[data-theme-motion='media-orbit'] { animation-name: theme-media-orbit; animation-duration: 1200ms; }
[data-theme-motion='media-plan'] { animation-name: theme-media-plan; animation-duration: 900ms; }
[data-theme-motion='ticker-track'] { animation: theme-ticker-track 16s linear infinite; }

[data-theme-motion='action-lift'],
[data-theme-motion^='state-'] {
	transition: translate 240ms cubic-bezier(0.22, 1, 0.36, 1),
		scale 240ms cubic-bezier(0.22, 1, 0.36, 1);
}

[data-theme-motion='action-lift']:is(:hover, :focus-within) { translate: 0 -4px; }

[data-theme-motion^='state-']:is(:hover, :focus-within) { scale: 1.008; }

/* A look (theme-depth-v1) on a pointer that hovers: a lone photo leans in inside its
   frame, so its shadow and shape stay. Rest is unmoved. */
@media (hover: hover) and (pointer: fine) {
	[data-theme-hover='zoom'] img {
		transition: scale var(--theme-hover-zoom, 700ms) cubic-bezier(0.22, 1, 0.36, 1);
	}
	[data-theme-hover='zoom']:hover img { scale: 1.03; }
	/* The louder look answers sooner: its crisp tone selects it. */
	[data-theme-hover='zoom'][data-theme-photo-tone='crisp'] { --theme-hover-zoom: 450ms; }
}

/* A line icon draws itself on from nothing (each stroke measures 1) and stays drawn. The
   draw runs on time. Its first frame is hidden, so a round cap never shows a dot before
   the pen lands, and the pen sets off fast, so no frame holds a row of dots; at rest it
   carries no dash and draws as without it. A browser that cannot follow the scroll draws
   it at load; one that can draws it as it arrives (below). */
[data-theme-motion='icon-draw'] svg :is(path, circle, rect, line, polyline, polygon, ellipse) {
	animation: theme-icon-draw 600ms cubic-bezier(0.33, 1, 0.68, 1) var(--theme-motion-delay, 0ms)
		backwards;
}

/* Where the browser follows the scroll, two steps on an icon's view timeline time its draw.
   Unarmed it is drawn, so where they never come (reduced motion, the builder, a browser
   without style queries) it stays drawn. Steps are set on the main thread, which on a fast
   scroll lands them frames late. The arm comes a whole screen before the icon is in view
   and holds it at its hidden first frame, so even a fling's late step never shows it drawn,
   then gone, then drawing; the second comes as it enters the screen and starts the draw, so
   a slow scroll sees all of it. Until the icon reaches the screen it is out of sight anyway. */
@property --theme-icon-armed { syntax: '<number>'; inherits: true; initial-value: 0; }
@property --theme-icon-shown { syntax: '<number>'; inherits: true; initial-value: 0; }

@keyframes theme-reveal-soft {
	from { opacity: 0; translate: 0 22px; scale: 0.985; }
	to { opacity: 1; translate: 0 0; scale: 1; }
}
@keyframes theme-reveal-snap {
	from { opacity: 0; translate: -34px 0; clip-path: inset(0 100% 0 0); }
	to { opacity: 1; translate: 0 0; clip-path: inset(0); }
}
@keyframes theme-reveal-pop {
	from { opacity: 0; translate: 0 28px; scale: 0.94; }
	to { opacity: 1; translate: 0 0; scale: 1; }
}
@keyframes theme-reveal-measure {
	from { opacity: 0; translate: 0 14px; clip-path: inset(0 0 100% 0); }
	to { opacity: 1; translate: 0 0; clip-path: inset(0); }
}
@keyframes theme-reveal-orbit {
	from { opacity: 0; translate: 24px 18px; scale: 0.96; }
	to { opacity: 1; translate: 0 0; scale: 1; }
}
@keyframes theme-reveal-quiet {
	from { opacity: 0; translate: 0 12px; }
	to { opacity: 1; translate: 0 0; }
}
@keyframes theme-reveal-step {
	from { opacity: 0; translate: 0 20px; clip-path: inset(0 0 52% 0); }
	to { opacity: 1; translate: 0 0; clip-path: inset(0); }
}
@keyframes theme-media-enter {
	from { opacity: 0; translate: 0 38px; scale: 1.035; }
	to { opacity: 1; translate: 0 0; scale: 1; }
}
@keyframes theme-media-cut {
	from { opacity: 0; translate: 44px 0; clip-path: inset(0 0 0 76%); }
	to { opacity: 1; translate: 0 0; clip-path: inset(0); }
}
@keyframes theme-media-orbit {
	from { opacity: 0; translate: 42px 28px; scale: 0.9; }
	to { opacity: 1; translate: 0 0; scale: 1; }
}
@keyframes theme-media-plan {
	from { opacity: 0; translate: 0 30px; clip-path: inset(16% 8% 16% 8%); }
	to { opacity: 1; translate: 0 0; clip-path: inset(0); }
}
/* The photo is scaled by 1.06, 3% beyond its frame on every side, and travels 2.5% of its
   height, so its edges never show. Both live in the keyframes: unanimated, it is as drawn. */
@keyframes theme-photo-drift {
	from { transform: translateY(-2.5%) scale(1.06); }
	to { transform: translateY(2.5%) scale(1.06); }
}
@keyframes theme-icon-arm {
	from { --theme-icon-armed: 0; }
	to { --theme-icon-armed: 1; }
}
@keyframes theme-icon-show {
	from { --theme-icon-shown: 0; }
	to { --theme-icon-shown: 1; }
}
@keyframes theme-icon-draw {
	from { opacity: 0; stroke-dasharray: 1; stroke-dashoffset: 1; }
	1% { opacity: 1; }
	to { opacity: 1; stroke-dasharray: 1; stroke-dashoffset: 0; }
}
@keyframes theme-ticker-track {
	0%, 8% { translate: 0 0; }
	50% { translate: -3.5% 0; }
	92%, 100% { translate: 0 0; }
}

/* Scroll-linked reveals must finish while the element is entering the
   viewport. Ending later (for example at `cover 34%`) keeps everything in the
   lower part of the screen invisible at rest, including first-screen copy. */
@supports (animation-timeline: view()) {
	/* Everything in here follows the page's own scroll, and a view timeline binds to the
	   nearest scroll container, so the body must never become one. It would whenever the
	   root's overflow is set as well: the menu sheet does that to lock the page, and so does
	   another renderer's stylesheet once it has loaded. Every timeline would then read "in
	   view" at once, and an icon held below the screen would start drawing unseen. Clipping
	   scrolls nothing and looks the same. The builder keeps its own scrolling. */
	:root:not(:has([data-render-mode='editor'])) body { overflow-x: clip !important; }

	[data-theme-motion^='media-'],
	[data-theme-motion^='reveal-'] {
		animation-timeline: view();
		animation-range: entry 0% entry 70%;
		animation-delay: 0ms;
	}

	/* The arm stays set until the icon falls a whole screen below it again, so it draws
	   again only when it comes back up from that far below, and never when it comes back
	   down from above. Shown, it waits 120 ms more than its stagger, about the time a slow
	   scroll takes to bring it wholly into view. */
	[data-theme-motion='icon-draw'] {
		animation:
			theme-icon-arm steps(1, jump-start) both,
			theme-icon-show steps(1, jump-start) both;
		animation-timeline: view(block 0px -100%), view(block 0px);
		animation-range: entry 0% entry 100%;
	}
	[data-theme-motion='icon-draw'] svg :is(path, circle, rect, line, polyline, polygon, ellipse) {
		animation: none;
	}
	@container style(--theme-icon-armed: 1) {
		[data-theme-motion='icon-draw'] svg :is(path, circle, rect, line, polyline, polygon, ellipse) {
			animation: theme-icon-draw 600ms cubic-bezier(0.33, 1, 0.68, 1)
				calc(var(--theme-motion-delay, 0ms) + 120ms) backwards paused;
		}
	}
	@container style(--theme-icon-shown: 1) {
		[data-theme-motion='icon-draw'] svg :is(path, circle, rect, line, polyline, polygon, ellipse) {
			animation-play-state: running;
		}
	}

	/* A lone photo (theme-depth-v1) drifts inside its frame as it crosses the screen, from
	   up to down, so it seems to sit a little deeper than the page. The frame names the
	   timeline: the photo's own clipper is a scroll container, and would hold it still. */
	[data-theme-scroll='drift'] { view-timeline: --theme-photo-drift block; }
	[data-theme-scroll='drift'] img {
		animation: theme-photo-drift linear;
		animation-timeline: --theme-photo-drift;
		animation-range: cover 0% cover 100%;
	}
}

@media (prefers-reduced-motion: reduce) {
	/* An icon's strokes, a hovered photo and a drifting one lose only what they move. */
	[data-theme-motion='icon-draw'] svg * { animation: none !important; }
	[data-theme-hover] img { transition: none !important; scale: 1 !important; }
	[data-theme-scroll] img { animation: none !important; }
	[data-theme-motion] {
		animation: none !important;
		transition: none !important;
		translate: none !important;
		scale: 1 !important;
		clip-path: none !important;
	}
}

[data-render-mode='editor'] [data-theme-motion] {
	animation: none !important;
	opacity: 1 !important;
	translate: none !important;
	scale: 1 !important;
	clip-path: none !important;
}

[data-render-mode='editor'] [data-theme-motion='icon-draw'] svg * { animation: none !important; }
[data-render-mode='editor'] [data-theme-hover] img { transition: none !important; scale: 1 !important; }
[data-render-mode='editor'] [data-theme-scroll] img { animation: none !important; }
