/**
 * Unodevs — Strata sections. Structure only.
 *
 * The four scroll-driven sections: counterflow, reel, depth, zoomgate.
 * Palette and type belong to whichever style layer is active — these are
 * registered sections and work in any demo, so nothing here hard-codes a
 * colour that is not derived from the theme's own custom properties.
 *
 * Two things this file is responsible for that the script is not:
 *
 *  1. The layout that makes the motion possible at all — the tall wrappers,
 *     the sticky frames, the column padding that stops a sliding column
 *     exposing a gap.
 *
 *  2. The state everything falls back to when the script does not run. Not
 *     "a degraded version": an actual readable section. Under reduced
 *     motion, with JavaScript off, and in print, every one of these is a
 *     plain block of content, which is why none of them is built out of
 *     elements that only make sense once they have been transformed.
 *
 * @package Unodevs
 */


/* ==========================================================================
   1. Counterflow
   --------------------------------------------------------------------------
   Three columns, the middle one travelling upward while the outer two fall.
   ========================================================================== */

.u-flow-section {
	/* The columns slide inside this, and a slid column must never show its
	   own end. */
	overflow: hidden;
}

.u-flow {
	display: grid;
	grid-template-columns: repeat(3, 1fr);
	gap: clamp(14px, 2vw, 28px);
	align-items: start;
	padding-inline: clamp(16px, 4vw, 48px);
}

/*
 * The padding is the trick that makes this work.
 *
 * A column that slides up by 160px would leave 160px of nothing at its
 * bottom edge. Giving every column that much dead space at both ends, and
 * pulling the whole grid back by the same amount, means the movement
 * happens inside space that was already there. Without it the effect is
 * obvious as a hole rather than as motion.
 */
.u-flow-col {
	display: grid;
	gap: clamp(14px, 2vw, 28px);
	padding-block: 180px;
	margin-block: -180px;
}

/* The middle column starts lower so it has room to travel upward before it
   runs out of section. */
.u-flow-col-down {
	padding-top: 260px;
	margin-top: -180px;
}

.u-flow-item {
	display: block;
	border-radius: var(--u-radius);
	overflow: hidden;
	background: var(--u-surface);
	border: 1px solid var(--u-border);
	color: inherit;
	text-decoration: none;
}

.u-flow-media {
	aspect-ratio: 4 / 5;
	background:
		linear-gradient(140deg,
			rgba(var(--u-primary-rgb), 0.16),
			rgba(var(--u-accent-rgb), 0.10));
	overflow: hidden;
}

.u-flow-media img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	display: block;
}

.u-flow-body {
	padding: 14px 16px 18px;
}

.u-flow-body h3 {
	font-size: 1.02rem;
	margin: 0;
}

.u-flow-meta {
	display: block;
	margin-top: 4px;
	font-size: 0.82rem;
	color: var(--u-muted);
}

@media (max-width: 860px) {
	/*
	 * Two columns on a tablet. Not three narrower ones — at this width the
	 * cards become too small for the images to be worth showing, and the
	 * whole point of the section is the images passing each other.
	 */
	.u-flow { grid-template-columns: repeat(2, 1fr); }
	.u-flow-col-down { padding-top: 180px; }
}

@media (max-width: 620px) {
	/*
	 * One column, and the motion goes with it. Two columns sliding past
	 * each other needs two columns; a single column sliding against itself
	 * is just a section that will not sit still.
	 */
	.u-flow {
		grid-template-columns: 1fr;
		padding-inline: 0;
	}

	.u-flow-col,
	.u-flow-col-down {
		padding-block: 0;
		margin-block: 0;
		padding-top: 0;
		margin-top: 0;
		transform: none !important;
	}
}


/* ==========================================================================
   2. Reel
   --------------------------------------------------------------------------
   Copy rolling upward through a sticky frame, driven by the page scrollbar.
   ========================================================================== */

.u-reel {
	/* Set inline by PHP from the number of lines: one screen each, plus one
	   so the last line settles before the section lets go. */
	min-height: var(--u-reel-h, 500vh);
	position: relative;
}

.u-reel-pin {
	position: sticky;
	top: 0;
	min-height: 100vh;
	display: grid;
	align-content: center;
	overflow: hidden;
}

.u-reel-head {
	margin-bottom: clamp(24px, 5vh, 56px);
}

/*
 * The frame. Fixed height, because the script measures it and spaces the
 * lines by it — a frame that grows with its content would mean the spacing
 * changed depending on which line happened to be longest.
 */
.u-reel-frame {
	position: relative;
	height: clamp(180px, 30vh, 280px);

	/* Lines fade out at the edges rather than being clipped. A hard cut
	   makes the roll look like a scrolling div, which is what it is and
	   exactly what it should not look like. */
	-webkit-mask-image: linear-gradient(180deg, transparent, #000 22%, #000 78%, transparent);
	mask-image: linear-gradient(180deg, transparent, #000 22%, #000 78%, transparent);
}

.u-reel-line {
	position: absolute;
	inset: 0;
	display: grid;
	align-content: center;
	gap: 10px;
}

.u-reel-line p {
	margin: 0;
	font-size: clamp(1.5rem, 4vw, 3rem);
	line-height: 1.15;
	max-width: 22ch;
	font-weight: 500;
}

.u-reel-note {
	font-size: 0.72rem;
	letter-spacing: 0.18em;
	text-transform: uppercase;
	color: var(--u-muted);
}

/* A thin progress rail, so the section says how much of itself is left.
   A sticky section with no indication of length is the single most
   complained-about pattern on the web and it costs four rules to fix. */
.u-reel-rail {
	position: absolute;
	right: clamp(16px, 4vw, 40px);
	top: 22%;
	bottom: 22%;
	width: 2px;
	background: var(--u-border);
	border-radius: 2px;
}

.u-reel-bead {
	display: block;
	width: 100%;
	height: 100%;
	background: var(--u-primary);
	border-radius: inherit;
	transform-origin: top center;
	transform: scaleY(0);
}

@media (max-width: 620px) {
	.u-reel-rail { display: none; }
}


/* ==========================================================================
   3. Depth
   --------------------------------------------------------------------------
   Planes moving at different rates behind one headline.
   ========================================================================== */

.u-depth {
	position: relative;
	overflow: hidden;
	padding-block: clamp(90px, 16vh, 200px);
	isolation: isolate;
}

.u-depth-field {
	position: absolute;
	inset: -20% 0;
	z-index: -1;
	pointer-events: none;
}

/*
 * The planes are soft shapes rather than pictures on purpose: an image at
 * four different depths needs four images, all correctly sized, or the
 * effect looks like a slideshow that failed. Gradients cost nothing, scale
 * to any screen, and take the site's own palette, so the depth field is the
 * right colour in every demo without anybody uploading anything.
 */
.u-depth-plane {
	position: absolute;
	border-radius: 50%;
	filter: blur(2px);
}

.u-depth-p1 {
	width: 46vmax; height: 46vmax;
	top: 4%; left: -10%;
	background: radial-gradient(circle, rgba(var(--u-primary-rgb), 0.14), transparent 62%);
}

.u-depth-p2 {
	width: 34vmax; height: 34vmax;
	top: 32%; right: -8%;
	background: radial-gradient(circle, rgba(var(--u-accent-rgb), 0.16), transparent 64%);
}

.u-depth-p3 {
	width: 20vmax; height: 20vmax;
	bottom: 6%; left: 22%;
	background: radial-gradient(circle, rgba(var(--u-primary-rgb), 0.12), transparent 60%);
}

.u-depth-p4 {
	width: 12vmax; height: 12vmax;
	top: 12%; left: 58%;
	background: radial-gradient(circle, rgba(var(--u-accent-rgb), 0.20), transparent 58%);
}

.u-depth-head {
	max-width: 34ch;
	margin-bottom: clamp(36px, 6vh, 72px);
}

.u-depth-list {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
	gap: clamp(20px, 3vw, 44px);
}

.u-depth-item h3 {
	font-size: 1.1rem;
	margin: 0 0 6px;
}

.u-depth-item p {
	margin: 0;
	color: var(--u-muted);
	max-width: 34ch;
}

/*
 * A hairline above each item, so the list reads as an index rather than as
 * four floating paragraphs. It also gives the differing plane rates
 * something to be measured against — without a fixed reference the
 * different speeds are much harder to perceive.
 */
.u-depth-item {
	padding-top: 16px;
	border-top: 1px solid var(--u-border);
}


/* ==========================================================================
   4. Zoom gate
   --------------------------------------------------------------------------
   A shape that grows until the page passes through it.
   ========================================================================== */

.u-gate {
	min-height: 260vh;
	position: relative;
}

.u-gate-pin {
	position: sticky;
	top: 0;
	height: 100vh;
	display: grid;
	place-items: center;
	overflow: hidden;
	isolation: isolate;
}

/*
 * The shape.
 *
 * Sized in px rather than a percentage because the script divides the
 * viewport diagonal by this number to work out how far it has to scale. A
 * percentage would change with the viewport and the scale factor would have
 * to be recomputed on every resize for no benefit.
 */
.u-gate-shape {
	position: absolute;
	width: 120px;
	height: 120px;
	border-radius: 50%;
	background: var(--u-primary);
	z-index: -1;
	transform: scale(1);
}

.u-gate-before,
.u-gate-after {
	grid-area: 1 / 1;
	text-align: center;
	position: relative;
}

.u-gate-after {
	/*
	 * Sits on the fully-grown shape, so it needs the colour that is legible
	 * against the primary rather than the page's own ink.
	 *
	 * --u-on-primary is the theme-wide answer to "what text goes on the
	 * accent". White is right for most palettes and wrong for the bright
	 * ones — Kinetic's orange and Playful's coral both fail contrast with
	 * white — so those layers set it to their ink, exactly as they already
	 * do for --btn-fg. Anything reading this variable stays correct when a
	 * palette changes.
	 */
	color: var(--u-on-primary, #fff);
	opacity: 0;
}

.u-gate-after .u-display {
	font-size: clamp(2rem, 6vw, 4.5rem);
	margin: 0 0 0.4em;
	color: inherit;
}

.u-gate-after .u-lead {
	margin-inline: auto;
	max-width: 46ch;
	color: inherit;
	opacity: 0.86;
}

.u-gate-after .u-btn-primary {
	margin-top: 1.6rem;
	--btn-bg: var(--u-surface);
	--btn-fg: var(--u-text);
}


/* ==========================================================================
   5. When the motion is switched off
   --------------------------------------------------------------------------
   Not a fallback, a second design. Everything below is what these four
   sections are for a visitor who has asked for reduced motion, has
   JavaScript off, or is printing — and all three have to be genuinely
   readable, not a broken version of the animated one.
   ========================================================================== */

@media (prefers-reduced-motion: reduce) {
	/* Unpin. A sticky frame with no motion to justify it is a section that
	   refuses to scroll. */
	.u-reel,
	.u-gate {
		min-height: 0;
	}

	.u-reel-pin,
	.u-gate-pin {
		position: static;
		height: auto;
		min-height: 0;
		padding-block: clamp(60px, 10vh, 110px);
	}

	/* The reel becomes an ordinary list of statements. */
	.u-reel-frame {
		height: auto;
		display: grid;
		gap: clamp(20px, 4vh, 40px);
		-webkit-mask-image: none;
		mask-image: none;
	}

	.u-reel-line {
		position: static;
		inset: auto;
		opacity: 1 !important;
		transform: none !important;
	}

	.u-reel-line p {
		font-size: clamp(1.2rem, 2.4vw, 1.7rem);
		max-width: 40ch;
	}

	.u-reel-rail { display: none; }

	/* The gate stops being a gate: both blocks show, stacked, and the shape
	   goes. Half a grown circle behind static text is meaningless. */
	.u-gate-pin {
		display: grid;
		place-items: start;
		gap: clamp(20px, 4vh, 40px);
	}

	.u-gate-before,
	.u-gate-after {
		grid-area: auto;
		opacity: 1 !important;
		transform: none !important;
		pointer-events: auto !important;
	}

	.u-gate-after {
		color: inherit;
		background: var(--u-primary);
		color: var(--u-on-primary, #fff);
		border-radius: var(--u-radius-lg);
		padding: clamp(28px, 5vw, 56px);
	}

	.u-gate-shape { display: none; }

	/* Columns and planes simply stop moving. */
	.u-flow-col,
	.u-depth-plane,
	.u-depth-head,
	.u-depth-item {
		transform: none !important;
	}

	.u-flow-col,
	.u-flow-col-down {
		padding-block: 0;
		margin-block: 0;
		padding-top: 0;
		margin-top: 0;
	}
}

@media print {
	.u-reel,
	.u-gate { min-height: 0; }

	.u-reel-pin,
	.u-gate-pin {
		position: static;
		height: auto;
		min-height: 0;
	}

	.u-reel-frame {
		height: auto;
		display: grid;
		gap: 12px;
		-webkit-mask-image: none;
		mask-image: none;
	}

	.u-reel-line {
		position: static;
		opacity: 1 !important;
		transform: none !important;
	}

	.u-gate-before,
	.u-gate-after {
		grid-area: auto;
		opacity: 1 !important;
		transform: none !important;
	}

	.u-gate-shape,
	.u-depth-field,
	.u-reel-rail { display: none; }

	.u-flow-col {
		padding-block: 0;
		margin-block: 0;
		transform: none !important;
	}
}
