/**
 * Shared carousel navigation: the countdown pill dots (the prev/next arrows
 * were removed in the 2026-09 client round — the dots are the whole nav now).
 * Registered in inc/hooks/enqueue.php and enqueued from the
 * render.php of any block that switches into carousel mode, so pages without a
 * carousel never load it.
 *
 * The nav sits AFTER the carousel element rather than inside it: Slick turns
 * every child of its root into a slide, so the dots host lives in an external
 * container the runtime fills — DOM order matches visual order and tab order
 * matches both.
 *
 * Hidden until the JS adds .is-ready: with JS off the block renders its static
 * design layout and an empty nav would just be dead space.
 */
.hp-carousel-nav {
	--hp-nav-gap: 24px;

	position: relative; /* anchors the pause toggle when it is focused */
	display: none;
	align-items: center;
	justify-content: center;
	gap: var(--hp-nav-gap);
	margin-top: 56px;
}

.hp-carousel-nav.is-ready {
	display: flex;
}

/* Dots — built by assets/js/carousels.js (never by slick: slick rebuilds its
   dots on every breakpoint re-init, which would wipe the countdown state).
   The active dot widens into a pill holding a countdown fill that slides in
   from the left over the autoplay interval (veed.io reference). The dot→pill
   width change is a 0.2s transition — a documented exception to the
   transform/opacity rule (see CLAUDE.md): the reflow is confined to the
   six-dot row re-centring, and the instant swap it replaces read as jank. */
.hp-carousel-nav__dots {
	display: flex;
	align-items: center;
	justify-content: center;
	/* 0, not Figma's 14px: each dot gained 8px of transparent padding a side to
	   reach its 24x24 target, so a 14px gap would have pushed the optical
	   spacing to 30px and visibly widened the row. At 0 the pips read 16px
	   apart -- within 2px of the design -- while the hit areas stay 24px and
	   never overlap. */
	gap: 0;
}

/*
 * The pip stays 8px; the TARGET around it is 24x24 (WCAG 2.2 SC 2.5.8, which
 * the old 8x8 button failed by size AND by the 22px spacing exception). The box
 * is grown with transparent padding and the pip drawn as a background, so the
 * design is untouched while the hit area triples.
 *
 * Opacity 0.45, not the 0.25 this used to sit at: black at 0.25 over paper is
 * 1.84:1, and a control's own shape has to reach 3:1 (SC 1.4.11). 0.45 lands at
 * 3.4:1 -- the smallest change that clears the bar.
 */
.hp-carousel-dot {
	position: relative;
	display: block;
	box-sizing: content-box;
	width: 8px;
	height: 8px;
	padding: 8px;
	border: 0;
	background: none;
	font-size: 0;
	cursor: pointer;
}

.hp-carousel-dot::before {
	content: "";
	position: absolute;
	inset: 8px;
	border-radius: 4px;
	background: var(--hp-color-ink);
	opacity: 0.45;
}

.hp-carousel-dot:hover::before {
	opacity: 0.7;
}

/*
 * The ring goes INSIDE the 24px tap target. The dot row sits at gap 0 (each
 * 8px pip carries 8px of transparent padding a side, for WCAG 2.2 SC 2.5.8),
 * so an outward ring would overlap its neighbour's target. A negative offset
 * plus a pill radius turns the global ring from assets/css/focus.css into a
 * tight circle around the pip — a stadium around the current slide's 32px
 * pill. It sits on the BUTTON, not the pip, so the pip's own opacity change
 * can never fade the indicator in.
 */
.hp-carousel-dot:focus-visible {
	border-radius: 999px;
	outline-offset: calc(-2 * var(--hp-focus-width));
}

.hp-carousel-dot:focus-visible::before {
	opacity: 0.7;
}

/* The current slide's dot becomes the countdown pill: a faint track whose
   fill grows left-to-right in sync with the autoplay timer (one clock — see
   carousels.js setupAutoplay). */
.hp-carousel-dot.is-active {
	width: 32px;
}

/* Countdown track. Was rgba(0,0,0,.2) = 1.61:1; raised for SC 1.4.11. */
.hp-carousel-dot.is-active::before {
	border-radius: 4px;
	background: rgba(0, 0, 0, 0.45);
	opacity: 1;
}

/* inset matches the button's padding, not 0: the target box is 24px now, and
   the countdown has to fill the 8px pip inside it.

   The fill is a rounded MASK holding a full-size bar that slides in with
   translateX, not a bar scaled up with scaleX: scaling squashes the border
   radius with it, so an early countdown rendered as a ~2px square-cornered
   black sliver poking past the track's rounded cap (client flagged it). The
   sliding bar keeps its geometry, so the leading edge is always a soft
   rounded cap emerging from the track's own curve. Still transform-only. */
.hp-carousel-dot__fill {
	position: absolute;
	inset: 8px;
	overflow: hidden;
	border-radius: 4px;
}

.hp-carousel-dot__fill::before {
	content: "";
	position: absolute;
	inset: 0;
	border-radius: 4px;
	background: var(--hp-color-ink);
	/* -101%, not -100%: keeps the bar's antialiased right edge from bleeding
	   a hairline into the mask while parked. */
	transform: translateX(-101%);
}

/* No countdown running (autoplay off, reduced motion, or paused out of a
   cycle): the pill reads solid. */
.hp-carousel-dot.is-active:not(.is-counting) .hp-carousel-dot__fill::before {
	transform: translateX(0);
}

@keyframes hp-dot-countdown {
	from {
		transform: translateX(-100%);
	}

	to {
		transform: translateX(0);
	}
}

/* Press feedback, fades and the countdown are motion, so they stay behind the
   gate. The controls themselves work identically with reduced motion on. */
@media (prefers-reduced-motion: no-preference) {
	.hp-carousel-dot {
		transition: opacity 0.2s ease, transform 0.16s ease, width 0.2s ease;
	}

	.hp-carousel-dot.is-active.is-counting .hp-carousel-dot__fill::before {
		animation: hp-dot-countdown var(--hp-carousel-interval, 6000ms) linear forwards;
	}

	/* Must out-specify the animation shorthand above (which resets
	   play-state to running), or pausing never freezes the fill. */
	.hp-carousel-nav.is-paused .hp-carousel-dot.is-active.is-counting .hp-carousel-dot__fill::before {
		animation-play-state: paused;
	}
}

/* Pause/play toggle (SC 2.2.2) — built by carousels.js for autoplaying
   carousels.
 *
 * Visually hidden by design decision: the glyph was pulling the nav row
 * ~38px off centre and reads as clutter next to the dots. It is NOT removed —
 * it stays in the DOM, in tab order, and unhides on keyboard focus (the
 * skip-link pattern), so keyboard and screen-reader users keep the mechanism.
 *
 * KNOWN GAP: a sighted mouse or touch user who wants to stop the motion cannot
 * find it. Hover pause still covers mouse; touch has nothing. Re-read the
 * SC 2.2.2 note in CLAUDE.md before relying on this on a client that has an
 * accessibility obligation. */
.hp-carousel-nav__pause:not(:focus-visible) {
	position: absolute;
	width: 1px;
	height: 1px;
	margin: -1px;
	overflow: hidden;
	clip-path: inset(50%);
	white-space: nowrap;
}

.hp-carousel-nav__pause:focus-visible {
	position: absolute;
	top: 50%;
	right: 0;
	transform: translateY(-50%);
}

.hp-carousel-nav__pause {
	display: flex;
	align-items: center;
	justify-content: center;
	width: 32px;
	height: 32px;
	padding: 0;
	border: 0;
	border-radius: 50%;
	background: none;
	color: var(--hp-color-ink);
	cursor: pointer;
	opacity: 0.5;
}

.hp-carousel-nav__pause:hover,
.hp-carousel-nav__pause:focus-visible {
	opacity: 1;
}

/* Inverted disc, the theme's icon-button focus language. The button is already
   a 32px circle, so nothing has to move; its glyphs are fill="currentColor",
   so `color` inverts them. `background` (the shorthand) overrides the base
   `none`. Nothing here transitions, so the swap is instant. */
.hp-carousel-nav__pause:focus-visible {
	outline: none;
	background: var(--hp-focus-color);
	color: var(--hp-focus-contrast);
}

.hp-carousel-nav__pause-glyph--play,
.hp-carousel-nav.is-user-paused .hp-carousel-nav__pause-glyph--pause {
	display: none;
}

.hp-carousel-nav.is-user-paused .hp-carousel-nav__pause-glyph--play {
	display: block;
}

@media (max-width: 768px) {
	.hp-carousel-nav {
		--hp-nav-gap: 16px;

		margin-top: 40px;
	}
}
