/* =========================================================================
   Hero text overlay
   Separate from app.css because the slide editor's live preview loads this
   same file — one source, so the preview cannot drift from the homepage.
   Loaded on the front page only.

   Layout reads data attributes written by pt_hero_overlay_html():
     data-v / data-h   desktop position (top|middle|bottom, left|center|right)
     data-mv / data-mh phone position   (own row and column)
     data-align        text alignment   (left|center|right)
     data-malign       phone alignment  (left|center|right)
     data-tone         light | dark     (text colour)
     data-scrim        none | soft | strong

   Breakpoints are container queries on the overlay, not media queries, so the
   editor's 390px phone preview gets the real phone rules. On the homepage the
   overlay spans the window, so the two behave identically. Sizes use cqi/cqb
   (1% of the overlay's width/height) for the same reason. Colours fall back to
   literals because the editor has none of the theme's tokens.

   Height matters as much as width: a slide with no phone artwork shows its
   wide banner on a phone as a ~220px strip, and a 16:6 banner on a tablet is
   ~290px tall. Short overlays shrink the heading and drop the supporting line,
   then the label, rather than spill over the edges and the slide dots.
   ========================================================================= */

.pt-hero__overlay {
	/* size, not inline-size: the height queries below need the block axis. */
	container: pt-hero-overlay / size;
	position: absolute;
	inset: 0;
	/* Clicks fall through to the slide's link underneath. */
	pointer-events: none;
	font-family: 'Archivo', system-ui, -apple-system, 'Segoe UI', sans-serif;
	-webkit-font-smoothing: antialiased;
}

/* ------------------------------------------------------------------ scrim */

.pt-hero__scrim {
	--pt-ov-rgb: 18 14 11;
	--pt-ov-a: 0.46;
	--pt-ov-0: rgb(var(--pt-ov-rgb) / var(--pt-ov-a));
	--pt-ov-1: rgb(var(--pt-ov-rgb) / calc(var(--pt-ov-a) * 0.55));
	position: absolute;
	inset: 0;
}

[data-tone='dark'] > .pt-hero__scrim { --pt-ov-rgb: 246 246 243; --pt-ov-a: 0.62; }
[data-scrim='strong'] > .pt-hero__scrim { --pt-ov-a: 0.7; }
[data-tone='dark'][data-scrim='strong'] > .pt-hero__scrim { --pt-ov-a: 0.84; }
[data-scrim='none'] > .pt-hero__scrim { display: none; }

/* Shaded from the side the text sits on, fading out across the picture. */
[data-h='left'] > .pt-hero__scrim {
	background: linear-gradient(90deg, var(--pt-ov-0) 0%, var(--pt-ov-1) 34%, transparent 70%);
}
[data-h='right'] > .pt-hero__scrim {
	background: linear-gradient(270deg, var(--pt-ov-0) 0%, var(--pt-ov-1) 34%, transparent 70%);
}
[data-h='center'][data-v='top'] > .pt-hero__scrim {
	background: linear-gradient(180deg, var(--pt-ov-0) 0%, var(--pt-ov-1) 32%, transparent 66%);
}
[data-h='center'][data-v='bottom'] > .pt-hero__scrim {
	background: linear-gradient(0deg, var(--pt-ov-0) 0%, var(--pt-ov-1) 32%, transparent 66%);
}
[data-h='center'][data-v='middle'] > .pt-hero__scrim {
	background: radial-gradient(ellipse 58% 64% at 50% 50%, var(--pt-ov-0) 0%, var(--pt-ov-1) 48%, transparent 100%);
}

/* ------------------------------------------------------------------ frame */

/*
 * Lined up with the site's content width, so a left-aligned heading starts
 * where the sections below start. Padded clear of the arrows at the sides and
 * the dots at the bottom centre.
 */
.pt-hero__frame {
	--pt-ov-gutter: clamp(1rem, 3.5cqi, 3rem);
	position: relative;
	box-sizing: border-box;
	display: grid;
	grid-template-columns: minmax(0, 1fr);
	width: min(100% - max(var(--pt-ov-gutter), 5.25rem) * 2, 1400px);
	height: 100%;
	margin-inline: auto;
	padding-block: clamp(1.5rem, 4.5cqi, 4rem) clamp(4rem, 5.5cqi, 5rem);
}

[data-v='top'] > .pt-hero__frame { align-content: start; }
[data-v='middle'] > .pt-hero__frame { align-content: center; }
[data-v='bottom'] > .pt-hero__frame { align-content: end; }

[data-h='left'] > .pt-hero__frame { justify-items: start; }
[data-h='center'] > .pt-hero__frame { justify-items: center; }
[data-h='right'] > .pt-hero__frame { justify-items: end; }

/* ------------------------------------------------------------------- copy */

.pt-hero__copy {
	max-width: min(40rem, 100%);
	color: #fff;
}

[data-h='center'] .pt-hero__copy { max-width: min(48rem, 100%); }

[data-align='left'] .pt-hero__copy { text-align: left; }
[data-align='center'] .pt-hero__copy { text-align: center; }
[data-align='right'] .pt-hero__copy { text-align: right; }

.pt-hero__eyebrow {
	margin: 0 0 0.9rem;
	font-size: clamp(0.72rem, 0.6rem + 0.35cqi, 0.875rem);
	font-weight: 600;
	letter-spacing: 0.16em;
	line-height: 1.3;
	text-transform: uppercase;
	opacity: 0.92;
}

.pt-hero__heading {
	margin: 0;
	/* Grows with width, capped by height so two lines always fit the frame. */
	font-size: clamp(1.25rem, min(1rem + 3.4cqi, 11cqb), 4.25rem);
	font-weight: 650;
	line-height: 1.04;
	letter-spacing: -0.025em;
	text-wrap: balance;
	color: inherit;
}

.pt-hero__text {
	max-width: 34rem;
	margin: 1rem 0 0;
	font-size: clamp(0.95rem, 0.85rem + 0.35cqi, 1.2rem);
	line-height: 1.5;
	white-space: pre-line;
	text-wrap: pretty;
}

[data-align='center'] .pt-hero__text { margin-inline: auto; }
[data-align='right'] .pt-hero__text { margin-left: auto; }

/* Light text keeps a soft shadow as a second line of defence when the
   shading is off or the picture is busy. */
[data-tone='light'] :is(.pt-hero__eyebrow, .pt-hero__heading, .pt-hero__text) {
	text-shadow: 0 1px 2px rgb(0 0 0 / 0.16), 0 2px 18px rgb(0 0 0 / 0.2);
}

[data-tone='dark'] .pt-hero__copy { color: var(--pt-ink, #221d19); }
[data-tone='dark'] .pt-hero__eyebrow { color: var(--pt-bronze-deep, #86582e); opacity: 1; }

/* ----------------------------------------------------------------- button */

.pt-hero__cta {
	display: inline-flex;
	align-items: center;
	gap: 0.5rem;
	margin-top: clamp(1.25rem, 1rem + 0.8cqi, 1.75rem);
	padding: 0.85rem 1.5rem;
	border-radius: 999px;
	font-size: 0.875rem;
	font-weight: 600;
	letter-spacing: -0.012em;
	line-height: 1;
	background: #fff;
	color: var(--pt-ink, #221d19);
	transition:
		background-color 160ms cubic-bezier(0.22, 1, 0.36, 1),
		color 160ms cubic-bezier(0.22, 1, 0.36, 1);
}

.pt-hero__cta svg {
	width: 16px;
	height: 16px;
	flex: none;
	transition: translate 160ms cubic-bezier(0.22, 1, 0.36, 1);
}

[data-tone='dark'] .pt-hero__cta {
	background: var(--pt-ink, #221d19);
	color: var(--pt-paper, #f6f6f3);
}

/* The button is a picture of a button; the link is the whole slide. */
.pt-hero__link:is(:hover, :focus-visible) .pt-hero__cta {
	background: var(--pt-bronze-deep, #86582e);
	color: #fff;
}

.pt-hero__link:is(:hover, :focus-visible) .pt-hero__cta svg { translate: 3px 0; }

/* ------------------------------------------------------------------ phone */

@container pt-hero-overlay (max-width: 767.98px) {
	/*
	 * Phones have their own position (data-mv / data-mh) and alignment
	 * (data-malign). Every phone selector below is written one step heavier
	 * than its desktop counterpart — `.pt-hero__overlay[...]` — because a
	 * container query adds no specificity: at equal weight the desktop rule
	 * won, which is how a left desktop position kept phone text pinned left
	 * even with the phone set to centre.
	 */
	.pt-hero__frame {
		width: calc(100% - var(--pt-ov-gutter) * 2);
		/* Scales with the banner's height; ~40px / ~68px on a 4:5 phone
		   banner, the bottom keeping clear air above the slide dots. */
		padding-block: clamp(2.25rem, 8cqb, 3.5rem) clamp(4.25rem, 13cqb, 5.5rem);
	}

	.pt-hero__overlay[data-mv='top'] > .pt-hero__frame { align-content: start; }
	.pt-hero__overlay[data-mv='middle'] > .pt-hero__frame { align-content: center; }
	.pt-hero__overlay[data-mv='bottom'] > .pt-hero__frame { align-content: end; }

	.pt-hero__overlay[data-mh='left'] > .pt-hero__frame { justify-items: start; }
	.pt-hero__overlay[data-mh='center'] > .pt-hero__frame { justify-items: center; }
	.pt-hero__overlay[data-mh='right'] > .pt-hero__frame { justify-items: end; }

	/* The block is as wide as its longest line, up to the full width, so a
	   short heading really does sit in the chosen column. */
	.pt-hero__overlay[data-h] .pt-hero__copy { max-width: 100%; }

	.pt-hero__overlay[data-malign='left'] .pt-hero__copy { text-align: left; }
	.pt-hero__overlay[data-malign='center'] .pt-hero__copy { text-align: center; }
	.pt-hero__overlay[data-malign='right'] .pt-hero__copy { text-align: right; }

	.pt-hero__overlay[data-malign] .pt-hero__text { margin-inline: 0; }
	.pt-hero__overlay[data-malign='center'] .pt-hero__text { margin-inline: auto; }
	.pt-hero__overlay[data-malign='right'] .pt-hero__text { margin-left: auto; }

	.pt-hero__eyebrow { margin-bottom: 0.65rem; }
	.pt-hero__heading { font-size: min(1.85rem, max(1.25rem, 9cqb)); }
	.pt-hero__text { margin-top: 0.7rem; }

	/* A phone is narrow, so shade by row rather than by side. Heavier than
	   the desktop `[data-h][data-v]` shapes (0,3,0). */
	.pt-hero__overlay[data-mv='top'][data-mh] > .pt-hero__scrim {
		background: linear-gradient(180deg, var(--pt-ov-0) 0%, var(--pt-ov-1) 36%, transparent 70%);
	}
	.pt-hero__overlay[data-mv='bottom'][data-mh] > .pt-hero__scrim {
		background: linear-gradient(0deg, var(--pt-ov-0) 0%, var(--pt-ov-1) 36%, transparent 70%);
	}
	.pt-hero__overlay[data-mv='middle'][data-mh] > .pt-hero__scrim {
		background: radial-gradient(ellipse 95% 55% at 50% 50%, var(--pt-ov-0) 0%, var(--pt-ov-1) 50%, transparent 100%);
	}
}

/*
 * The arrows switch on at a 768px *viewport*; this overlay measures the hero,
 * which is narrower by the scrollbar. Between the two the phone layout would
 * run with the arrows showing and the text under the left one (seen at 768px:
 * text at 26px, arrow to 60px). No phone is this wide, so keep arrow clearance.
 */
@container pt-hero-overlay (min-width: 640px) and (max-width: 767.98px) {
	.pt-hero__frame { width: calc(100% - 5.25rem * 2); }
}

/* ---------------------------------------------------------- short frames */

@container pt-hero-overlay (max-height: 420px) {
	.pt-hero__frame { padding-block: 0.9rem 3rem; }
	.pt-hero__text { display: none; }
	.pt-hero__eyebrow { margin-bottom: 0.5rem; }
	.pt-hero__cta { margin-top: 0.85rem; padding: 0.7rem 1.2rem; font-size: 0.8125rem; }
}

@container pt-hero-overlay (max-height: 300px) {
	.pt-hero__eyebrow { display: none; }
}

/* -------------------------------------------------------------- entrance */

/*
 * The slider marks off-screen slides `inert`, so the words rise in as their
 * slide becomes current — no script. The first slide is never inert on load,
 * so it paints immediately rather than fading in (it is the page's largest
 * element, and a fade would hold back first paint).
 */
.pt-hero__copy > * {
	transition:
		opacity 520ms cubic-bezier(0.22, 1, 0.36, 1),
		translate 640ms cubic-bezier(0.22, 1, 0.36, 1);
}

.pt-hero__copy > :nth-child(1) { transition-delay: 180ms; }
.pt-hero__copy > :nth-child(2) { transition-delay: 250ms; }
.pt-hero__copy > :nth-child(3) { transition-delay: 320ms; }
.pt-hero__copy > :nth-child(4) { transition-delay: 390ms; }

.pt-hero__slide[inert] .pt-hero__copy > * {
	opacity: 0;
	translate: 0 14px;
	transition-duration: 240ms, 0s;
	transition-delay: 0s, 240ms;
}

@media (prefers-reduced-motion: reduce) {
	.pt-hero__copy > *,
	.pt-hero__slide[inert] .pt-hero__copy > * {
		translate: none;
		transition: opacity 200ms linear;
	}
}
