/* ════════════════════════════════════════════════════════════════════
   SITE MOTION: the press-proof language on every page
   ════════════════════════════════════════════════════════════════════
   Loaded on all pages after the page styles (inc/enqueue.php). The home
   page adds its own layers on top (motion.css, motion-high.css).

   One orchestrated moment per view, always print vocabulary:
   - Page head (every inner page, on load): crop marks settle, the slug's
     control patches ink in, the headline's cyan and magenta plates slide
     into register, the trim rule is rolled on.
   - Listings (product, category, post grids): sheets come off the press
     as they scroll into view (JS: motion-site.js); on hover (or tap) a
     card's artwork prints off-register for a beat and snaps back.
   - Product page: the gallery proof registers on load; the spec sheet
     inks in, row by row, whenever its tab opens.
   - Forms (job tickets): a focused field's ring arrives as two
     misregistered plates that lock into the magenta focus ring.
   - 404: a deliberately misregistered giant 404.
   - Empty search: a blank sheet feeds out of the press.
   - Footer: the colour rule inks in when it comes into view.
   - Long reads (posts, legal pages): a CMYK ink rule under the header
     tracks reading progress (CSS scroll timeline, no JS).

   Rules of the house: transform, opacity, clip-path, text-shadow and
   filter only (no layout properties), nothing scroll-jacked, decoration
   is pseudo-elements or aria-hidden. prefers-reduced-motion: reduce or
   forced colours: everything below is off and the design is static.
   Scroll reveals hide content only under html.tr-site-motion, which
   motion-site.js sets; without JS nothing is ever hidden.
   ════════════════════════════════════════════════════════════════════ */

/* ── New semantic tokens (defined from existing ones; a theme such as
   [data-theme="dark"] may redefine them) ─────────────────────────────── */
:root {
	--tr-ease-press: cubic-bezier(0.16, 0.84, 0.24, 1);     /* fast in, long settle */
	--tr-ease-snap: cubic-bezier(0.3, 1.8, 0.5, 1);         /* sprung register snap */
	--tr-ghost-c: color-mix(in srgb, var(--tr-color-cyan) 88%, transparent);    /* misregistered cyan plate */
	--tr-ghost-m: color-mix(in srgb, var(--tr-color-magenta) 80%, transparent); /* misregistered magenta plate */
	--tr-ghost-y: color-mix(in srgb, var(--tr-color-yellow) 92%, transparent);  /* misregistered yellow plate */
	--tr-halftone-dot: color-mix(in srgb, var(--tr-color-ink) 10%, transparent);  /* page-head screen */
	--tr-perforation: var(--tr-color-paper);                  /* ticket notches = page background */
	--tr-rule-k: var(--tr-color-logo-grey);                   /* K segment of the CMYK rules */
	--tr-duration-register: 900ms;
}

@media (prefers-reduced-motion: no-preference) and (forced-colors: none) {
	/* ════════════════════════════════════════════════════════════════
	   1. PAGE HEAD: the proof registers on load
	   ════════════════════════════════════════════════════════════════ */
	.tr-page-head > .tr-container::before {
		animation: tr-marks-settle 520ms var(--tr-ease-press) 60ms backwards;
	}

	.tr-page-head > .tr-container::after {
		animation: tr-slug-ink 460ms ease-out 420ms backwards;
	}

	:is(.tr-page-head :is(h1, .tr-entry__title), .tr-pdp__header h1) {
		animation: tr-h1-register var(--tr-duration-register) var(--tr-ease-press) 120ms backwards;
	}

	.tr-page-head::after {
		animation: tr-rule-ink 700ms var(--tr-ease-press) 260ms backwards;
	}

	.tr-page-head--dark::after {
		animation: tr-rule-uncover 760ms var(--tr-ease-press) 260ms backwards;
	}

	/* ════════════════════════════════════════════════════════════════
	   2. LISTINGS: off the press (armed by motion-site.js)
	   ════════════════════════════════════════════════════════════════ */
	.tr-site-motion [data-tr-press] > * {
		clip-path: inset(-12px -12px 100% -12px);
		translate: 0 18px;
		transition:
			clip-path 640ms var(--tr-ease-press),
			translate 640ms var(--tr-ease-press);
		transition-delay: calc(var(--tr-col, 0) * 70ms);
	}

	.tr-site-motion [data-tr-press] > .is-inview {
		clip-path: inset(-12px -12px -12px -12px);
		translate: 0 0;
	}

	/* Settled: nothing stays clipped, so hover lifts and focus rings show. */
	.tr-site-motion [data-tr-press] > .is-settled {
		clip-path: none;
		translate: none;
		transition: none;
	}

	/* A card that just came off the press prints off-register for a beat,
	   then snaps into register: the phone's version of the hover. */
	.tr-site-motion [data-tr-press] > .is-inview:not(.is-initial) :is(.tr-product-card__media, .tr-post-card__media) > :is(svg, img) {
		animation: tr-misregister 760ms calc(260ms + var(--tr-col, 0) * 70ms) backwards;
	}

	/* ── Hover / tap misregistration (cards) ─────────────────────────── */
	@media (hover: hover) {
		:is(.tr-product-card, .tr-post-card):hover :is(.tr-product-card__media, .tr-post-card__media) > :is(svg, img) {
			animation: tr-misregister 620ms backwards;
		}

		:is(.tr-product-card, .tr-post-card):hover :is(.tr-product-card__title, .tr-post-card__title) {
			animation: tr-misregister-type 620ms backwards;
		}

		.tr-cat-card:hover .tr-cat-card__icon {
			animation: tr-misregister 560ms backwards;
		}
	}

	@media (hover: none) {
		:is(.tr-product-card, .tr-post-card, .tr-cat-card):active :is(.tr-product-card__media > svg, .tr-product-card__media > img, .tr-post-card__media > svg, .tr-post-card__media > img, .tr-cat-card__icon) {
			animation: tr-misregister 520ms backwards;
		}
	}

	/* Post cards: the plate rule on top is rolled on as the card is hovered. */
	.tr-post-card::before { transition: transform 320ms var(--tr-ease-press); }

	/* ── CTA band on inner pages: the magenta is rolled on ───────────── */
	.tr-site-motion .tr-cta-band[data-tr-roll] {
		clip-path: inset(0 100% 0 0 round var(--tr-radius-md));
		transition: clip-path 700ms var(--tr-ease-press);
	}

	.tr-site-motion .tr-cta-band[data-tr-roll].is-inview {
		clip-path: inset(0 0 0 0 round var(--tr-radius-md));
	}

	.tr-site-motion .tr-cta-band[data-tr-roll].is-settled {
		clip-path: none;
		transition: none;
	}

	/* ════════════════════════════════════════════════════════════════
	   3. PRODUCT PAGE: the proof registers, the spec sheet inks in
	   ════════════════════════════════════════════════════════════════ */
	.tr-pdp__media .tr-proof__crop::before,
	.tr-pdp__media .tr-proof__crop::after {
		animation: tr-draw 420ms ease-out 380ms backwards;
	}

	.tr-pdp__media .tr-proof__crop--tl::before,
	.tr-pdp__media .tr-proof__crop--tr::before { transform-origin: bottom; }
	.tr-pdp__media .tr-proof__crop--bl::before,
	.tr-pdp__media .tr-proof__crop--br::before { transform-origin: top; }
	.tr-pdp__media .tr-proof__crop--tl::after,
	.tr-pdp__media .tr-proof__crop--bl::after { transform-origin: right; }
	.tr-pdp__media .tr-proof__crop--tr::after,
	.tr-pdp__media .tr-proof__crop--br::after { transform-origin: left; }

	.tr-pdp__stage > :is(svg, img) {
		animation: tr-proof-register 1100ms var(--tr-ease-press) 140ms backwards;
	}

	.tr-pdp__media .tr-proof::before {
		animation: tr-reg-turn 640ms var(--tr-ease-press) 520ms backwards;
	}

	.tr-pdp__media .tr-proof::after {
		animation: tr-slug-ink 460ms ease-out 700ms backwards;
	}

	/* Replays whenever the tab is opened (display none → table). */
	.tr-spec-table tr {
		animation: tr-row-ink 460ms var(--tr-ease-press) backwards;
		animation-delay: calc(var(--tr-row, 0) * 60ms);
	}

	.tr-spec-table tr:nth-child(2) { --tr-row: 1; }
	.tr-spec-table tr:nth-child(3) { --tr-row: 2; }
	.tr-spec-table tr:nth-child(4) { --tr-row: 3; }
	.tr-spec-table tr:nth-child(5) { --tr-row: 4; }
	.tr-spec-table tr:nth-child(6) { --tr-row: 5; }
	.tr-spec-table tr:nth-child(n+7) { --tr-row: 6; }

	.tr-spec-table th::before {
		animation: tr-tick-ink 360ms var(--tr-ease-press) backwards;
		animation-delay: calc(120ms + var(--tr-row, 0) * 60ms);
	}

	.tr-tabs__panel:not([hidden]) {
		animation: tr-panel-in 280ms var(--tr-ease-press) backwards;
	}

	/* ════════════════════════════════════════════════════════════════
	   4. FORMS: the focus ring registers
	   ════════════════════════════════════════════════════════════════ */
	:is(.tr-input, .tr-select, .tr-textarea):focus-visible {
		animation: tr-focus-register 420ms var(--tr-ease-press);
	}

	/* The ticket's control patches ink in once. */
	:is(.tr-quote, .tr-form[data-tr-validate])::after {
		animation: tr-slug-ink 460ms ease-out 300ms backwards;
	}

	/* ════════════════════════════════════════════════════════════════
	   5. 404 and the empty result
	   ════════════════════════════════════════════════════════════════ */
	.tr-404__plate--c { animation: tr-404-c 1300ms var(--tr-ease-press) 100ms backwards; }
	.tr-404__plate--m { animation: tr-404-m 1300ms var(--tr-ease-press) 180ms backwards; }
	.tr-404__plate--y { animation: tr-404-y 1300ms var(--tr-ease-press) 260ms backwards; }
	.tr-404__plate--k { animation: tr-404-k 700ms var(--tr-ease-press) backwards; }

	/* Pointer (desktop): the plates drift further apart with the cursor,
	   never into register (motion-site.js sets --tr-404-x/y, -1…1). */
	.tr-404__plate--c { translate: calc(var(--tr-404-x, 0) * -10px) calc(var(--tr-404-y, 0) * -6px); }
	.tr-404__plate--m { translate: calc(var(--tr-404-x, 0) * 12px) calc(var(--tr-404-y, 0) * 8px); }
	.tr-404__plate--y { translate: calc(var(--tr-404-x, 0) * -5px) calc(var(--tr-404-y, 0) * 11px); }

	.tr-empty__art {
		animation: tr-sheet-feed 900ms var(--tr-ease-press) 80ms backwards;
	}

	/* ════════════════════════════════════════════════════════════════
	   6. FOOTER: the colour rule inks in (armed by motion-site.js)
	   ════════════════════════════════════════════════════════════════ */
	.tr-site-motion .tr-site-footer .tr-colorbar--rule > span {
		transform: scaleX(0);
		transform-origin: left;
		transition: transform 520ms var(--tr-ease-press);
	}

	.tr-site-motion .tr-site-footer .tr-colorbar--rule > span:nth-child(2) { transition-delay: 90ms; }
	.tr-site-motion .tr-site-footer .tr-colorbar--rule > span:nth-child(3) { transition-delay: 180ms; }
	.tr-site-motion .tr-site-footer .tr-colorbar--rule > span:nth-child(4) { transition-delay: 270ms; }

	.tr-site-motion .tr-site-footer.is-inked .tr-colorbar--rule > span { transform: none; }

	/* ════════════════════════════════════════════════════════════════
	   7. LONG READS: reading progress as an ink rule under the header
	   ════════════════════════════════════════════════════════════════ */
	@supports (animation-timeline: scroll()) {
		:is(.single-post, .page-template-default) .tr-site-header::after {
			content: "";
			position: absolute;
			right: 0;
			bottom: -1px;
			left: 0;
			height: 3px;
			background: linear-gradient(90deg, var(--tr-color-cyan) 0 25%, var(--tr-color-magenta) 0 50%, var(--tr-color-yellow) 0 75%, var(--tr-rule-k, var(--tr-color-logo-grey)) 0);
			transform-origin: left;
			animation: tr-read-progress linear both;
			animation-timeline: scroll(root block);
			pointer-events: none;
		}
	}
}

/* Printing: everything static and visible. */
@media print {
	[data-tr-press] > *,
	.tr-cta-band[data-tr-roll] { clip-path: none !important; translate: none !important; }
	.tr-site-footer .tr-colorbar--rule > span { transform: none !important; }
	.tr-site-header::after { display: none !important; }
}

/* ── Keyframes ──────────────────────────────────────────────────────── */
@keyframes tr-marks-settle { from { opacity: 0; scale: 1.035 1.2; } }
@keyframes tr-slug-ink { from { clip-path: inset(0 100% 0 0); } to { clip-path: inset(0 0 0 0); } }
@keyframes tr-rule-ink { from { clip-path: inset(0 100% 0 0); } to { clip-path: inset(0 0 0 0); } }
@keyframes tr-rule-uncover { from { transform: scaleX(1); } }
@keyframes tr-draw { from { scale: 0; } }
@keyframes tr-reg-turn { from { opacity: 0; rotate: -90deg; scale: 0.6; } }
@keyframes tr-panel-in { from { opacity: 0; translate: 0 6px; } }

/* Headline plates: cyan from up-left, magenta from down-right, converging
   under the key (zero-offset shadows sit hidden under the glyphs). */
@keyframes tr-h1-register {
	from { text-shadow: -0.07em -0.035em 0 var(--tr-ghost-c), 0.06em 0.045em 0 var(--tr-ghost-m); }
	to { text-shadow: 0 0 0 var(--tr-ghost-c), 0 0 0 var(--tr-ghost-m); }
}

@keyframes tr-proof-register {
	from { filter: drop-shadow(-14px -9px 0 var(--tr-ghost-c)) drop-shadow(12px 10px 0 var(--tr-ghost-m)); }
	to { filter: drop-shadow(0 0 0 var(--tr-ghost-c)) drop-shadow(0 0 0 var(--tr-ghost-m)); }
}

/* Off-register for a beat, then a sprung snap into register. */
@keyframes tr-misregister {
	0%,
	38% {
		filter: drop-shadow(-3px -1px 0 var(--tr-ghost-c)) drop-shadow(3px 2px 0 var(--tr-ghost-m));
		animation-timing-function: var(--tr-ease-snap);
	}
	100% { filter: drop-shadow(0 0 0 var(--tr-ghost-c)) drop-shadow(0 0 0 var(--tr-ghost-m)); }
}

@keyframes tr-misregister-type {
	0%,
	38% {
		text-shadow: -2px 0 0 var(--tr-ghost-c), 2px 1px 0 var(--tr-ghost-m);
		animation-timing-function: var(--tr-ease-snap);
	}
	100% { text-shadow: 0 0 0 var(--tr-ghost-c), 0 0 0 var(--tr-ghost-m); }
}

@keyframes tr-row-ink { from { clip-path: inset(0 100% 0 0); } to { clip-path: inset(0 0 0 0); } }
@keyframes tr-tick-ink { from { scale: 1 0; } }

/* Two misregistered rings (cyan, magenta) lock into the focus ring. */
@keyframes tr-focus-register {
	from {
		box-shadow:
			0 0 0 2px var(--tr-color-paper),
			-5px -4px 0 2px var(--tr-ghost-c),
			5px 4px 0 2px var(--tr-ghost-m);
	}
	to {
		box-shadow:
			0 0 0 2px var(--tr-color-paper),
			0 0 0 4px var(--tr-color-focus),
			0 0 0 4px var(--tr-color-focus);
	}
}

/* 404: every plate arrives from far off and stops short of register. */
@keyframes tr-404-k { from { opacity: 0; scale: 0.96; } }
@keyframes tr-404-c { from { opacity: 0; transform: translate(-0.22em, -0.14em) rotate(-4deg); } }
@keyframes tr-404-m { from { opacity: 0; transform: translate(0.2em, 0.16em) rotate(3deg); } }
@keyframes tr-404-y { from { opacity: 0; transform: translate(-0.08em, 0.24em) rotate(-2deg); } }

@keyframes tr-sheet-feed { from { opacity: 0; transform: translateY(-28px) rotate(-3deg); } }

@keyframes tr-read-progress { from { clip-path: inset(0 100% 0 0); } to { clip-path: inset(0 0 0 0); } }
