/*
 * Secondary highlight banner — auto-sliding blue-gradient card.
 * Figma: node 1752:4122 "Frame 2147227089" (1112x219, sits inside
 * .tp2026-container--narrow). Image 253x179 on the left (20px inset),
 * heading + description on the right, vertical dot nav on the right
 * edge (desktop). FR-012–FR-015 / carousel functional spec.
 */

/* Figma: hero background 1752:3948 ends at y=600; this card (1752:4122)
   starts at y=670 → a 70px gap, not zero. padding-bottom is left at the
   .tp-section default (64px, inherited, not overridden here). */
.tp2026-highlight-banner {
	padding-top: 70px;
}

.tp2026-highlight-banner__card {
	position: relative;
}

/* .surface is the actual visual "card": rounded blue-gradient box that
   clips the slide media. Kept separate from .card so the dot nav can
   drop below it (outside the rounded box) on small screens without
   being clipped by overflow:hidden. */
.tp2026-highlight-banner__surface {
	position: relative;
	border-radius: var(--tp-radius-lg);
	overflow: hidden;
	/*
	 * card-bg.webp — 2224x438, the 2x fill of this card's 1112x219 box,
	 * rebuilt from Figma's own render (see card-bg.build.py alongside it).
	 * It ships as the layer *under* the ::before wash below — the 8%
	 * #456186 is divided back out of the render so the browser's own
	 * compositing puts it back, instead of applying it twice.
	 *
	 * An earlier comment here claimed the dot texture was a client addition
	 * with no counterpart in the .fig. That was wrong, and it was reading the
	 * wrong layer: 1422:21196's fill really is a flat two-stop gradient, but
	 * 1422:39784 sits on top of it carrying a halftone CUSTOM effect at 8%
	 * layer opacity. Custom effects don't survive an SVG export — which is
	 * where the "no texture" reading came from — but they do render, so the
	 * texture is in the design. (The mobile block further down already had
	 * this right.) The client's own file agreed in intent and differed only
	 * in amplitude and mean colour; it is kept as card-bg.webp.bak-*.
	 *
	 * The halftone is colour-separated like a print screen: R, G and B each
	 * get their own dot lattice, all at a 12px pitch in 2x but at 29.5 /
	 * 89.5 / 14.5 degrees, so a bright red dot lands on flat blue. That is
	 * why this is a bitmap and not a CSS pattern — three screens at three
	 * angles have no common tile that repeats on whole pixels.
	 *
	 * The linear-gradient stays underneath as a fallback in the same
	 * declaration, so a failed image load still shows Figma's own ramp
	 * rather than a blank or mismatched surface. background-size:cover
	 * preserves the image's aspect ratio at any card width instead of
	 * stretching it.
	 */
	background-image:
		url('../images/highlight-banner/card-bg.webp'),
		linear-gradient(180deg, #1977f3 -66.1%, #0f4792 194.2%);
	background-size: cover;
	background-position: center;
	background-repeat: no-repeat;
}

/* Figma 1422:39784 — a second full-card rectangle, #456186 at 8% opacity,
   sitting over the gradient as a subtle darkening wash. Layered as a
   pseudo-element rather than a second background so it composites exactly
   like Figma's separate shape (a background-color would just flatten into
   the gradient's own colour space). */
.tp2026-highlight-banner__surface::before {
	content: '';
	position: absolute;
	inset: 0;
	z-index: 1;
	background: #456186;
	opacity: 0.08;
	pointer-events: none;
}

.tp2026-highlight-banner__track {
	position: relative; /* stack above ::before's tint wash (z-index 1) */
	z-index: 2;
	display: grid;
}

.tp2026-highlight-banner__slide {
	grid-area: 1 / 1;
	display: flex;
	align-items: center;
	/* Figma 1381:40272 image at x=20 w=253, text frame 1381:40269 at x=297
	   w=703 inside the 1112 card → 24 gap, 20 left inset, 112 right gutter
	   for the dot rail. */
	gap: 24px;
	padding: 20px 112px 20px 20px;
	opacity: 0;
	pointer-events: none;
	/* Figma 1752:4122 — DISSOLVE 300ms OUT_CUBIC. The only dissolve authored
	   on this component; it drives the slide cross-fade here. */
	transition: opacity var(--tp-speed-fast) var(--tp-ease);
}

.tp2026-highlight-banner__slide.is-active {
	opacity: 1;
	pointer-events: auto;
}

.tp2026-highlight-banner__media {
	flex: 0 0 auto;
	width: 253px;
	height: 179px;
	border-radius: 20px; /* Figma 1381:40272 */
	overflow: hidden;
}

/* <picture> is inline by default, so it would sit on a text baseline and
   leave a few px of descender gap under the photo inside the rounded frame. */
.tp2026-highlight-banner__media picture {
	display: block;
	width: 100%;
	height: 100%;
}

.tp2026-highlight-banner__media img {
	width: 100%;
	height: 100%;
	object-fit: cover;
}

/* Next-slide disc — mobile only (Figma 2225:2620). Hidden here rather than
   omitted from the markup so the breakpoint stays a CSS decision. */
.tp2026-highlight-banner__next {
	display: none;
}

.tp2026-highlight-banner__body {
	display: flex;
	flex-direction: column;
	gap: 15px; /* Figma 1381:40269 stack gap */
	color: var(--tp-white);
	min-width: 0;
}

.tp2026-highlight-banner__heading {
	font: var(--tp-subhead); /* Figma 1381:40270 — Medium 24/34 */
	/*
	 * --tp-subhead bakes in an absolute 34px leading. The breakpoints below
	 * step font-size down to 22px and 20px but cannot reach the shorthand's
	 * line-height, so the leading would stay at 34px and the heading's lines
	 * would drift apart on mobile (the same token trap that split the hero
	 * headline). Restated as the 34/24 ratio: identical at desktop, scales
	 * with the font everywhere else.
	 */
	line-height: 1.4167;
	color: var(--tp-white);
	text-transform: capitalize; /* Figma 1381:40270 textCase=TITLE */
	text-decoration-color: transparent;
	transition: text-decoration-color var(--tp-speed-fast) var(--tp-ease);
}

.tp2026-highlight-banner__desc {
	font: var(--tp-body);
	color: var(--tp-white); /* Figma 1381:40271 — full-opacity white */
	text-transform: capitalize; /* Figma 1381:40271 textCase=TITLE */
	/*
	 * Both engines put this paragraph's BOX at y=115 in the 219px card
	 * (Figma node 1381:40271; measured identical here), but they disagree
	 * on where the glyphs sit inside a 16/24 line box: a 2x render diffed
	 * against Figma's own export puts every one of the three lines exactly
	 * 1.00px higher in Chrome (per-line cross-correlation minima: -0.98,
	 * -0.99, -0.99). The 24/34 heading above it lands at -0.01px, so this
	 * is specific to the body's size/leading pair, not a block offset.
	 * Nudged down 1px with a compensating negative bottom margin so the
	 * flex column's own height stays 155px — otherwise the whole block
	 * would re-centre and drag the heading (currently exact) off by 0.5px.
	 */
	margin-top: 1px;
	margin-bottom: -1px;
}

/*
 * `text-transform: capitalize` uppercases the first letter of every word and
 * leaves the rest alone, which turns "iOS" into "IOS". The FRD's own figure
 * shows "Native iOS And Android", so the acronym is opted out of the
 * transform rather than the whole line losing its Figma title case.
 */
.tp2026-highlight-banner__heading .tp2026-highlight-banner__literal,
.tp2026-highlight-banner__desc .tp2026-highlight-banner__literal {
	text-transform: none;
}

/*
 * Emphasis inside a heading — the Connected Britain slide sets the event
 * name apart from the "ThinkPalm Is Heading To" lead-in. 700 against the
 * heading's own 500; Plus Jakarta Sans is loaded at both weights, so this
 * is a real cut rather than a synthesised bold. Inherits the hover
 * underline from the heading, so the whole line still underlines as one.
 */
.tp2026-highlight-banner__heading .tp2026-highlight-banner__strong {
	font-weight: 700;
}

/* FR-013: whole card is clickable; hover reveals an underline under
   the heading to signal that. Client-supplied hover spec applied below
   verbatim, with one deliberate omission: `font-size: 24px`. The base
   heading is already 24px at desktop, but the responsive breakpoints
   step it down to 22px (<=1024) and 20px (<=425) — hard-coding 24px
   here would make the text visibly jump size on hover at those widths.
   Every other declaration in the spec is constant across breakpoints,
   so they are safe to state explicitly. */
.tp2026-highlight-banner__slide:hover .tp2026-highlight-banner__heading,
.tp2026-highlight-banner__slide:focus-visible .tp2026-highlight-banner__heading {
	color: #fff;
	font-family: 'Plus Jakarta Sans';
	font-style: normal;
	font-weight: 500;
	line-height: 1.4167; /* 141.667% — ratio, not 34px, per the base rule */
	text-decoration-line: underline;
	text-decoration-style: solid;
	text-decoration-color: currentColor;
	text-decoration-skip-ink: auto;
	/* `auto` resolves to the font's own (chunky ~3px at 24px) underline in
	   Chromium; Figma 2035:1928 renders a noticeably finer rule. Measured
	   off Figma's own 2x export of the hover variant, the rule integrates
	   to 1.02px of ink (row intensities 111/172/66 over y=63.0-64.0).
	   1.5px does NOT render as 1.5 — Blink rounds decoration thickness to
	   whole CSS pixels, so it came out a solid 2.06px, double the design.
	   1px is both the honest value and what Blink actually draws. */
	text-decoration-thickness: 1px;
	text-underline-offset: auto;
	text-underline-position: from-font;
	text-transform: capitalize;
}

.tp2026-highlight-banner__slide:focus-visible {
	outline: 2px solid var(--tp-white);
	outline-offset: -4px;
}

/* Dot navigation — vertical column on the card's right edge (desktop).
   Figma 1446:2916: a 24px-wide rail whose right edge sits 24px in from the
   card's right edge (rail x=1064..1088 in the 1112 card). It is NOT bare
   dots — Rectangle 3 behind them is a full-height pill, #ffffff at 16%
   opacity, fully rounded. The dot column itself (Frame 2147226543) is 12px
   wide, so it's inset 6px on every side of the 24px capsule; at 4 dots that
   yields the capsule's ~75px height, but the padding approach below scales
   correctly to however many dots the slide count produces. */
.tp2026-highlight-banner__dots {
	position: absolute;
	top: 50%;
	right: 24px;
	transform: translateY(-50%);
	width: 24px;
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: 5px;
	padding: 6px 0;
	background: rgba(255, 255, 255, 0.16);
	border-radius: var(--tp-radius-pill);
	z-index: 2;
}

/* Bare <li>, flex-blockified as an item of the <ul> above, still opens an
   inline formatting context for its button — which pads it out to the
   page's 24px line-height (a 12px extra per dot: 5 dots = 60px of drift).
   Making the <li> itself a flex box collapses it straight to the button's
   own 12px, which is what let the capsule's height overshoot Figma's by
   60px+ above. */
.tp2026-highlight-banner__dots li {
	display: flex;
}

.tp2026-highlight-banner__dot {
	position: relative;
	width: 12px;
	height: 12px;
	border-radius: 50%;
	border: 1px solid var(--tp-white); /* Figma 1446:2921–2923 */
	background: transparent;
	padding: 0;
	transition: background var(--tp-speed-fast) var(--tp-ease), border-color var(--tp-speed-fast) var(--tp-ease), transform var(--tp-speed-fast) var(--tp-ease);
}

/* Invisible expanded hit area so the small dot stays comfortably tappable. */
.tp2026-highlight-banner__dot::after {
	content: '';
	position: absolute;
	inset: -10px;
}

.tp2026-highlight-banner__dot:hover {
	border-color: var(--tp-white);
	transform: scale(1.1);
}

.tp2026-highlight-banner__dot:focus-visible {
	outline: 2px solid var(--tp-white);
	outline-offset: 2px;
}

/* Deliberate deviation, do not "fix": in Figma the filled dot sits at the
   BOTTOM of the rail, but only as a side effect of how it was drawn — the
   whole rail is rotated 180deg and `Ellipse 1` (the filled one) is first in
   layer order, i.e. it is still dot 1, just painted upside down. Copying
   the rendered position would put the indicator at the bottom while slide 1
   is showing, decoupling it from the visible slide. Ours tracks the slide,
   so the active dot starts at the top and walks down. */
.tp2026-highlight-banner__dot.is-active {
	background: var(--tp-white);
	border-color: var(--tp-white);
}

/* Responsive breakpoints reference (Figma frame = 1440):
   1440 desktop / 1024 small-desktop / 768 tablet / 425,375,320 mobile */
@media (max-width: 1024px) {
	/* Same 0.75x scale base.css uses for .tp-section (64px -> 48px). */
	.tp2026-highlight-banner {
		padding-top: 52px;
	}

	.tp2026-highlight-banner__slide {
		gap: 24px;
		padding-right: 84px;
	}

	.tp2026-highlight-banner__heading {
		font-size: 22px;
	}
}

/*
 * Mobile card — Figma 2221:2571 in the 360px frame "homepage thinkpalm
 * mobile". Nothing here is a scaled-down desktop card: the photo goes
 * full-width above the copy, the dot rail turns into a horizontal pill in
 * the bottom-left corner, and a next-slide disc appears opposite it. Box
 * (all figures are Figma's, card origin x=20 y=470, 320x417):
 *   photo   x32  y482  296x144  r12   (12px inset all round)
 *   heading x40  y646  280x72   16/24 (3 lines)
 *   desc    x40  y734  280x80   12/16 (5 lines)
 *   nav row x40  y833  280x34         (20px above the card's bottom edge)
 */
@media (max-width: 768px) {
	/*
	 * Figma puts the card's top edge at y=470 inside a 544px hero — it
	 * overlaps the hero's bottom 74px instead of clearing it. A negative
	 * margin does that without touching the hero's own box; z-index lifts
	 * the card over the hero video, which paints in its own stacking
	 * context and would otherwise cover it.
	 */
	.tp2026-highlight-banner {
		position: relative;
		z-index: 2;
		margin-top: -74px;
		padding-top: 0;
		/* Figma: card bottom y=887, the next section's first text at y=951 →
		   a 64px gap. business-stats already contributes 40px of .tp-section
		   padding-top, so this side only owes the remaining 24. */
		padding-bottom: 24px;
	}

	.tp2026-highlight-banner__surface {
		border-radius: 16px; /* 2221:2549 */
		/*
		 * card-bg.webp is a 2224x438 export of the DESKTOP card. Cover-fitting
		 * it into a 320x417 portrait box crops out a narrow vertical slice of
		 * its middle, which lands nowhere near the mobile design's top-to-
		 * bottom gradient, so mobile paints Figma's own fill instead.
		 *
		 * 2221:2549's gradient is #1977F3 -> #0F4792, but its handles run from
		 * y=-66.21% to y=194.09% of the card, so the card only shows the slice
		 * between t=0.2544 and t=0.6385 of that ramp — never the pure end
		 * colours. Those two interpolated colours are stated directly here;
		 * quoting the raw stops with out-of-range percentages instead lets CSS
		 * clamp the top 63% of the card to flat #1977F3, which is 6-11 levels
		 * per channel too light.
		 */
		background-image: linear-gradient(180deg, rgb(22, 107, 218) 0%, rgb(19, 88, 181) 100%);
	}

	/*
	 * The second full-card rectangle (2221:2543) is not the flat #456186 wash
	 * the desktop rule assumes — same fills as the card beneath it, carrying a
	 * halftone-dot *effect* at 8% layer opacity (dotSize 6, scale 0.75, 14.5deg).
	 * Measured against Figma's own render, that layer's net contribution is an
	 * even 8% darkening (bottom of the card matches 0.92x the gradient to the
	 * level), with the dots themselves too faint to read at 1x. Reproduced as
	 * a flat 8% black rather than a CSS dot pattern: same result, no texture
	 * that would have to be kept in sync with the gradient underneath it.
	 */
	.tp2026-highlight-banner__surface::before {
		background: #000;
	}

	/*
	 * Vertical card: 12px photo inset, and a bottom band reserved for the
	 * absolutely-placed nav row — 19px gap + 34px row + 20px inset = 73.
	 */
	.tp2026-highlight-banner__slide {
		flex-direction: column;
		align-items: stretch;
		gap: 20px; /* photo bottom y=626 → text frame y=646 */
		padding: 12px 12px 73px;
	}

	/*
	 * Observation 003: with one slide the dot capsule and the next disc are
	 * never printed, so the 73px band reserved for that row would sit under
	 * the copy as empty blue. Falls back to the 20px bottom inset the row
	 * itself used (2225:2620), keeping the card's own edge spacing.
	 */
	.tp2026-highlight-banner__card.is-single .tp2026-highlight-banner__slide {
		padding-bottom: 20px;
	}

	.tp2026-highlight-banner__media {
		width: auto;
		max-width: none;
		/* 296x144 at the 360px design width, and the same ratio at every other
		   one — a fixed 144px height would stretch into a 5:1 letterbox strip
		   by the time the card is 728px wide at the 768 breakpoint. */
		height: auto;
		aspect-ratio: 296 / 144;
		border-radius: 12px; /* 2221:2570 */
	}

	.tp2026-highlight-banner__body {
		/* 12px of slide padding + 8 = the 20px text inset of 2221:2574
		   (x=40 in a card whose left edge is x=20). */
		margin: 0 8px;
		gap: 16px; /* 2221:2574 stack gap */
		/*
		 * With the box landing on Figma's y=646 exactly, the glyphs still came
		 * out 1px high in both text blocks (cap-tops measured 7px below the box
		 * top in Figma's render, 6px in Chrome's) — the two engines split a
		 * line box's leading slightly differently. Nudged rather than left
		 * alone because the glyphs are the visible part; `relative` keeps the
		 * flow, and the gap either side of the block absorbs the 1px.
		 */
		position: relative;
		top: 1px;
	}

	/* 2221:2567 — Plus Jakarta Sans Medium 16/24, three lines. */
	.tp2026-highlight-banner__heading {
		font-size: 16px;
		line-height: 24px;
	}

	/* 2221:2568 — Regular 12/16, five lines. */
	.tp2026-highlight-banner__desc {
		font-size: 12px;
		line-height: 16px;
		/* The desktop rule's 1px leading nudge is measured for 16/24 against
		   1381:40271. Here the type is 12/16 and the whole block is already
		   nudged by .__body above, so it must not apply a second time. */
		margin-top: 0;
		margin-bottom: 0;
	}

	/*
	 * The dot rail comes back inside the card, bottom-left, and turns
	 * horizontal. Figma 2221:2575 draws it as a 63.31x20.26 white-@16%
	 * capsule (Rectangle 3) holding 10.13px dots on a 14.35px pitch — so
	 * 4.22px of gap and 5.07px of padding. `bottom` centres the 20.26px
	 * capsule on the 34px row the next button defines: 20 + (34-20.26)/2.
	 */
	.tp2026-highlight-banner__dots {
		position: absolute;
		top: auto;
		right: auto;
		left: 20px;
		bottom: 26.87px;
		transform: none;
		width: auto;
		flex-direction: row;
		align-items: center;
		gap: 4.22px;
		padding: 5.07px;
		background: rgba(255, 255, 255, 0.16);
	}

	/* Still white-on-blue here, unlike the old build where the row dropped
	   onto the white page background and had to be recoloured. */
	.tp2026-highlight-banner__dot {
		width: 10.13px;
		height: 10.13px;
		border-width: 0.84px; /* 2221:2580-2582 stroke 0.844 */
	}

	/* 2225:2620 — 34px white disc, #1977F3 chevron, 20px in from the card's
	   bottom-right corner (mirroring the dot capsule's 20px left inset). */
	.tp2026-highlight-banner__next {
		display: flex;
		align-items: center;
		justify-content: center;
		position: absolute;
		right: 20px;
		bottom: 20px;
		width: 34px;
		height: 34px;
		padding: 0;
		border: 0;
		border-radius: 50%;
		background: var(--tp-white);
		color: #1977f3;
		cursor: pointer;
		z-index: 2;
	}

	.tp2026-highlight-banner__next:focus-visible {
		outline: 2px solid var(--tp-white);
		outline-offset: 2px;
	}
}

@media (prefers-reduced-motion: reduce) {
	.tp2026-highlight-banner__slide,
	.tp2026-highlight-banner__dot {
		transition: none;
	}
}
