/* ============================================================
   IT-RANKS — page transition: the 2-half curtain.

   Leaving a page:  two panels slide in from the top and bottom edges and meet
                    in the middle, the IT-RANKS mark forms out of dots on top
                    of them, then the browser navigates.
   Arriving:        the panels are already closed and part again.

   The bottom half trails the top by --itr-pt-lag so the two edges do not meet
   dead flat — that offset is what makes it read as a curtain rather than a wipe.

   Recovered verbatim from the approved 2026-05-02 revision. Timings and easing
   are the ones that were signed off; tune here, nowhere else.
   ============================================================ */

.itr-pt {
	--itr-pt-bg: #020a18;
	--itr-pt-ease-close: cubic-bezier(0.16, 1, 0.3, 1);
	--itr-pt-ease-open:  cubic-bezier(0.5, 0, 0.75, 0);
	--itr-pt-half:  580ms;
	--itr-pt-lag:   100ms;
	--itr-pt-total: 680ms;

	position: fixed;
	inset: 0;
	z-index: 2147483000;
	background: transparent;
	display: flex;
	align-items: center;
	justify-content: center;
	visibility: hidden;
	pointer-events: none;
}

.itr-pt__curtain {
	position: absolute;
	left: 0;
	right: 0;
	/* Overlap by 1px each. At a fractional device-pixel ratio a flat 50% puts
	   the meeting edge on a half device pixel (measured: 711.5 / 788.5 / 636.5
	   at dpr 1.75), so the shared row is antialiased to ~50% coverage by each
	   panel and a bright seam flashes across the middle just as they meet.
	   Overlapping removes the shared boundary entirely. */
	height: calc(50% + 1px);
	background: var(--itr-pt-bg);
	will-change: transform;
}

.itr-pt__curtain--top    { top: 0;    transform: translateY(-100%); }
.itr-pt__curtain--bottom { bottom: 0; transform: translateY(100%); }

/* ── Arrival: panels are closed on paint and part ────────────────────── */

.itr-pt.is-enter {
	visibility: visible;
	animation: itr-pt-hide-after var(--itr-pt-total) linear forwards;
}

.itr-pt.is-enter .itr-pt__curtain--top {
	animation: itr-pt-open-top var(--itr-pt-half) var(--itr-pt-ease-open) both;
}

.itr-pt.is-enter .itr-pt__curtain--bottom {
	animation: itr-pt-open-bottom var(--itr-pt-half) var(--itr-pt-ease-open) var(--itr-pt-lag) both;
}

@keyframes itr-pt-open-top    { from { transform: translateY(0); } to { transform: translateY(-100%); } }
@keyframes itr-pt-open-bottom { from { transform: translateY(0); } to { transform: translateY(100%);  } }
@keyframes itr-pt-hide-after  { from, 99% { visibility: visible; } to { visibility: hidden; } }

/* Hold the curtain shut until the document is ready to be looked at.
   The opening is a CSS animation, so it starts as soon as the overlay is
   parsed — which on this site is ~680ms, while DOMContentLoaded lands around
   2.9s. Left alone the curtain parts over a page that has not painted yet and
   the blank frame reads as a flash. The inline bootstrap in markup() adds
   is-held immediately and drops it on DOMContentLoaded (or a hard cap), so the
   animation simply waits at frame 0 — curtain closed — until there is
   something behind it. Pausing rather than delaying keeps the pure-CSS
   fallback: if the script never runs, the curtain still opens on its own. */
.itr-pt.is-held,
.itr-pt.is-held .itr-pt__curtain--top,
.itr-pt.is-held .itr-pt__curtain--bottom {
	animation-play-state: paused;
}

/* ── Exit: JS arms, then closes ──────────────────────────────────────── */

.itr-pt.is-out {
	animation: none;
	visibility: visible;
	pointer-events: all;
}

.itr-pt.is-out .itr-pt__curtain--top {
	transform: translateY(0);
	transition: transform var(--itr-pt-half) var(--itr-pt-ease-close);
}

.itr-pt.is-out .itr-pt__curtain--bottom {
	transform: translateY(0);
	transition: transform var(--itr-pt-half) var(--itr-pt-ease-close) var(--itr-pt-lag);
}

/* Set one frame before .is-out so the transition has a start value to move
   from — without this the panels would jump straight to closed. */
.itr-pt.is-arming {
	animation: none;
	visibility: visible;
	pointer-events: none;
}

.itr-pt.is-arming .itr-pt__curtain--top {
	transform: translateY(-100%);
	transition: transform var(--itr-pt-half) var(--itr-pt-ease-close);
}

.itr-pt.is-arming .itr-pt__curtain--bottom {
	transform: translateY(100%);
	transition: transform var(--itr-pt-half) var(--itr-pt-ease-close) var(--itr-pt-lag);
}

/* Killed outright — bfcache restore, reduced motion, or the safety timeout. */
.itr-pt.is-off {
	animation: none !important;
	visibility: hidden !important;
	pointer-events: none !important;
	transition: none !important;
}

.itr-pt.is-off .itr-pt__curtain--top    { transform: translateY(-100%) !important; }
.itr-pt.is-off .itr-pt__curtain--bottom { transform: translateY(100%)  !important; }

/* ── The dot mark, above the closed curtain ──────────────────────────── */

.itr-pt__mark {
	position: relative;
	/* Matches main-logo.png (812x1139) so the dots fill the box. 300px wide is
	   the point where the "TECHNOLOGY" sub-line still resolves as dots. */
	width: min(62vw, 300px);
	aspect-ratio: 812 / 1139;
	opacity: 0;
	transition: opacity 200ms ease;
	z-index: 10;
}

.itr-pt__mark.is-live { opacity: 1; }

/* Source artwork — read by the sampler, never shown. */
.itr-pt__src {
	position: absolute;
	inset: 0;
	display: flex;
	align-items: center;
	justify-content: center;
	color: #ffffff;
	visibility: hidden;
}

.itr-pt__src svg,
.itr-pt__src img { width: 80%; height: 80%; object-fit: contain; }

.itr-pt__canvas { display: block; width: 100%; height: 100%; }

/* ── Reduced motion: a short curtain, no dots ────────────────────────── */
@media (prefers-reduced-motion: reduce) {
	.itr-pt { --itr-pt-half: 160ms; --itr-pt-lag: 0ms; --itr-pt-total: 160ms; }
	.itr-pt__mark { display: none; }
}

/* Never cover the Elementor editor canvas. */
.elementor-editor-active .itr-pt,
.elementor-editor-preview .itr-pt { display: none !important; }
