/* ==========================================================================
   IPTV Espana — base layer
   Motion is CSS-only and load-driven, never scroll/JS-gated: a reveal that
   depends on a listener can leave indexable text at opacity 0 if it never
   fires. Every animation here completes on its own.
   ========================================================================== */

*, *::before, *::after { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }

body {
	margin: 0;
	background: var(--c-bg);
	color: var(--c-text);
	font-family: var(--font-sans);
	font-size: var(--t-base);
	line-height: var(--lh-normal);
	font-synthesis-weight: none;
	-webkit-font-smoothing: antialiased;
	text-rendering: optimizeLegibility;
	overflow-x: hidden;
}

h1, h2, h3, h4 {
	margin: 0 0 var(--s-4);
	text-wrap: balance;
}

/* Chapter level — the display face, set in caps. Accented Spanish capitals
   (Á É Í Ó Ú) rise above the cap line, so leading is 1.12 rather than the
   1.06 a Latin-only headline could take; below that they collide with the
   descenders of the line above. */
h1, h2 {
	font-family: var(--font-display);
	font-weight: 400;
	font-style: normal;
	text-transform: uppercase;
	letter-spacing: var(--ls-display);
	line-height: 1.12;
}
/* Italic phrases inside a headline are the one permitted accent. */
h1 em, h2 em, .display em { font-style: italic; font-weight: 400; }

/* Sub-structure stays in the body face — readable at length. */
h3, h4 {
	font-family: var(--font-sans);
	font-weight: 700;
	letter-spacing: -0.015em;
	line-height: var(--lh-snug);
}

h1 { font-size: var(--t-3xl); }
h2 { font-size: var(--t-2xl); }
h3 { font-size: var(--t-xl); }
h4 { font-size: var(--t-lg); }

p { margin: 0 0 var(--s-4); max-width: var(--measure); text-wrap: pretty; }

a { color: var(--c-accent-lo); text-decoration-thickness: 1px; text-underline-offset: 3px; }
a:hover { color: var(--c-accent); }

img, svg, video { max-width: 100%; height: auto; display: block; }

:focus-visible {
	outline: 2px solid var(--c-accent);
	outline-offset: 3px;
	border-radius: var(--r-sm);
}

.skip-link {
	position: absolute; left: -9999px;
	background: var(--c-accent); color: var(--c-accent-ink);
	padding: var(--s-3) var(--s-4); border-radius: var(--r-md);
	font-weight: 600; z-index: calc(var(--z-modal) + 1);
}
.skip-link:focus { left: var(--s-4); top: var(--s-4); }

.visually-hidden {
	position: absolute; width: 1px; height: 1px;
	padding: 0; margin: -1px; overflow: hidden;
	clip-path: inset(50%); white-space: nowrap; border: 0;
}

/* ---- Layout ------------------------------------------------------------ */

.wrap {
	width: 100%;
	max-width: var(--maxw);
	margin-inline: auto;
	padding-inline: var(--gutter);
}

.section { padding-block: var(--section-y); }

/* Asymmetric by default — the content column is offset, not centred. */
.split {
	display: grid;
	gap: var(--s-7);
	grid-template-columns: 1fr;
	align-items: center;
}
@media (min-width: 900px) {
	.split { grid-template-columns: 1.15fr 0.85fr; gap: var(--s-8); }
	.split--reverse > :first-child { order: 2; }
}

.stack > * + * { margin-top: var(--s-4); }

/* ---- Buttons ----------------------------------------------------------- */

.btn {
	display: inline-flex; align-items: center; justify-content: center;
	gap: var(--s-2);
	padding: 0.85em 1.6em;
	border: 1px solid transparent;
	border-radius: var(--r-full);
	font: inherit;
	font-weight: 600;
	font-size: var(--t-sm);
	letter-spacing: -0.01em;
	text-decoration: none;
	cursor: pointer;
	transition: transform var(--d-fast) var(--ease),
	            background-color var(--d-fast) var(--ease),
	            border-color var(--d-fast) var(--ease);
}
.btn:active { transform: translateY(1px) scale(0.985); }

.btn--primary {
	background: var(--c-accent);
	color: var(--c-accent-ink);
	box-shadow: var(--e-inset);
}
.btn--primary:hover { background: var(--c-accent-hi); color: var(--c-accent-ink); }

.btn--ghost {
	background: transparent;
	color: var(--c-text);
	border-color: var(--c-border-str);
}
.btn--ghost:hover { background: var(--c-surface-2); color: var(--c-text); }

/* ---- Stats band -------------------------------------------------------- */

.stats {
	display: grid;
	grid-template-columns: repeat(2, 1fr);
	gap: var(--s-5) var(--s-4);
	margin: 0; padding: 0;
	list-style: none;
}
@media (min-width: 720px) { .stats { grid-template-columns: repeat(4, 1fr); } }

/* Grouped by rule, not boxed in cards. */
.stats__item {
	display: flex; flex-direction: column; gap: var(--s-1);
	padding-left: var(--s-4);
	border-left: 1px solid var(--c-border);
	animation: rise var(--d-slow) var(--ease) both;
	animation-delay: calc(var(--i, 0) * 70ms);
}

.stats__value {
	font-size: var(--t-xl);
	font-weight: 700;
	letter-spacing: -0.04em;
	font-variant-numeric: tabular-nums;
	color: var(--c-text);
}
.stats__label {
	font-size: var(--t-xs);
	text-transform: uppercase;
	letter-spacing: 0.1em;
	color: var(--c-text-faint);
}

@keyframes rise {
	from { opacity: 0; transform: translateY(10px); }
	to   { opacity: 1; transform: none; }
}

/* ---- Header / footer --------------------------------------------------- */

.site-header {
	position: sticky; top: 0; z-index: var(--z-nav);
	/* containing block for the mobile panel */
	background: color-mix(in srgb, var(--c-bg) 88%, transparent);
	backdrop-filter: blur(14px);
	border-bottom: 1px solid var(--c-border);
}
.site-header__inner {
	display: flex; align-items: center; justify-content: space-between;
	gap: var(--s-5);
	min-height: 68px;
}

.brand {
	font-family: var(--font-display);
	font-weight: 400; font-size: calc(var(--t-lg) * 1.15);
	text-transform: uppercase;
	letter-spacing: var(--ls-display);
	color: var(--c-text); text-decoration: none;
	white-space: nowrap;
}
/* 24px counts as large text (needs 3:1) but #FF4A1F measured 2.92 — just under.
   The darker accent clears it without changing the wordmark's character. */
.brand span { color: var(--c-accent-lo); }

.nav ul {
	display: flex; align-items: center; gap: var(--s-5);
	margin: 0; padding: 0; list-style: none;
}
.nav a {
	color: var(--c-text-muted);
	text-decoration: none;
	font-size: var(--t-sm);
	font-weight: 500;
	transition: color var(--d-fast) var(--ease);
}
.nav a:hover, .nav .current-menu-item > a { color: var(--c-text); }

/* Seven mono, uppercase nav labels are materially wider than the sans ones
   they replaced: at exactly 900px the row ran 7px past the viewport. The
   desktop nav now waits for 1024px. Only the HEADER breakpoints move —
   every other 900px rule is layout and stays put. */
@media (max-width: 1023px) { .nav { display: none; } }

.site-footer {
	border-top: 1px solid var(--c-border);
	padding-block: var(--s-8) var(--s-6);
	color: var(--c-text-muted);
	font-size: var(--t-sm);
}
.footer-grid {
	display: grid; gap: var(--s-6);
	grid-template-columns: 1fr;
}
@media (min-width: 720px)  { .footer-grid { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1040px) { .footer-grid { grid-template-columns: 1.5fr 1fr 1fr 1fr; } }

/* Spanning tracks that do not exist at this breakpoint creates an implicit
   column and scrolls the whole page sideways. Span only where the grid is wide. */
.footer-col--wide { grid-column: auto; }
@media (min-width: 720px)  { .footer-col--wide { grid-column: span 2; } }

.footer-col h2 {
	font-size: var(--t-xs);
	text-transform: uppercase;
	letter-spacing: 0.1em;
	color: var(--c-text-faint);
	margin-bottom: var(--s-3);
}
.footer-col ul { margin: 0; padding: 0; list-style: none; }
.footer-col li + li { margin-top: var(--s-2); }
.footer-col a { color: var(--c-text-muted); text-decoration: none; }
.footer-col a:hover { color: var(--c-text); }



.colophon {
	margin-top: var(--s-7);
	padding-top: var(--s-5);
	border-top: 1px solid var(--c-border);
	display: flex; flex-wrap: wrap; gap: var(--s-4);
	justify-content: space-between;
	font-size: var(--t-xs);
	color: var(--c-text-faint);
}

/* ---- Prose ------------------------------------------------------------- */

.prose { max-width: none; }
.prose > * + * { margin-top: var(--s-4); }

/* Text is held to a readable measure; block components (pricing matrix, wide
   tables) span the full container instead of inheriting the prose width. */
.prose > p,
.prose > ul:not([class]),
.prose > ol:not([class]),
.prose > h2,
.prose > h3,
.prose > h4,
.prose > blockquote { max-width: var(--maxw-text); }
.prose h2 { margin-top: var(--s-7); }
.prose h3 { margin-top: var(--s-6); }
/* Editorial lists only. Component lists (.tier-nav, .stats, .plan-grid)
   carry a class and must not inherit prose list spacing — the
   li+li margin leaks into flex rows and knocks the first item out of line. */
.prose :is(ul, ol):not([class]) { padding-left: var(--s-5); }
.prose :is(ul, ol):not([class]) li + li { margin-top: var(--s-2); }

.prose table { width: 100%; border-collapse: collapse; font-size: var(--t-sm); }
.prose th, .prose td {
	text-align: left; padding: var(--s-3);
	border-bottom: 1px solid var(--c-border);
}
.prose th { color: var(--c-text-faint); font-weight: 600; font-size: var(--t-xs);
            text-transform: uppercase; letter-spacing: 0.08em; }

/* Wide content scrolls inside its own box; the page body never scrolls sideways. */
.scroll-x { overflow-x: auto; -webkit-overflow-scrolling: touch; }

/* ---- States ------------------------------------------------------------ */

.notice {
	padding: var(--s-4);
	border: 1px solid var(--c-border);
	border-left-width: 3px;
	border-radius: var(--r-md);
	background: var(--c-surface);
}
.notice--error { border-left-color: var(--c-err); }
.notice--ok    { border-left-color: var(--c-ok); }

.empty {
	padding: var(--s-8) var(--s-5);
	text-align: center;
	color: var(--c-text-muted);
	border: 1px dashed var(--c-border);
	border-radius: var(--r-lg);
}


/* ---- Mobile navigation -------------------------------------------------
   Native <details> disclosure: no JavaScript, keyboard accessible, and the
   links are in the DOM for crawlers whether or not it is open.
   ------------------------------------------------------------------------ */

.nav-toggle { display: none; }

@media (max-width: 1023px) {
	.nav-toggle { display: block; }

	.nav-toggle > summary {
		list-style: none;
		cursor: pointer;
		display: inline-flex;
		align-items: center;
		gap: var(--s-2);
		padding: var(--s-2) var(--s-3);
		border: 1px solid var(--c-border-str);
		border-radius: var(--r-full);
		font-size: var(--t-sm);
		font-weight: 500;
		color: var(--c-text);
		user-select: none;
	}
	.nav-toggle > summary::-webkit-details-marker { display: none; }
	.nav-toggle > summary::after {
		content: "";
		width: 8px; height: 8px;
		border-right: 1.5px solid currentColor;
		border-bottom: 1.5px solid currentColor;
		transform: translateY(-2px) rotate(45deg);
		transition: transform var(--d-fast) var(--ease);
	}
	.nav-toggle[open] > summary::after { transform: translateY(1px) rotate(-135deg); }

	.nav-toggle__panel {
		position: absolute;
		left: 0; right: 0;
		top: 100%;
		background: var(--c-bg);
		border-bottom: 1px solid var(--c-border);
		box-shadow: var(--e-3);
		padding: var(--s-4) var(--gutter) var(--s-5);
		animation: rise var(--d-base) var(--ease) both;
	}
	.nav-toggle__panel ul {
		display: flex; flex-direction: column; gap: 0;
		margin: 0; padding: 0; list-style: none;
	}
	.nav-toggle__panel li + li { border-top: 1px solid var(--c-border); }
	.nav-toggle__panel a {
		display: block;
		padding: var(--s-3) 0;
		color: var(--c-text);
		text-decoration: none;
		font-size: var(--t-base);
	}
	.nav-toggle__panel a:hover { color: var(--c-accent); }

	/* At the narrowest widths the brand plus a full-size CTA will not fit. */
	.site-header__inner { gap: var(--s-3); }
	.header-cta { padding: 0.7em 1.05em; font-size: var(--t-xs); }
}

@media (max-width: 380px) { .header-cta { display: none; } }

/* ---- Small utilities used by templates (kept out of inline styles) ----- */

.page-header { margin-bottom: var(--s-7); }
.lede { color: var(--c-text-muted); }
.mt-3 { margin-top: var(--s-3); }
.m-0  { margin: 0; }

.card-title { font-size: var(--t-lg); margin-bottom: var(--s-2); }
.card-title a { color: var(--c-text); text-decoration: none; }
.card-title a:hover { color: var(--c-accent); }

/* ---- Checkout ----------------------------------------------------------
   Summary and form sit side by side above 900px; the summary leads so the
   visitor sees what they are buying before the fields.
   ------------------------------------------------------------------------ */

.checkout {
	display: grid;
	gap: var(--s-7);
	grid-template-columns: 1fr;
	align-items: start;
}
@media (min-width: 900px) {
	.checkout { grid-template-columns: 1fr 0.9fr; gap: var(--s-8); }
	.checkout__form { position: sticky; top: calc(68px + var(--s-5)); }
}

.eyebrow {
	font-size: var(--t-xs);
	text-transform: uppercase;
	letter-spacing: 0.12em;
	color: var(--c-accent);
	margin-bottom: var(--s-2);
}

.price-now {
	display: flex; align-items: baseline; gap: var(--s-4);
	flex-wrap: wrap;
	font-size: var(--t-3xl);
	font-weight: 700;
	letter-spacing: -0.04em;
	font-variant-numeric: tabular-nums;
	margin-bottom: var(--s-2);
}
.price-was {
	font-size: var(--t-xl);
	font-weight: 500;
	color: var(--c-text-faint);
	text-decoration-thickness: 1px;
}

.ticks { margin: var(--s-6) 0 0; padding: 0; list-style: none; }
.ticks li {
	position: relative;
	padding-left: var(--s-5);
	padding-block: var(--s-2);
	border-top: 1px solid var(--c-border);
	color: var(--c-text-muted);
	font-size: var(--t-sm);
}
.ticks li::before {
	content: "";
	position: absolute;
	left: 0; top: 50%;
	width: 6px; height: 10px;
	border-right: 2px solid var(--c-accent);
	border-bottom: 2px solid var(--c-accent);
	transform: translateY(-60%) rotate(45deg);
}

/* ---- Forms ------------------------------------------------------------- */

.form {
	background: var(--c-surface);
	border: 1px solid var(--c-border);
	border-radius: var(--r-lg);
	padding: var(--s-6);
	box-shadow: var(--e-2), var(--e-inset);
}

.field { display: flex; flex-direction: column; gap: var(--s-2); margin-bottom: var(--s-5); }

.field label {
	font-size: var(--t-sm);
	font-weight: 600;
	color: var(--c-text);
}

.field input {
	width: 100%;
	padding: 0.8em 0.9em;
	background: var(--c-bg);
	border: 1px solid var(--c-border-str);
	border-radius: var(--r-md);
	color: var(--c-text);
	font: inherit;
	font-size: var(--t-base);
	transition: border-color var(--d-fast) var(--ease);
}
.field input::placeholder { color: var(--c-text-faint); }
.field input:hover { border-color: var(--c-text-faint); }
.field input:focus-visible { border-color: var(--c-accent); outline-offset: 1px; }
.field input[aria-invalid="true"] { border-color: var(--c-err); }

.field__help  { font-size: var(--t-xs); color: var(--c-text-faint); margin: 0; }
.field__error { font-size: var(--t-xs); color: var(--c-err); margin: 0; font-weight: 500; }

.btn--block { width: 100%; }

/* ---- Pricing matrix ---------------------------------------------------- */

.plan-grid {
	display: grid;
	gap: var(--s-4);
	grid-template-columns: 1fr;
}
@media (min-width: 640px)  { .plan-grid { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1040px) { .plan-grid { grid-template-columns: repeat(3, 1fr); } }

.plan {
	display: flex; flex-direction: column; gap: var(--s-2);
	padding: var(--s-5);
	border: 1px solid var(--c-border);
	border-radius: var(--r-lg);
	background: var(--c-surface);
	transition: border-color var(--d-fast) var(--ease),
	            transform var(--d-fast) var(--ease);
}
.plan:hover { border-color: var(--c-border-str); transform: translateY(-2px); }

.plan__term { font-size: var(--t-xs); text-transform: uppercase;
              letter-spacing: 0.1em; color: var(--c-text-faint); }
.plan__price {
	font-size: var(--t-2xl); font-weight: 700; letter-spacing: -0.04em;
	font-variant-numeric: tabular-nums;
}
.plan__pm { font-size: var(--t-sm); color: var(--c-text-muted); }
.plan .btn { margin-top: var(--s-3); }

.plan-group { margin-bottom: var(--s-8); }
.plan-group > h3 { margin-bottom: var(--s-4); }

/* ---- Tier navigation --------------------------------------------------- */

.tier-nav__list {
	display: flex; flex-wrap: wrap; align-items: center; gap: var(--s-2);
	margin: 0 0 var(--s-6); padding: 0; list-style: none;
}
.tier-nav__list li + li { margin-top: 0; } /* defensive: never inherit prose list spacing */
.tier-nav a,
.tier-nav__current {
	display: inline-block;
	padding: 0.55em 1.1em;
	border: 1px solid var(--c-border);
	border-radius: var(--r-full);
	font-size: var(--t-sm);
	font-weight: 500;
	text-decoration: none;
	transition: border-color var(--d-fast) var(--ease),
	            color var(--d-fast) var(--ease);
}
.tier-nav a { color: var(--c-text-muted); }
.tier-nav a:hover { color: var(--c-text); border-color: var(--c-border-str); }
.tier-nav__current {
	background: var(--c-accent-wash);
	border-color: var(--c-accent);
	color: var(--c-accent-hi);
}

/* ---- Content components ------------------------------------------------ */


.cta {
	display: flex; flex-wrap: wrap; align-items: center;
	justify-content: space-between; gap: var(--s-5);
	margin-block: var(--s-7);
	padding: var(--s-6);
	border: 1px solid var(--c-border);
	border-left: 3px solid var(--c-accent);
	border-radius: var(--r-lg);
	background: var(--c-surface);
}
.cta__title { font-size: var(--t-xl); margin: 0 0 var(--s-1); }
.cta__text  { margin: 0; color: var(--c-text-muted); max-width: 48ch; }

/* FAQ — native disclosure, answers present in the HTML when closed. */
.faq { margin-block: var(--s-5); border-top: 1px solid var(--c-border); }
.faq__item { border-bottom: 1px solid var(--c-border); }
.faq__item > summary {
	list-style: none;
	cursor: pointer;
	display: flex; align-items: center; justify-content: space-between; gap: var(--s-4);
	padding: var(--s-4) 0;
	font-weight: 600;
	font-size: var(--t-base);
	color: var(--c-text);
}
.faq__item > summary::-webkit-details-marker { display: none; }
.faq__item > summary::after {
	content: "";
	flex: none;
	width: 9px; height: 9px;
	border-right: 1.5px solid var(--c-text-faint);
	border-bottom: 1.5px solid var(--c-text-faint);
	transform: translateY(-2px) rotate(45deg);
	transition: transform var(--d-fast) var(--ease);
}
.faq__item[open] > summary::after { transform: translateY(2px) rotate(-135deg); }
.faq__item > summary:hover { color: var(--c-accent); }
.faq__a { padding-bottom: var(--s-4); }
.faq__a p { margin: 0; color: var(--c-text-muted); }

/* Hero — asymmetric, content offset left, never centred. */
.hero { padding-block: clamp(3rem, 1.5rem + 6vw, 6rem) var(--section-y); }
.hero__title { font-size: var(--t-3xl); max-width: 22ch; }
.hero__lede { font-size: var(--t-lg); color: var(--c-text-muted); max-width: 52ch; }
.hero__actions { display: flex; flex-wrap: wrap; gap: var(--s-3); margin-block: var(--s-6); }
.hero .stats { margin-top: var(--s-8); }

.trust { display: flex; flex-wrap: wrap; gap: var(--s-2) var(--s-5); margin: 0; padding: 0; list-style: none; }
.trust li { font-size: var(--t-sm); color: var(--c-text-muted); }

/* ---- Single post ------------------------------------------------------- */

.post-meta {
	font-size: var(--t-sm);
	color: var(--c-text-faint);
	margin: 0;
}

.post-nav {
	display: grid; gap: var(--s-4);
	grid-template-columns: 1fr;
	margin-top: var(--s-8);
	padding-top: var(--s-6);
	border-top: 1px solid var(--c-border);
}
@media (min-width: 720px) { .post-nav { grid-template-columns: 1fr 1fr; } }

.post-nav__link {
	display: flex; flex-direction: column; gap: var(--s-1);
	padding: var(--s-4);
	border: 1px solid var(--c-border);
	border-radius: var(--r-lg);
	color: var(--c-text);
	text-decoration: none;
	transition: border-color var(--d-fast) var(--ease);
}
.post-nav__link:hover { border-color: var(--c-border-str); color: var(--c-text); }
.post-nav__link--next { text-align: right; }
.post-nav__dir {
	font-size: var(--t-xs); text-transform: uppercase;
	/* accent-as-text on paper: --c-accent is 4.01:1, the darker step is 4.97 */
	letter-spacing: 0.1em; color: var(--c-accent-lo);
}

/* ---- Contact ----------------------------------------------------------- */

.footer-note { color: var(--c-text-faint); font-size: var(--t-xs); }

.wa-link {
	/* accent-as-text on paper needs the darker step: --c-accent is 4.01:1 */
	color: var(--c-accent-lo);
	text-decoration-thickness: 1px;
	text-underline-offset: 3px;
	white-space: nowrap;
}
.wa-link:hover { color: var(--c-accent); }

/* ==========================================================================
   Product visuals
   ========================================================================== */

/* ---- Hero: asymmetric split, artwork right --------------------------- */

.hero-split {
	display: grid;
	gap: var(--s-7);
	grid-template-columns: 1fr;
	align-items: center;
	padding-block: clamp(2.5rem, 1rem + 5vw, 5rem) var(--s-8);
}
@media (min-width: 960px) {
	.hero-split { grid-template-columns: 1.05fr 0.95fr; gap: var(--s-9); }
}

.hero-split__text > .stats { margin-top: var(--s-7); }
.btn--lg { padding: 1em 2em; font-size: var(--t-base); }

/* Player chrome. Markup, not an image: crisp at any density, zero bytes. */
.hero-split__art { position: relative; }

.screen {
	position: relative;
	z-index: 1;
	border: 1px solid var(--c-border-str);
	border-radius: var(--r-xl);
	background: linear-gradient(180deg, var(--c-surface-2), var(--c-surface));
	box-shadow: var(--e-3), var(--e-inset);
	overflow: hidden;
	animation: rise var(--d-slow) var(--ease) both;
}

.screen__bar {
	display: flex; align-items: center; gap: var(--s-2);
	padding: var(--s-3) var(--s-4);
	border-bottom: 1px solid var(--c-border);
	background: rgb(0 0 0 / 0.25);
}
.screen__dot {
	width: 9px; height: 9px; border-radius: var(--r-full);
	background: var(--c-border-str);
}
.screen__label {
	margin-left: var(--s-2);
	font-size: var(--t-xs);
	letter-spacing: 0.08em;
	text-transform: uppercase;
	color: var(--c-text-faint);
}

/* Accent bloom behind the panel — tinted, never a neon glow. */
.screen__glow {
	position: absolute;
	/* No negative right inset: it pushed the bounding box past the viewport
	   and body overflow-x:hidden merely hid the resulting scroll. */
	inset: 12% 0 -10% 6%;
	background: radial-gradient(60% 60% at 60% 40%, var(--c-accent-wash), transparent 70%);
	filter: blur(42px);
	z-index: 0;
	pointer-events: none;
}

.epg { margin: 0; padding: 0; list-style: none; }
.epg__row {
	display: grid;
	grid-template-columns: 6.5rem 1fr auto;
	gap: var(--s-3);
	align-items: center;
	padding: var(--s-4);
	border-bottom: 1px solid var(--c-border);
	font-size: var(--t-sm);
	animation: rise var(--d-slow) var(--ease) both;
	animation-delay: calc(140ms + var(--i, 0) * 90ms);
}
.epg__row:last-child { border-bottom: 0; }
.epg__ch {
	font-weight: 600;
	color: var(--c-text);
	letter-spacing: -0.02em;
}
.epg__prog { color: var(--c-text-muted); }
.epg__time {
	display: inline-flex; align-items: center; gap: var(--s-2);
	font-variant-numeric: tabular-nums;
	font-size: var(--t-xs);
	color: var(--c-text-faint);
	white-space: nowrap;
}
.epg__row--live { background: var(--c-accent-wash); }
.epg__row--live .epg__time { color: var(--c-accent-hi); font-weight: 600; }
.epg__dot {
	width: 6px; height: 6px; border-radius: var(--r-full);
	background: var(--c-accent);
	animation: pulse 2s var(--ease) infinite;
}
@keyframes pulse {
	0%, 100% { opacity: 1; transform: scale(1); }
	50%      { opacity: 0.45; transform: scale(0.75); }
}

@media (max-width: 600px) {
	.epg__row { grid-template-columns: 5rem 1fr; }
	.epg__time { grid-column: 2; justify-self: start; }
}

/* ---- Channel logo wall ------------------------------------------------ */

.logo-wall { margin-block: var(--s-8); }
.logo-wall__title { font-size: var(--t-xl); margin-bottom: var(--s-5); }

/* Fade the edges so logos enter and leave rather than being cut off. */
.logo-wall__viewport {
	display: flex;
	gap: var(--s-6);
	overflow: hidden;
	mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent);
	-webkit-mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent);
}

.logo-wall__track {
	display: flex;
	flex: none;
	align-items: center;
	gap: var(--s-6);
	margin: 0; padding: 0;
	list-style: none;
	animation: marquee 42s linear infinite;
}
.logo-wall:hover .logo-wall__track { animation-play-state: paused; }

@keyframes marquee {
	from { transform: translate3d(0, 0, 0); }
	to   { transform: translate3d(calc(-100% - var(--s-6)), 0, 0); }
}

.logo-wall__item {
	flex: none;
	display: grid;
	place-items: center;
	width: 118px; height: 62px;
	padding: var(--s-3);
	border: 1px solid var(--c-border);
	border-radius: var(--r-md);
	background: var(--c-surface);
}
.logo-wall__item img {
	max-width: 100%; max-height: 34px;
	width: auto; height: auto;
	object-fit: contain;
	/* Every mark is dark artwork drawn for a light background — which is now
	   exactly what this theme is, so the invert(1) that made them legible on
	   the old dark ground turned them white-on-white and erased the wall.
	   brightness(0) alone flattens each mark to one ink silhouette, so the row
	   reads as a uniform set rather than a jumble of brand colours. */
	filter: brightness(0);
	opacity: 0.68;
	transition: opacity var(--d-base) var(--ease), filter var(--d-base) var(--ease);
}
.logo-wall__item:hover img { opacity: 1; }

@media (prefers-reduced-motion: reduce) {
	.logo-wall__track { animation: none; }
	.logo-wall__viewport { overflow-x: auto; }
}

/* ---- Device grid ------------------------------------------------------ */

.devices {
	display: grid;
	grid-template-columns: repeat(2, 1fr);
	gap: var(--s-3);
	margin: var(--s-5) 0;
	padding: 0;
	list-style: none;
}
@media (min-width: 640px)  { .devices { grid-template-columns: repeat(3, 1fr); } }
@media (min-width: 1040px) { .devices { grid-template-columns: repeat(6, 1fr); } }

.devices__item {
	display: flex; flex-direction: column; align-items: center; gap: var(--s-1);
	padding: var(--s-5) var(--s-3);
	border: 1px solid var(--c-border);
	border-radius: var(--r-lg);
	background: var(--c-surface);
	text-align: center;
	transition: border-color var(--d-fast) var(--ease), transform var(--d-fast) var(--ease);
	animation: rise var(--d-slow) var(--ease) both;
	animation-delay: calc(var(--i, 0) * 60ms);
}
.devices__item:hover { border-color: var(--c-border-str); transform: translateY(-2px); }
.devices__icon { width: 30px; height: 30px; color: var(--c-accent); margin-bottom: var(--s-2); }
.devices__name { font-size: var(--t-sm); font-weight: 600; }
.devices__sub  {
	font-size: var(--t-xs);
	color: var(--c-text-faint);
	text-wrap: balance;
}
.devices__name { text-wrap: balance; }

/* ---- Payment ---------------------------------------------------------- */

.pay { margin: var(--s-5) 0 0; }
.pay img { max-width: 280px; opacity: 0.8; }

/* ---- Platform poster row ---------------------------------------------- */

.posters-wrap { margin-block: var(--s-8); }

.posters {
	display: grid;
	grid-template-columns: repeat(2, 1fr);
	gap: var(--s-3);
	margin: var(--s-5) 0 0;
	padding: 0;
	list-style: none;
}
@media (min-width: 640px)  { .posters { grid-template-columns: repeat(3, 1fr); } }
@media (min-width: 1040px) { .posters { grid-template-columns: repeat(6, 1fr); } }

.posters__item {
	position: relative;
	overflow: hidden;
	border: 1px solid var(--c-border);
	border-radius: var(--r-lg);
	/* Reserve the ratio so the row never shifts as posters decode. */
	aspect-ratio: 400 / 520;
	animation: rise var(--d-slow) var(--ease) both;
	animation-delay: calc(var(--i, 0) * 70ms);
}
.posters__item img {
	width: 100%; height: 100%;
	object-fit: cover;
	display: block;
	transition: transform var(--d-slow) var(--ease), opacity var(--d-base) var(--ease);
	opacity: 0.86;
}
.posters__item:hover img { transform: scale(1.04); opacity: 1; }

/* The poster art already displays the brand wordmark; an overlay label sits on
   top of it. Keep the name for assistive tech only (alt text carries it too). */
.posters__name {
	position: absolute;
	width: 1px; height: 1px;
	padding: 0; margin: -1px;
	overflow: hidden;
	clip-path: inset(50%);
	white-space: nowrap;
}

/* ==========================================================================
   Pricing cards
   Three terms side by side, the twelve-month plan raised and centred.
   ========================================================================== */

.pgrid {
	display: grid;
	gap: var(--s-4);
	grid-template-columns: 1fr;
	align-items: start;
	margin-block: var(--s-6);
}
@media (min-width: 900px) {
	.pgrid { grid-template-columns: repeat(3, 1fr); gap: var(--s-5); align-items: center; }
}

.pcard {
	position: relative;
	display: flex;
	flex-direction: column;
	gap: var(--s-4);
	padding: var(--s-6);
	border: 1px solid var(--c-border);
	border-radius: var(--r-xl);
	background: var(--c-surface);
	transition: border-color var(--d-base) var(--ease), transform var(--d-base) var(--ease);
}
.pcard:hover { border-color: var(--c-border-str); }

/* The recommended plan earns emphasis through border, ground and elevation —
   not a second accent colour. */
.pcard--popular {
	border-color: var(--c-accent);
	background: linear-gradient(180deg, var(--c-accent-wash), var(--c-surface) 42%);
	box-shadow: var(--e-3);
}
@media (min-width: 900px) {
	.pcard--popular { padding-block: var(--s-7); }
}

.pcard__badge {
	position: absolute;
	top: 0; left: 50%;
	transform: translate(-50%, -50%);
	padding: 0.35em 1em;
	border-radius: var(--r-full);
	background: var(--c-accent);
	color: var(--c-accent-ink);
	font-size: var(--t-xs);
	font-weight: 700;
	letter-spacing: 0.06em;
	text-transform: uppercase;
	white-space: nowrap;
}

.pcard__name {
	font-size: var(--t-lg);
	margin: 0 0 var(--s-1);
	letter-spacing: -0.03em;
}
.pcard__term {
	margin: 0;
	font-size: var(--t-sm);
	color: var(--c-text-faint);
}

.pcard__price { border-block: 1px solid var(--c-border); padding-block: var(--s-4); }
.pcard__was {
	margin: 0 0 var(--s-1);
	font-size: var(--t-sm);
	color: var(--c-text-faint);
}
.pcard__now {
	display: flex; align-items: baseline; gap: var(--s-2);
	margin: 0 0 var(--s-2);
}
.pcard__amount {
	font-size: clamp(2.25rem, 1.8rem + 1.8vw, 3rem);
	font-weight: 700;
	letter-spacing: -0.045em;
	line-height: 1;
	font-variant-numeric: tabular-nums;
}
.pcard__cur { font-size: var(--t-sm); color: var(--c-text-faint); font-weight: 600; }

.pcard__meta {
	display: flex; align-items: center; gap: var(--s-3);
	margin: 0;
	font-size: var(--t-sm);
	color: var(--c-text-muted);
	font-variant-numeric: tabular-nums;
}
.pcard__off {
	padding: 0.2em 0.6em;
	border-radius: var(--r-full);
	background: rgb(74 222 128 / 0.14);
	color: var(--c-ok);
	font-size: var(--t-xs);
	font-weight: 700;
	white-space: nowrap;
}

.pcard__features {
	flex: 1;
	margin: 0; padding: 0;
	list-style: none;
	display: grid;
	gap: var(--s-3);
}
.pcard__features li {
	display: grid;
	grid-template-columns: 16px 1fr;
	gap: var(--s-3);
	align-items: start;
	font-size: var(--t-sm);
	color: var(--c-text-muted);
}
.pcard__features svg {
	width: 16px; height: 16px;
	margin-top: 2px;
	fill: none;
	stroke: var(--c-accent);
	stroke-width: 2;
	stroke-linecap: round;
	stroke-linejoin: round;
}

/* ---- Multi-screen band ------------------------------------------------- */

.multiband {
	display: flex; flex-wrap: wrap; align-items: center; gap: var(--s-4);
	margin-top: var(--s-5);
	padding: var(--s-5);
	border: 1px solid var(--c-border);
	border-radius: var(--r-lg);
	background: var(--c-surface);
}
.multiband__icon {
	flex: none;
	width: 40px; height: 40px;
	padding: 8px;
	border-radius: var(--r-md);
	background: var(--c-accent-wash);
	color: var(--c-accent);
}
.multiband__text { flex: 1 1 16rem; }
.multiband__title { margin: 0; font-weight: 600; }
.multiband__sub   { margin: 0; font-size: var(--t-sm); color: var(--c-text-muted); }

/* ---- Trust row --------------------------------------------------------- */

.trustrow {
	display: flex; flex-wrap: wrap; justify-content: center; gap: var(--s-3) var(--s-6);
	margin: var(--s-5) 0 0; padding: 0;
	list-style: none;
}
.trustrow li {
	display: inline-flex; align-items: center; gap: var(--s-2);
	font-size: var(--t-sm);
	color: var(--c-text-faint);
}
.trustrow svg {
	width: 15px; height: 15px;
	fill: none; stroke: currentColor; stroke-width: 1.4;
	stroke-linecap: round; stroke-linejoin: round;
}
.trustrow li:first-child { color: var(--c-ok); }

/* ---- Bento feature cards ----------------------------------------------
   Asymmetric on purpose: the lead card spans two tracks so the row has a
   rhythm rather than reading as three equal boxes.
   ------------------------------------------------------------------------ */


/* ---- Hero banner ------------------------------------------------------- */

.banner { margin: 0 0 var(--s-7); }
.banner__img {
	width: 100%;
	aspect-ratio: 1600 / 893;
	object-fit: cover;
	border-radius: var(--r-xl);
	border: 1px solid var(--c-border);
}

/* ---- Guide figure ------------------------------------------------------ */

.guide { margin: var(--s-5) 0; }
.guide__img {
	width: 100%;
	aspect-ratio: 1600 / 893;
	object-fit: cover;
	border: 1px solid var(--c-border);
	border-radius: var(--r-lg);
}
.guide figcaption {
	margin-top: var(--s-2);
	font-size: var(--t-xs);
	color: var(--c-text-faint);
}

/* ---- Hero depth -------------------------------------------------------
   A second panel behind the first, offset and rotated, so the artwork reads
   as a stack rather than a flat rectangle. On wide viewports the deck bleeds
   past the container edge, which implies the product continues off-screen.
   ------------------------------------------------------------------------ */

.stack-deck { position: relative; z-index: 1; }

/* Hidden below the split breakpoint: the rotated bounding box pushes ~7px past
   the viewport on narrow screens, and the depth effect needs room the single
   column does not have. */
.stack-deck__back { display: none; }

@media (min-width: 900px) {
.stack-deck__back {
	display: block;
	position: absolute;
	inset: -14px 0 22px 24px;
	border: 1px solid var(--c-border);
	border-radius: var(--r-xl);
	background: linear-gradient(180deg, var(--c-surface-2), transparent 70%);
	transform: rotate(-2.2deg);
	opacity: 0.55;
}
}

@media (min-width: 1240px) {
	/* Bleed toward the viewport edge, not an arbitrary offset. */
	.hero-split__art { margin-right: calc((100vw - var(--maxw)) / -2 + var(--gutter)); }
}

/* Category pills: the EPG stops looking like a table and starts looking like
   an interface someone navigates. */
.screen__tabs {
	display: flex;
	gap: var(--s-2);
	margin: 0;
	padding: var(--s-3) var(--s-4);
	list-style: none;
	border-bottom: 1px solid var(--c-border);
	overflow: hidden;
}
.screen__tabs li {
	flex: none;
	padding: 0.3em 0.75em;
	border-radius: var(--r-full);
	font-size: var(--t-xs);
	font-weight: 500;
	color: var(--c-text-faint);
	border: 1px solid transparent;
}
.screen__tabs .is-active {
	color: var(--c-accent-hi);
	border-color: var(--c-accent);
	background: var(--c-accent-wash);
}

/* Faint vertical rules framing the hero column, echoing the reference's
   structural guides without adding chrome. */
@media (min-width: 1240px) {
	.hero-split { position: relative; }
	/* One rule only, on the container edge. A second at 58% ran behind the
	   artwork and read as a stray line rather than a frame. */
	.hero-split::before {
		content: "";
		position: absolute;
		top: 0; bottom: 0;
		left: calc(var(--gutter) * -1);
		width: 1px;
		background: linear-gradient(180deg, transparent, var(--c-border) 18%, var(--c-border) 82%, transparent);
		pointer-events: none;
	}
}

/* ==========================================================================
   Editorial layer
   --------------------------------------------------------------------------
   Three devices carry the whole design, applied consistently:

   1. THE SLATE   A mono, auto-numbered section label with a hairline rule —
                  borrowed from a broadcast production slate. Numbering is a
                  CSS counter, so sections can be reordered in wp-admin
                  without anyone having to renumber anything by hand.
   2. THE DISPLAY Enormous uppercase Instrument Serif, with italic phrases
                  as the only permitted emphasis.
   3. THE BAND    Full-bleed ink-ground sections that break the scroll into
                  chapters instead of one endless column of cards.
   ========================================================================== */

/* ---- Paper ------------------------------------------------------------- */
/* Fibre, not a flat fill. Fixed so it reads as the stock the page is printed
   on rather than something that scrolls with the content. */
body::before {
	content: "";
	position: fixed;
	inset: 0;
	z-index: 0;
	pointer-events: none;
	opacity: 0.4;
	mix-blend-mode: multiply;
	background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='180' height='180' filter='url(%23n)' opacity='0.22'/%3E%3C/svg%3E");
}
.site-header, main, .site-footer { position: relative; z-index: 1; }

/* ---- 1. The slate ------------------------------------------------------ */
main { counter-reset: slate; }

.slate {
	display: flex;
	align-items: center;
	gap: var(--s-4);
	margin: 0 0 var(--s-5);
	font-family: var(--font-mono);
	font-size: var(--t-xs);
	font-weight: 500;
	text-transform: uppercase;
	letter-spacing: var(--ls-label);
	color: var(--c-text-faint);
}
.slate::before {
	counter-increment: slate;
	content: counter(slate, decimal-leading-zero);
	color: var(--c-accent-lo);
}
/* The rule runs to the edge of the column — a magazine hairline, not a border. */
.slate::after {
	content: "";
	flex: 1;
	height: 1px;
	background: var(--c-border);
}
.slate--plain::before { content: none; counter-increment: none; }

/* The live-signal dot. Pulses only where motion is welcome. */
.slate__live {
	display: inline-flex;
	align-items: center;
	gap: var(--s-2);
	color: var(--c-accent-lo);
}
.slate__live::before {
	content: "";
	width: 6px; height: 6px;
	border-radius: var(--r-full);
	background: var(--c-accent);
	animation: signal 2s var(--ease-out) infinite;
}
@keyframes signal {
	0%, 100% { opacity: 1;   box-shadow: 0 0 0 0   var(--c-accent-wash); }
	50%      { opacity: 0.6; box-shadow: 0 0 0 5px rgb(220 53 11 / 0); }
}

/* ---- 2. The display ---------------------------------------------------- */
.display {
	font-family: var(--font-display);
	font-weight: 400;
	font-size: var(--t-display);
	text-transform: uppercase;
	letter-spacing: var(--ls-display);
	line-height: 1.12;
	margin: 0;
	text-wrap: balance;
}
/* Capitals carry no descenders, so optical balance wants the block pulled
   slightly tighter than the metrics suggest. */
.display--tight { line-height: 1.04; }
.display em { font-style: italic; }

/* An italic phrase set against the accent, used once per page at most. */
.display .hot { color: var(--c-accent-lo); font-style: italic; }

.lede--editorial {
	font-size: var(--t-lg);
	line-height: var(--lh-normal);
	color: var(--c-text-muted);
	max-width: 46ch;
}

/* ---- 3. The band ------------------------------------------------------- */
.band {
	position: relative;
	padding-block: var(--section-y);
}
.band--ink {
	background: var(--c-ink);
	color: var(--c-ink-text);
}
.band--ink h1, .band--ink h2, .band--ink h3, .band--ink h4 { color: var(--c-ink-text); }
.band--ink p,
.band--ink .lede--editorial { color: var(--c-ink-muted); }
.band--ink .slate { color: var(--c-ink-muted); }
.band--ink .slate::after { background: var(--c-ink-border); }
.band--ink .slate::before,
.band--ink .display .hot,
.band--ink .slate__live { color: var(--c-accent-hi); }
.band--ink a { color: var(--c-accent-hi); }

/* Cards sitting on the ink ground invert with it. */
.band--ink .card,
.band--ink .pcard {
	background: var(--c-ink-2);
	border-color: var(--c-ink-border);
	color: var(--c-ink-text);
}

/* A band butted against the footer shouldn't leave a seam. */
.band--ink + .site-footer { border-top-color: transparent; }

/* ---- Rules ------------------------------------------------------------- */
.rule {
	height: 1px;
	background: var(--c-border);
	border: 0;
	margin: 0;
}

/* ---- Page-load reveal -------------------------------------------------- */
/* One orchestrated entrance, driven by animation-delay rather than a scroll
   listener: text that depends on an observer can be indexed at opacity 0. */
@keyframes rise {
	from { opacity: 0; transform: translateY(14px); }
	to   { opacity: 1; transform: none; }
}
/* transitions.dev "texts reveal" (18-texts-reveal.md), adapted.
 *
 * ADAPTED, NOT VERBATIM — and the deviation is the point. The published
 * snippet is transition-driven: lines sit at opacity 0 until JS adds
 * .is-shown. Dropped in here that would reintroduce exactly the failure this
 * block was written to avoid (see the note above) — hero copy painted at zero
 * opacity for anything that does not run scripts. So the snippet's MOTION is
 * adopted (12px rise, 3px cross-blur, 500ms, smooth-out ease, --stagger-*
 * tokens) while the delivery stays animation + `backwards`: no JS, no
 * observer, and every word painted if the animation never runs at all.
 *
 * Named stagger-rise rather than reusing `rise` because `rise` is declared
 * twice in this file (L178 at 10px, L1330 at 14px) and the second wins. */
@keyframes stagger-rise {
	from {
		opacity: 0;
		transform: translateY(var(--stagger-distance));
		filter: blur(var(--stagger-blur));
	}
	to { opacity: 1; transform: none; filter: blur(0); }
}

.reveal > * {
	animation: stagger-rise var(--stagger-dur) var(--stagger-ease) backwards;
	will-change: transform, opacity, filter;
}
/* Delays derive from the token, so retuning the stagger is a one-line edit.
   The hero column runs to five or six children depending on whether the
   activity pill and payment row have anything true to say; the n+7 catch-all
   means a seventh block lands with the row rather than jumping in unstaggered. */
.reveal > :nth-child(1)    { animation-delay: 0ms; }
.reveal > :nth-child(2)    { animation-delay: calc(var(--stagger-stagger) * 1); }
.reveal > :nth-child(3)    { animation-delay: calc(var(--stagger-stagger) * 2); }
.reveal > :nth-child(4)    { animation-delay: calc(var(--stagger-stagger) * 3); }
.reveal > :nth-child(5)    { animation-delay: calc(var(--stagger-stagger) * 4); }
.reveal > :nth-child(6)    { animation-delay: calc(var(--stagger-stagger) * 5); }
.reveal > :nth-child(n+7)  { animation-delay: calc(var(--stagger-stagger) * 6); }

/* The global reduced-motion block neutralises duration; this also removes the
   transform and blur so nothing lands a pixel off or a frame soft. */
@media (prefers-reduced-motion: reduce) {
	.reveal > * {
		animation: none;
		opacity: 1;
		transform: none;
		filter: none;
		will-change: auto;
	}
	.slate__live::before { animation: none; }
}

/* ---- Editorial hero ---------------------------------------------------- */
/* The headline spans the full measure like a cover line; the lede and the
   product art sit BENEATH it in two columns. That is the grid-break — a
   text-left/art-right hero is the shape every competitor already uses. */
.hero-ed {
	padding-block: clamp(2.5rem, 1rem + 5vw, 5rem) var(--section-y);
}
.hero-ed__title {
	font-size: var(--t-display);
	max-width: 18ch;         /* three lines at desktop, never a single ribbon */
	margin: 0 0 var(--s-7);
}
.hero-ed__body {
	display: grid;
	gap: var(--s-7);
	grid-template-columns: 1fr;
	align-items: start;
}
@media (min-width: 900px) {
	.hero-ed__title { max-width: 15ch; }
	.hero-ed__body {
		grid-template-columns: minmax(0, 0.85fr) minmax(0, 1.15fr);
		gap: var(--s-8);
	}
}
.hero-ed__col > :first-child { margin-top: 0; }

/* Figures are data — they belong in the mono face, not the body face. */
.stats__value {
	font-family: var(--font-mono);
	font-weight: 500;
	letter-spacing: -0.02em;
	font-feature-settings: "tnum" 1;
}
.stats__label {
	font-family: var(--font-mono);
	text-transform: uppercase;
	letter-spacing: var(--ls-label);
}

/* ---- Buttons ----------------------------------------------------------- */
/* Square-ish, mono-labelled: a pill button is the single most generic shape
   in the category. */
.btn {
	font-family: var(--font-mono);
	font-weight: 500;
	text-transform: uppercase;
	letter-spacing: 0.08em;
	font-size: var(--t-xs);
	border-radius: var(--r-sm);
}
.btn--primary {
	background: var(--c-accent);
	color: var(--c-accent-ink);
	border-color: var(--c-accent);
}
.btn--primary:hover { background: var(--c-text); border-color: var(--c-text); color: var(--c-bg); }
.btn--ghost {
	background: transparent;
	color: var(--c-text);
	border-color: var(--c-border-str);
}
.btn--ghost:hover { background: var(--c-text); color: var(--c-bg); border-color: var(--c-text); }
.band--ink .btn--ghost { color: var(--c-ink-text); border-color: var(--c-ink-border); }
.band--ink .btn--ghost:hover { background: var(--c-ink-text); color: var(--c-ink); }

/* ---- Nav --------------------------------------------------------------- */
.nav a {
	font-family: var(--font-mono);
	font-size: var(--t-xs);
	font-weight: 400;
	text-transform: uppercase;
	letter-spacing: 0.06em;
}

/* ---- The screen is the one dark object on the page --------------------- */
/* A television IS dark. Making the EPG the single ink-ground element gives
   the paper page its focal point and lets the channel colour carry, instead
   of a light panel that dissolves into the background. */
.screen {
	background: var(--c-ink);
	border-color: var(--c-ink);
	border-radius: var(--r-lg);
	box-shadow: var(--e-3);
}
.screen__bar {
	background: rgb(255 255 255 / 0.04);
	border-bottom-color: var(--c-ink-border);
}
.screen__dot   { background: rgb(241 239 234 / 0.22); }
.screen__label { font-family: var(--font-mono); color: var(--c-ink-muted); letter-spacing: var(--ls-label); }

.screen__tabs      { border-bottom-color: var(--c-ink-border); }
.screen__tabs li   { font-family: var(--font-mono); font-size: var(--t-xs);
                     text-transform: uppercase; letter-spacing: 0.06em;
                     color: var(--c-ink-muted); border-radius: var(--r-sm); }
.screen__tabs .is-active { color: var(--c-accent-ink); background: var(--c-accent);
                           border-color: var(--c-accent); }

.epg__row        { border-bottom-color: var(--c-ink-border); }
.epg__ch         { color: var(--c-ink-text); }
.epg__prog       { color: var(--c-ink-muted); }
.epg__time       { font-family: var(--font-mono); color: var(--c-ink-muted); }
.epg__row--live  { background: rgb(220 53 11 / 0.14); }
.epg__row--live .epg__time { color: var(--c-accent-hi); }

/* The deck behind it reads as a second screen, so it takes the ink too —
   at low opacity it was invisible on a light ground. */
@media (min-width: 900px) {
	.stack-deck__back {
		background: var(--c-ink);
		border-color: var(--c-ink);
		opacity: 0.16;
	}
}
/* Warm bloom under the screen, as light off a panel onto paper. */
.screen__glow { filter: blur(52px); opacity: 0.9; }

/* ---- Hero corrections -------------------------------------------------- */
/* The first draft opened with ~200px of nothing under a sticky header that
   already supplies breathing room. Editorial pages start high on the page. */
.hero-ed { padding-block: clamp(1.5rem, 0.75rem + 2.5vw, 3rem) var(--section-y); }
.hero-ed__title { margin-bottom: var(--s-6); }

/* An outline, not a fill: at 16% ink the back panel read as a grey smudge
   bleeding off the corner. A hairline edge says "second screen" outright. */
@media (min-width: 900px) {
	.stack-deck__back {
		background: none;
		border: 1px solid var(--c-border-str);
		opacity: 0.5;
		border-radius: var(--r-lg);
		inset: -18px 0 26px 28px;
	}
}

/* ---- Surfaces on paper ------------------------------------------------- */
/* The logo tiles and device cards were chips on a dark ground. On paper a
   bordered box per logo is visual noise: let the marks sit on the page. */
.logo-wall__item { border: 0; background: none; }
.logo-wall__item:hover img { opacity: 1; }

/* ==========================================================================
   Editorial: pricing
   ========================================================================== */

/* Square the cards off and drop them onto the page rather than floating them
   on a lighter chip — on paper, a raised white card inside a white section is
   just a shadow with nothing to say. */
.pcard {
	border-radius: var(--r-md);
	background: var(--c-surface);
	box-shadow: none;
	gap: var(--s-5);
}

/* The recommended plan is the one INK card in the set. It uses the same
   logic as the screen in the hero: the thing that matters most is the thing
   that is dark. A tinted wash could not compete with that at a glance. */
.pcard--popular {
	background: var(--c-ink);
	border-color: var(--c-ink);
	color: var(--c-ink-text);
	box-shadow: var(--e-3);
}
.pcard--popular .pcard__name,
.pcard--popular .pcard__amount { color: var(--c-ink-text); }
.pcard--popular .pcard__term,
.pcard--popular .pcard__cur,
.pcard--popular .pcard__was,
.pcard--popular .pcard__meta,
.pcard--popular .pcard__features li { color: var(--c-ink-muted); }
.pcard--popular .pcard__price,
.pcard--popular .pcard__features li { border-color: var(--c-ink-border); }
.pcard--popular .btn--ghost { color: var(--c-ink-text); border-color: var(--c-ink-border); }
.pcard--popular .btn--ghost:hover { background: var(--c-ink-text); color: var(--c-ink); }

.pcard__badge {
	border-radius: var(--r-sm);
	font-family: var(--font-mono);
	font-weight: 500;
	letter-spacing: var(--ls-label);
}

/* Prices are the loudest type on a commercial page — so they take the
   display face, which is the loudest voice this design has. */
.pcard__amount {
	font-family: var(--font-display);
	font-weight: 400;
	letter-spacing: -0.02em;
	font-size: clamp(2.5rem, 1.9rem + 2.2vw, 3.5rem);
}
.pcard__name { font-family: var(--font-sans); font-weight: 700; letter-spacing: -0.02em; }
.pcard__cur,
.pcard__term,
.pcard__was,
.pcard__meta { font-family: var(--font-mono); font-size: var(--t-xs); letter-spacing: 0.02em; }
.pcard__was { text-decoration: line-through; }

/* A green pill has no place in this palette — the saving is data, so it is
   set as data: mono, boxed, in the single accent. */
.pcard__off {
	border-radius: var(--r-sm);
	background: none;
	border: 1px solid var(--c-accent);
	color: var(--c-accent-lo);
	font-family: var(--font-mono);
	font-weight: 500;
	padding: 0.25em 0.5em;
}
.pcard--popular .pcard__off { color: var(--c-accent-hi); border-color: var(--c-accent); }


/* ==========================================================================
   Chaptering
   --------------------------------------------------------------------------
   Every H2 in page content becomes a numbered chapter: a hairline rule, a
   mono numeral, then the display heading. Done with a CSS counter and ::before
   so it needs no content authoring and appears on every page automatically —
   and, because generated content is not part of the DOM text, it changes
   nothing about what the H2 says to a crawler.
   ========================================================================== */
.prose { counter-reset: chapter; }

.prose > h2 {
	margin-top: var(--s-9);
	padding-top: var(--s-4);
	border-top: 1px solid var(--c-border);
}
.prose > h2:first-child { margin-top: 0; }

.prose > h2::before {
	counter-increment: chapter;
	content: counter(chapter, decimal-leading-zero);
	display: block;
	margin-bottom: var(--s-3);
	font-family: var(--font-mono);
	font-size: var(--t-xs);
	font-weight: 500;
	letter-spacing: var(--ls-label);
	color: var(--c-accent-lo);
	/* The numeral is decoration; the heading text is the real label. */
	-webkit-user-select: none;
	user-select: none;
}
.band--ink .prose > h2 { border-top-color: var(--c-ink-border); }
.band--ink .prose > h2::before { color: var(--c-accent-hi); }

/* ---- Logo wall on paper ------------------------------------------------ */
/* Without their chips the marks were floating at 34px in a 118px cell, which
   read as scattered specks. Larger, tighter, and flattened to one ink weight. */
.logo-wall__item { width: auto; height: 48px; padding: 0; }
.logo-wall__item img { max-height: 40px; }
.logo-wall__viewport,
.logo-wall__track { gap: var(--s-8); }
@keyframes marquee {
	from { transform: translate3d(0, 0, 0); }
	to   { transform: translate3d(calc(-100% - var(--s-8)), 0, 0); }
}

/* ---- Chaptering, part 2 ------------------------------------------------ */
/* Shortcode sections render their own <h2> outside .prose's direct children,
   so half the page was numbered and half was not. Share one counter across
   both, and opt the components in explicitly rather than with a loose
   descendant selector that would number headings inside cards too. */
.prose > h2,
.logo-wall__title,
.platforms__title {
	margin-top: var(--s-9);
	padding-top: var(--s-4);
	border-top: 1px solid var(--c-border);
	font-family: var(--font-display);
	font-size: var(--t-2xl);
	font-weight: 400;
	text-transform: uppercase;
	letter-spacing: var(--ls-display);
	line-height: 1.12;
}
.logo-wall__title::before,
.platforms__title::before {
	counter-increment: chapter;
	content: counter(chapter, decimal-leading-zero);
	display: block;
	margin-bottom: var(--s-3);
	font-family: var(--font-mono);
	font-size: var(--t-xs);
	font-weight: 500;
	letter-spacing: var(--ls-label);
	color: var(--c-accent-lo);
	-webkit-user-select: none;
	user-select: none;
}
.logo-wall { margin-block: var(--s-6); }

/* The supplied marks are 300x150 with generous transparent margins baked in,
   so the visible glyph is well under half the box. Scaling the box up is the
   only way to give them presence without re-cutting the artwork. */
.logo-wall__item { width: 150px; height: 68px; }
.logo-wall__item img { max-height: 68px; max-width: 100%; }

/* ---- Closing CTA as an ink chapter ------------------------------------- */
/* The page was ending on flat paper. This is the third device of the system —
   a full-bleed ink band — and the close is the one place on the page that
   most deserves it. */
.cta {
	background: var(--c-ink);
	border: 0;
	border-radius: var(--r-md);
	color: var(--c-ink-text);
	padding: var(--s-8) var(--s-7);
	margin-block: var(--s-9) var(--s-7);
	align-items: end;
}
.cta__title {
	font-family: var(--font-display);
	font-weight: 400;
	font-size: var(--t-2xl);
	text-transform: uppercase;
	letter-spacing: var(--ls-display);
	line-height: 1.12;
	color: var(--c-ink-text);
}
.cta__text { color: var(--c-ink-muted); }
.cta .btn--primary:hover { background: var(--c-ink-text); color: var(--c-ink); border-color: var(--c-ink-text); }

/* ---- FAQ --------------------------------------------------------------- */
.faq__item > summary {
	font-family: var(--font-sans);
	font-weight: 600;
	padding-block: var(--s-5);
}
.faq__item > summary:hover { color: var(--c-accent-lo); }

/* ---- Footer ------------------------------------------------------------ */
.footer-col h2 {
	font-family: var(--font-mono);
	font-size: var(--t-xs);
	font-weight: 500;
	text-transform: uppercase;
	letter-spacing: var(--ls-label);
	color: var(--c-text-faint);
	/* The chaptering rules must not reach footer column headings. */
	border-top: 0;
	padding-top: 0;
	margin-top: 0;
}
.footer-col h2::before { content: none; counter-increment: none; }
.colophon { font-family: var(--font-mono); font-size: var(--t-xs); letter-spacing: 0.02em; }

/* The hero owns its own top spacing; the wrapping .section was stacking
   another --section-y (up to 120px) on top of it, which is where the dead
   band under the header came from. */
.section:has(.hero-ed) { padding-top: 0; }

/* ==========================================================================
   Trust signals
   ========================================================================== */

/* ---- Payment strip ----------------------------------------------------- */
.pay { margin-top: var(--s-6); }
.pay__label {
	margin: 0 0 var(--s-3);
	font-family: var(--font-mono);
	font-size: var(--t-xs);
	text-transform: uppercase;
	letter-spacing: var(--ls-label);
	color: var(--c-text-faint);
}
.pay__list {
	display: flex; flex-wrap: wrap;
	gap: var(--s-2) var(--s-3);
	margin: 0; padding: 0; list-style: none;
}
.pay__item {
	display: inline-flex; align-items: center; gap: var(--s-2);
	padding: 0.4em 0.7em;
	border: 1px solid var(--c-border);
	border-radius: var(--r-sm);
	font-family: var(--font-mono);
	font-size: var(--t-xs);
	color: var(--c-text-muted);
	white-space: nowrap;
}
.pay__glyph { width: 16px; height: 16px; flex: none; color: var(--c-text-faint); }
.band--ink .pay__item { border-color: var(--c-ink-border); color: var(--c-ink-muted); }

/* ---- Activity notice --------------------------------------------------- */
/* Renders only when a real lead sits inside the freshness window, so it must
   look at home appearing and disappearing between page loads — no reserved
   slot, no layout shift when absent. */
.actividad {
	display: inline-flex; align-items: center; gap: var(--s-2);
	margin: var(--s-5) 0 0;
	padding: 0.45em 0.8em;
	border: 1px solid var(--c-border);
	border-radius: var(--r-full);
	background: var(--c-surface);
	font-family: var(--font-mono);
	font-size: var(--t-xs);
	color: var(--c-text-muted);
	max-width: none;
}
.actividad strong { color: var(--c-text); font-weight: 500; }
.actividad__dot {
	width: 6px; height: 6px; flex: none;
	border-radius: var(--r-full);
	background: var(--c-ok);
	animation: signal 2.4s var(--ease-out) infinite;
}
@media (prefers-reduced-motion: reduce) { .actividad__dot { animation: none; } }

/* ---- Reviews ----------------------------------------------------------- */
.reviews { margin-block: var(--s-8); }
.reviews__title {
	margin-top: var(--s-9);
	padding-top: var(--s-4);
	border-top: 1px solid var(--c-border);
	font-family: var(--font-display);
	font-size: var(--t-2xl);
	font-weight: 400;
	text-transform: uppercase;
	letter-spacing: var(--ls-display);
	line-height: 1.12;
}
.reviews__title::before {
	counter-increment: chapter;
	content: counter(chapter, decimal-leading-zero);
	display: block;
	margin-bottom: var(--s-3);
	font-family: var(--font-mono);
	font-size: var(--t-xs);
	font-weight: 500;
	letter-spacing: var(--ls-label);
	color: var(--c-accent-lo);
	-webkit-user-select: none;
	user-select: none;
}
.revgrid {
	display: grid;
	grid-template-columns: 1fr;
	gap: var(--s-4);
	margin-top: var(--s-6);
}
@media (min-width: 760px)  { .revgrid { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1040px) { .revgrid { grid-template-columns: repeat(3, 1fr); } }

.rev {
	display: flex; flex-direction: column; gap: var(--s-4);
	margin: 0;
	padding: var(--s-6);
	border: 1px solid var(--c-border);
	border-radius: var(--r-md);
	background: var(--c-surface);
}
/* An oversized opening quote in the display face — the reviews read as pulled
   quotes in a feature spread rather than as app-store cards with star rows.
   No stars anywhere: a rating we cannot substantiate is not decoration. */
.rev__q { margin: 0; position: relative; padding-top: var(--s-5); }
.rev__q::before {
	content: "\201C";
	position: absolute; top: -0.32em; left: -0.04em;
	font-family: var(--font-display);
	font-size: 4rem;
	line-height: 1;
	color: var(--c-accent);
	opacity: 0.32;
	pointer-events: none;
}
.rev__q p { margin: 0; font-size: var(--t-base); color: var(--c-text); max-width: none; }
.rev__who {
	font-family: var(--font-mono);
	font-size: var(--t-xs);
	text-transform: uppercase;
	letter-spacing: var(--ls-label);
	color: var(--c-text-faint);
	margin-top: auto;
}

/* The payment chips need clearance from the CTA above them (the old
   `.hero .stats` margin rule keys off a class the editorial hero no longer
   uses). The stats band sets its own spacing — it is a sibling of the body
   now, not the last thing in this column. */
.hero-ed__col .pay   { margin-top: var(--s-6); }
.hero-ed__col .actividad + .pay { margin-top: var(--s-4); }

/* ---- Payment strip, supplied artwork ----------------------------------- */
/* The acceptance marks ship as one transparent PNG. Capped rather than
   full-width: at 550px natural it would out-measure the lede beside it and
   read as the loudest thing in the hero, which it is not. */
.pay--art .pay__art {
	width: 100%;
	max-width: 420px;
	height: auto;
}
@media (min-width: 900px) { .pay--art .pay__art { max-width: 380px; } }

/* Left in full colour deliberately. Desaturating them to protect the
   monochrome palette made the marks read as broken or disabled — these work by
   instant recognition, and a grey Visa is worth less than no Visa. They are
   small enough at this size not to fight the one accent. */
.pay--art .pay__art { opacity: 0.94; }
.pay--art:hover .pay__art { opacity: 1; }

/* ---- Review star ratings ----------------------------------------------- */
.rev__rating {
	display: flex;
	gap: 2px;
	margin: 0;
	max-width: none;
}
.rev__star {
	width: 15px; height: 15px;
	flex: none;
	fill: var(--c-accent);
}
/* An unearned star is drawn as an outline rather than hidden, so a 4/5 reads
   as four-out-of-five at a glance instead of "four stars". */
.rev__star--off {
	fill: none;
	stroke: var(--c-border-str);
	stroke-width: 1.6;
}
/* The rating sits above the quote, so the decorative quote mark needs less
   headroom than it does when it leads the card. */
.rev__rating + .rev__q { padding-top: var(--s-4); }
.rev__rating + .rev__q::before { top: -0.42em; }

/* ---- Review card corrections ------------------------------------------- */
/* The oversized quote glyph was designed for a card that opens with text. With
   a rating above it the two occupy the same corner and overlap. The stars
   already say "this is a review", so the glyph stands down when they're
   present rather than both fighting for the same 40 square pixels. */
.rev__rating + .rev__q { padding-top: 0; }
.rev__rating + .rev__q::before { content: none; }

/* Five cards in a three-column grid leave a dead cell in row two. Flex with a
   grow factor lets the final row expand to fill the width instead, and it
   holds for any number of reviews — three, five or seven — so adding one
   later can't reintroduce the hole. */
.revgrid {
	display: flex;
	flex-wrap: wrap;
	gap: var(--s-4);
}
.revgrid > .rev {
	flex: 1 1 300px;
	min-width: 0;
}

/* ==========================================================================
   Scroll UI
   --------------------------------------------------------------------------
   Both effects below are pure CSS scroll-driven animation. No listener, no
   IntersectionObserver, nothing on the main thread — and, critically, both sit
   inside @supports. A browser without scroll-timeline gets the static page
   with every word visible, which is the rule this project has held since the
   base layer: indexable text must never depend on a script that might not run.
   ========================================================================== */

/* ---- Reading progress -------------------------------------------------- */
.readbar {
	position: fixed;
	inset: 0 0 auto 0;
	height: 2px;
	z-index: calc(var(--z-nav) + 1);
	pointer-events: none;
	background: transparent;
}
.readbar__fill {
	display: block;
	height: 100%;
	width: 100%;
	background: var(--c-accent);
	transform: scaleX(0);
	transform-origin: 0 50%;
}

@supports (animation-timeline: scroll()) {
	.readbar__fill {
		animation: readbar-grow linear both;
		animation-timeline: scroll(root block);
	}
}
@keyframes readbar-grow {
	from { transform: scaleX(0); }
	to   { transform: scaleX(1); }
}

/* ---- Section reveal on scroll ------------------------------------------ */
/* Applied to structural blocks only, never to a bare paragraph: if support is
   ever partial, a half-revealed heading is recoverable, half-revealed body
   copy is not. */
@supports (animation-timeline: view()) {
	@media (prefers-reduced-motion: no-preference) {
		.prose > h2,
		.steps,
		.revgrid,
		.pgrid,
		.guide,
		.reviews__title,
		.logo-wall__title,
		.platforms__title {
			animation: reveal-in linear both;
			animation-timeline: view();
			/* Finishes well before the block reaches the middle of the screen,
			   so nothing is still fading while it is being read. */
			animation-range: entry 5% cover 28%;
		}
	}
}
/* TRANSFORM ONLY — deliberately no opacity.
 *
 * With animation-timeline: view(), anything below the fold sits at the START
 * of its range until it is scrolled to. Had this faded from opacity 0, every
 * H2 below the first screen would render at zero opacity for any renderer that
 * does not scroll — and headings are indexable content. Sliding without fading
 * keeps every word painted at all times and still reads as a reveal. */
@keyframes reveal-in {
	from { transform: translateY(18px); }
	to   { transform: none; }
}

/* ==========================================================================
   Steps
   --------------------------------------------------------------------------
   A numbered rail: mono numerals in a ring, joined by a dashed line. The
   numerals are a CSS counter, so reordering the steps in wp-admin cannot leave
   the numbering stale.
   ========================================================================== */
.steps {
	counter-reset: step;
	list-style: none;
	margin: var(--s-6) 0 0;
	padding: 0;
}
.steps__item {
	position: relative;
	padding: 0 0 var(--s-6) calc(var(--s-8) + var(--s-2));
	min-height: 40px;
}
.steps__item:last-child { padding-bottom: 0; }

/* The ring */
.steps__item::before {
	counter-increment: step;
	content: counter(step, decimal-leading-zero);
	position: absolute;
	left: 0;
	top: 0;
	display: grid;
	place-items: center;
	width: 40px;
	height: 40px;
	border: 1px solid var(--c-border-str);
	border-radius: var(--r-full);
	background: var(--c-bg);
	font-family: var(--font-mono);
	font-size: var(--t-xs);
	font-weight: 500;
	color: var(--c-accent-lo);
	z-index: 1;
}
/* The dashed rail, drawn between one ring and the next */
.steps__item::after {
	content: "";
	position: absolute;
	left: 19px;
	top: 40px;
	bottom: 0;
	width: 1px;
	background: repeating-linear-gradient(
		to bottom,
		var(--c-border) 0 4px,
		transparent 4px 9px
	);
}
.steps__item:last-child::after { content: none; }

.steps__title {
	margin: 0 0 var(--s-2);
	padding-top: 0.35em;
	font-family: var(--font-sans);
	font-size: var(--t-lg);
	font-weight: 700;
	letter-spacing: -0.015em;
	/* Chaptering adds a rule and a numeral to headings in .prose; steps carry
	   their own numbering, so those must not apply here. */
	border-top: 0;
}
.steps__title::before { content: none; counter-increment: none; }
.steps__text { margin: 0; color: var(--c-text-muted); max-width: 60ch; }

.band--ink .steps__item::before { background: var(--c-ink); border-color: var(--c-ink-border); color: var(--c-accent-hi); }
.band--ink .steps__text { color: var(--c-ink-muted); }

/* ---- Buying-guide rail ------------------------------------------------- */
/* The six criteria were fourteen paragraphs in an unbroken column. Same rail
   as .steps, but applied to prose already in the page rather than to a new
   component — the words are untouched, only their rhythm changes. */
.guia { counter-reset: crit; margin-top: var(--s-6); }

.guia > h3 {
	position: relative;
	margin: var(--s-7) 0 var(--s-3);
	padding-left: calc(var(--s-8) + var(--s-2));
	min-height: 40px;
	display: flex;
	align-items: center;
	font-family: var(--font-sans);
	font-size: var(--t-lg);
	font-weight: 700;
	letter-spacing: -0.015em;
}
.guia > h3::before {
	counter-increment: crit;
	content: counter(crit, decimal-leading-zero);
	position: absolute;
	left: 0; top: 0;
	display: grid;
	place-items: center;
	width: 40px; height: 40px;
	border: 1px solid var(--c-border-str);
	border-radius: var(--r-full);
	background: var(--c-bg);
	font-family: var(--font-mono);
	font-size: var(--t-xs);
	font-weight: 500;
	color: var(--c-accent-lo);
}
/* Indent the body copy to sit under its heading, and run the dashed rail down
   beside it so the six criteria read as one sequence. */
.guia > p {
	position: relative;
	margin: 0 0 var(--s-5);
	padding-left: calc(var(--s-8) + var(--s-2));
	max-width: calc(var(--maxw-text) + var(--s-8));
}
/* One unbroken rail drawn on the container. Segments-per-paragraph left a gap
   at every criterion boundary, which read as six disconnected blocks rather
   than one sequence. The numerals carry an opaque background, so they punch
   through the line cleanly. */
.guia { position: relative; }
.guia::before {
	content: "";
	position: absolute;
	left: 19px;
	top: 40px;
	bottom: var(--s-6);
	width: 1px;
	background: repeating-linear-gradient(
		to bottom,
		var(--c-border) 0 4px,
		transparent 4px 9px
	);
}

@media (max-width: 600px) {
	/* The rail costs 56px of a 360px screen. Below 600px the numeral sits
	   above the heading instead and the indent is dropped entirely. */
	.guia > h3 { display: block; padding-left: 0; padding-top: 48px; min-height: 0; }
	.guia > p  { padding-left: 0; }
	.guia::before { content: none; }
}

/* ==========================================================================
   "Por qué elegir" — claims band
   --------------------------------------------------------------------------
   Full-bleed ink. This is the persuasion moment on the page, and the ink band
   is the design's chapter break — using it here splits the long paper scroll
   in two and gives the argument the weight the old image cards never had.

   The bleed is done with margin, not 100vw: on a platform with classic
   scrollbars 100vw is WIDER than the document, which pushes a horizontal
   scrollbar onto every page. calc(50% - 50vw) against the padded container
   reaches the same edges and cannot exceed the content width.
   ========================================================================== */
.claves {
	--claves-pad: clamp(1.5rem, 0.5rem + 4vw, 4.5rem);
	list-style: none;
	margin: var(--s-7) calc(50% - 50vw) 0;
	padding: var(--section-y) max(var(--gutter), calc(50vw - var(--maxw) / 2 + var(--gutter)));
	background: var(--c-ink);
	color: var(--c-ink-text);
	display: grid;
	grid-template-columns: 1fr;
	gap: 0;
}
@media (min-width: 860px) {
	.claves { grid-template-columns: repeat(2, 1fr); }
}

.clave {
	position: relative;
	padding: var(--s-6) 0;
}
/* Hairline dividers rather than card borders — a magazine grid, not four
   boxes floating on a dark rectangle. */
@media (min-width: 860px) {
	.clave { padding: var(--s-6) var(--s-7); }
	.clave:nth-child(odd)  { padding-left: 0; }
	.clave:nth-child(even) { padding-right: 0; }
	.clave:nth-child(-n+2) { padding-top: 0; }
	.clave:nth-child(n+3)  { padding-bottom: 0; }
	/* vertical rule between the two columns */
	.clave:nth-child(even)::before {
		content: "";
		position: absolute;
		left: 0; top: var(--s-4); bottom: var(--s-4);
		width: 1px;
		background: var(--c-ink-border);
	}
	/* horizontal rule between the two rows */
	.clave:nth-child(n+3)::after {
		content: "";
		position: absolute;
		top: 0; left: 0; right: 0;
		height: 1px;
		background: var(--c-ink-border);
	}
	.clave:nth-child(even):nth-child(n+3)::after { left: var(--s-7); }
}
@media (max-width: 859px) {
	.clave + .clave { border-top: 1px solid var(--c-ink-border); }
}

.clave__title {
	margin: 0 0 var(--s-3);
	font-family: var(--font-display);
	font-weight: 400;
	font-size: var(--t-xl);
	text-transform: uppercase;
	letter-spacing: var(--ls-display);
	line-height: 1.16;
	color: var(--c-ink-text);
	max-width: 18ch;
}
.clave__text {
	margin: 0;
	color: var(--c-ink-muted);
	max-width: 46ch;
}

/* ---- Hero photograph (topic pages) ------------------------------------- */
/* Takes the same treatment as the EPG mockup it replaces, so the hero keeps
   one visual rule across the site: whatever sits in the art column is the one
   dark object on the paper page. */
.hero-ed__figure {
	margin: 0;
	border-radius: var(--r-lg);
	overflow: hidden;
	background: var(--c-ink);
	box-shadow: var(--e-3);
}
.hero-ed__photo {
	display: block;
	width: 100%;
	height: auto;
	/* Reserved before the file loads, so the headline above never jumps.
	   Must match the delivered file's ratio or object-fit crops the subject. */
	aspect-ratio: 1600 / 893;
	object-fit: cover;
}
@media (min-width: 900px) {
	/* One ratio at every width — a desktop-only crop would hide part of the
	   subject the prompt was written to put there. */
	.hero-ed__art--photo .hero-ed__photo { aspect-ratio: 1600 / 893; }
}

/* ==========================================================================
   Hero + footer corrections
   ========================================================================== */

/* THE 388px OF DEAD PAGE BELOW THE FOOTER.
   .screen__glow is absolutely positioned with a negative bottom inset. When the
   hero markup was rewritten, .hero-ed__art lost the `position: relative` its
   predecessor had — so the glow resolved against the initial containing block
   instead of the hero, and its -10% bottom dragged the document 388px past the
   footer. Containing it fixes the dead space at its source rather than capping
   the page height somewhere further down. */
.hero-ed__art { position: relative; }

/* ---- Payment strip: smaller ------------------------------------------- */
/* Was rendering 380x148 — a two-row block taller than the CTA above it, which
   made acceptance marks the loudest thing in the hero. They are reassurance,
   not the offer. */
.pay--art .pay__art { max-width: 300px; }
@media (min-width: 900px)  { .pay--art .pay__art { max-width: 272px; } }
@media (min-width: 1240px) { .pay--art .pay__art { max-width: 300px; } }
.pay { margin-top: var(--s-5); }
.pay__label { margin-bottom: var(--s-2); }

/* ---- Stats: the band under the hero ------------------------------------ */
/* Four across in one row, spanning both hero columns.
   This lived in the text column for a while and was forced to 2x2 there,
   because four items in a 466px box gave each label ~102px and "Películas y
   series" needs 173px at a readable size — so one label wrapped, one figure
   lost the shared baseline, and the row read as broken. The constraint was
   the container, not the count: across the full hero each item gets ~265px
   and all four labels sit on one line with room to spare. */
.hero-ed > .stats {
	grid-template-columns: repeat(2, minmax(0, 1fr));
	gap: var(--s-5) var(--s-6);
	margin-top: var(--s-8);
}
/* 1000px, not the 720px the generic band uses: measured, "Películas y series"
   needs 174px on one line and a quarter of the hero only reaches that at
   ~1000px. Below it the row would carry one two-line label among three
   one-liners, so it stays 2x2 rather than going four-up badly. */
@media (min-width: 1000px) {
	.hero-ed > .stats { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}
.stats__label {
	text-wrap: balance;
	hyphens: none;
}
/* The figure and its label are one unit; keep them locked together so a
   wrapped label pushes nothing else around. */
.stats__item { gap: var(--s-1); align-content: start; }

/* ---- Breadcrumbs ------------------------------------------------------- */
.crumbs { margin-bottom: var(--s-5); }
.crumbs__list {
	display: flex; flex-wrap: wrap; align-items: center;
	gap: var(--s-2);
	margin: 0; padding: 0; list-style: none;
	font-family: var(--font-mono);
	font-size: var(--t-xs);
	text-transform: uppercase;
	letter-spacing: var(--ls-label);
	color: var(--c-text-faint);
}
.crumbs__item { display: inline-flex; align-items: center; gap: var(--s-2); }
.crumbs__item + .crumbs__item::before {
	content: "/";
	color: var(--c-border-str);
}
.crumbs__item a { color: var(--c-text-faint); text-decoration: none; }
.crumbs__item a:hover { color: var(--c-accent-lo); text-decoration: underline; }
/* The current page truncates rather than wrapping the trail onto three lines. */
.crumbs__item [aria-current] {
	color: var(--c-text-muted);
	max-width: 46ch;
	overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
/* A page whose hero renders its own H1 needs the trail tucked closer. */
.section > .wrap > .crumbs { margin-top: var(--s-5); }

/* ==========================================================================
   Hero tile grid
   ==========================================================================
   Graph paper behind the hero, with a cell that lights up under the cursor.
   It gives the top of the page a texture the rest of the site does not have,
   which is the whole job: a reader should know, without reading, that they
   have landed somewhere and not on page four of a blog.

   The grid is laid out by `repeat(auto-fill, ...)`, so the markup ships a flat
   run of cells and the browser decides how many fit. No JavaScript, no
   measuring, nothing to recalculate on resize. */

.hero-ed {
	position: relative;
	/* Its own stacking context: the grid sits at z-index 0 and the content at
	   1, and neither has an opinion about anything outside the hero. */
	isolation: isolate;
}
.hero-ed > :not(.tiles) { position: relative; z-index: 1; }

/* The grid runs edge to edge while the hero itself stays inside the measure.
   100vw counts the scrollbar, so the section clips rather than scrolls — see
   the `overflow-x: clip` below, which is what makes this safe. */
.tiles {
	--tile-size: 36px;
	--tile: var(--c-accent-wash);

	position: absolute;
	top: 0;
	bottom: 0;
	left: 50%;
	width: 100vw;
	transform: translateX(-50%);
	z-index: 0;

	/* The lines are painted, not built. A fixed run of cells can only cover so
	   much area, and on a 2560px display 720 of them run out two thirds of the
	   way down — which would show as a hard horizontal edge. Painting the grid
	   on the container means it covers whatever the viewport turns out to be,
	   and the cells are left with the one job they are actually needed for:
	   being something a cursor can hover. Where they run out, the grid simply
	   stops lighting up; it never stops being drawn. */
	background-image:
		repeating-linear-gradient(to right,  var(--c-tile-line) 0 1px, transparent 1px var(--tile-size)),
		repeating-linear-gradient(to bottom, var(--c-tile-line) 0 1px, transparent 1px var(--tile-size));

	display: grid;
	grid-template-columns: repeat(auto-fill, var(--tile-size));
	grid-auto-rows: var(--tile-size);
	/* Cells start at the top-left corner so they land exactly on the painted
	   lines; centring them would offset the two by half a leftover column. */
	justify-content: start;
	align-content: start;
	overflow: hidden;

	/* Fades out over the lower half so the grid frames the headline instead of
	   running under the stats and into the section below it. */
	-webkit-mask-image: linear-gradient(to bottom, #000 0%, #000 45%, transparent 92%);
	mask-image: linear-gradient(to bottom, #000 0%, #000 45%, transparent 92%);
}

/* Gated on a real pointer. On a touch screen :hover latches after a tap, so
   an unguarded rule would leave a lit square sitting in the hero until the
   visitor happened to tap somewhere else. */
@media (hover: hover) {
	/* The fill lands the instant the cursor arrives and then takes its time
	   leaving, so a moving cursor draws a trail rather than a flicker. The
	   instant half is the :hover rule's zero duration. */
	.tiles > i { transition: background-color 1.6s ease-out; }
	.tiles > i:hover {
		background-color: var(--tile);
		transition-duration: 0s;
	}
}
@media (prefers-reduced-motion: reduce) {
	.tiles > i { transition: none; }
}
@media (min-width: 768px) {
	.tiles { --tile-size: 48px; }
}

/* 100vw is wider than the page whenever a scrollbar is present. `clip` (not
   `hidden`) contains the overflow without turning the section into a scroll
   container, which would otherwise break `position: sticky` inside it. */
.section:has(.hero-ed) { overflow-x: clip; }

/* ---- Hero art: cut-outs ------------------------------------------------
   A photograph wants the dark card — it reads as a still from the product. A
   transparent mockup does not: the card would box the cut-out and `cover`
   would crop the devices it exists to show. This variant strips both and
   grounds the art with a drop shadow that follows the actual silhouette. */
.hero-ed__figure--bare {
	background: none;
	border-radius: 0;
	box-shadow: none;
	overflow: visible;
}
.hero-ed__photo--bare {
	aspect-ratio: auto;
	object-fit: contain;
	/* Never scaled past the pixels the file actually has: this source is
	   540px wide, and letting the column stretch it would put a soft hero on
	   every retina screen. Centred instead, with the column's slack as air. */
	max-width: 540px;
	margin-inline: auto;
	/* Follows the silhouette rather than a box, which is the point of using a
	   cut-out. Light enough to read as contact shadow, not as a glow. */
	filter: drop-shadow(0 16px 26px rgb(20 20 18 / 0.16));
}
@media (min-width: 900px) {
	/* Beats `.hero-ed__art--photo .hero-ed__photo`, which pins the 1600x893
	   crop for photographic heroes. */
	.hero-ed__art--photo .hero-ed__photo--bare { aspect-ratio: auto; }
}
