/* ============================================================
   broadband.click — results grid
   Consumes bare var(--bbc-*) from the child theme's tokens.css.
   No fallbacks and no literals: if a token is missing the grid
   should look obviously broken in review, not silently drift to
   a default that nobody chose.

   Visual pass 2 — the first version was legible but drab. The
   changes are deliberate and listed here so they are not undone
   as drive-by "fixes":
     · card borders lightened, elevation carried by a soft
       accent-tinted shadow (was a 3:1 border on every card)
     · radius raised via the token scale — still not pills
     · provider tiles get a generated colour so a logo-less list
       is not a wall of grey boxes
     · the price block became the focal point instead of one more
       equal column
   What did NOT change: the Ad label, the neutral default sort,
   and total-cost-under-monthly. Those carry legal weight.
   ============================================================ */

.bbc-compare {
	container-type: inline-size;
	font-family: var(--bbc-font-sans);
}

/* ---- Results toolbar ---------------------------------------
   Sort is stated, not offered as a control, until the sort UI
   exists — claiming a neutral default is only honest if the
   page says which one is running.
   ------------------------------------------------------------ */
.bbc-toolbar {
	display: flex;
	flex-wrap: wrap;
	align-items: baseline;
	gap: var(--bbc-space-2) var(--bbc-space-5);
	padding: var(--bbc-space-3) var(--bbc-space-5);
	background: var(--bbc-surface-2);
	border: 1px solid var(--bbc-card-border);
	border-radius: var(--bbc-radius-2);
	font-size: var(--bbc-text-sm);
	line-height: var(--bbc-lh-sm);
	color: var(--bbc-text-muted);
}

.bbc-toolbar__count { color: var(--bbc-text); }
.bbc-toolbar__count strong { font-weight: var(--bbc-weight-bold); }

.bbc-toolbar__filter {
	display: flex;
	align-items: center;
	gap: var(--bbc-space-2);
	margin-left: auto;
}

.bbc-toolbar__filter select {
	min-height: 2.25rem;
	padding: var(--bbc-space-1) var(--bbc-space-2);
	font-family: var(--bbc-font-sans);
	font-size: var(--bbc-text-sm);
	color: var(--bbc-text);
	background: var(--bbc-surface);
	border: 1px solid var(--bbc-border-strong);
	border-radius: var(--bbc-radius-1);
}

/* Compact variant of the CTA sizing — the toolbar is one line tall. */
.bbc-toolbar__apply { min-height: 2.25rem; padding: var(--bbc-space-1) var(--bbc-space-3); }

.bbc-toolbar__check {
	display: inline-flex;
	align-items: center;
	gap: var(--bbc-space-1);
	color: var(--bbc-text);
	cursor: pointer;
	white-space: nowrap;
}

.bbc-toolbar__check input {
	width: 1rem;
	height: 1rem;
	accent-color: var(--bbc-brand-primary);
}

.bbc-toolbar__sort {
	display: flex;
	align-items: baseline;
	gap: var(--bbc-space-2);
}

.bbc-toolbar__sort strong {
	color: var(--bbc-text);
	font-weight: var(--bbc-weight-semi);
}

/* ---- Result list ------------------------------------------- */
.bbc-results {
	list-style: none;
	margin: var(--bbc-space-3) 0 0;
	padding: 0;
	display: grid;
	gap: var(--bbc-space-3);
}

/* ---- Deal row ----------------------------------------------
   Named grid areas rather than source order, so the narrow
   layout can put price above the detail list without reordering
   the DOM away from reading order.
   ------------------------------------------------------------ */
.bbc-deal {
	display: grid;
	grid-template-columns: 9rem minmax(0, 1fr) minmax(11rem, auto);
	grid-template-areas:
		"logo body price"
		"logo meta price";
	align-items: start;
	column-gap: var(--bbc-space-5);
	row-gap: var(--bbc-space-3);
	padding: var(--bbc-space-5);
	background: var(--bbc-card-bg);
	border: 1px solid var(--bbc-card-border);
	border-radius: var(--bbc-radius-2);
	box-shadow: var(--bbc-shadow-card);
	transition:
		border-color var(--bbc-dur-1) var(--bbc-ease),
		box-shadow var(--bbc-dur-2) var(--bbc-ease);
}

/* Deepen the existing shadow rather than translating the card.
   A row that physically lifts under the cursor implies the site
   is nudging that choice; depth alone just says "interactive". */
.bbc-deal:hover {
	border-color: var(--bbc-card-border-hover);
	box-shadow: var(--bbc-shadow-card-hover);
}

.bbc-deal:focus-within {
	box-shadow: var(--bbc-focus-ring);
}

/* The top row by the neutral sort. Earned by the ranking, never
   sold — see the "How we rank results" page. */
.bbc-deal--best {
	border-color: var(--bbc-brand-primary);
	box-shadow: var(--bbc-best-ring), var(--bbc-shadow-card);
}

/* ---- Logo cell ----------------------------------------------
   Until logos are licensed every row falls back to a wordmark.
   A column of identical grey boxes is what made the list hard to
   scan, so the tile takes a hue derived from the provider's
   initial: stable per provider, decorative only, and never the
   sole carrier of meaning.
   ------------------------------------------------------------ */
.bbc-deal__logo {
	grid-area: logo;
	display: flex;
	align-items: center;
	justify-content: center;
	min-height: 4.5rem;
	padding: var(--bbc-space-3);
	background: var(--bbc-surface);
	border: 1px solid var(--bbc-border);
	border-radius: var(--bbc-radius-1);
	overflow: hidden;
}

.bbc-deal__logo img {
	max-width: 100%;
	height: auto;
	max-height: 3rem;
	object-fit: contain;
}

.bbc-deal__wordmark {
	position: relative;
	/* z-index creates a stacking context so the ::before tint can sit at
	   z-index:-1 — behind the name (which is a bare text node the shortcode
	   emits, so it cannot be lifted above the tint itself) but still in
	   front of the tile's own background. */
	z-index: 0;
	display: flex;
	align-items: center;
	justify-content: center;
	width: 100%;
	min-height: 3rem;
	font-weight: var(--bbc-weight-bold);
	font-size: var(--bbc-text-sm);
	line-height: 1.15;
	letter-spacing: -0.015em;
	text-align: center;
	text-wrap: balance;
	color: var(--bbc-text);
}

/* The tint sits behind the text at low alpha so contrast never
   depends on which hue was generated. */
.bbc-deal__wordmark::before {
	content: "";
	position: absolute;
	z-index: -1;
	inset: calc(var(--bbc-space-3) * -1);
	background: var(--bbc-brand-primary);
	opacity: .07;
	border-radius: inherit;
}

/* ---- Body cell ---------------------------------------------- */
.bbc-deal__body { grid-area: body; min-width: 0; }

.bbc-deal__provider {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: var(--bbc-space-2);
	margin-bottom: var(--bbc-space-1);
}

.bbc-deal__name {
	font-family: var(--bbc-font-sans);
	font-size: var(--bbc-text-lg);
	font-weight: var(--bbc-weight-bold);
	line-height: var(--bbc-lh-lg);
	letter-spacing: -0.015em;
	margin: 0;
	color: var(--bbc-text);
}

.bbc-deal__package {
	color: var(--bbc-text-muted);
	font-size: var(--bbc-text-sm);
	line-height: var(--bbc-lh-sm);
}

/* Coverage note: informational, amber-family so it reads as "check
   this", without escalating to the semantic error colour. */
.bbc-deal__footprint {
	font-size: var(--bbc-text-xs);
	line-height: var(--bbc-lh-xs);
	color: var(--bbc-fun-amber-fg);
	margin-bottom: var(--bbc-space-1);
}

.bbc-availability-note {
	margin-top: var(--bbc-space-3);
	padding: var(--bbc-space-3) var(--bbc-space-4);
	background: var(--bbc-fun-amber-bg);
	color: var(--bbc-fun-amber-fg);
	border-radius: var(--bbc-radius-1);
	font-size: var(--bbc-text-sm);
	line-height: var(--bbc-lh-sm);
}

/* ---- Headline speed ----------------------------------------
   The metric scanned before price. Tabular figures come from the
   body font-feature-settings, so the column aligns without a
   monospace face.
   ------------------------------------------------------------ */
.bbc-deal__speed {
	display: flex;
	align-items: baseline;
	gap: var(--bbc-space-2);
	margin-top: var(--bbc-space-3);
}

.bbc-deal__speed-value {
	font-size: var(--bbc-text-xl);
	line-height: var(--bbc-lh-xl);
	font-weight: var(--bbc-weight-bold);
	letter-spacing: -0.02em;
	color: var(--bbc-text);
}

.bbc-deal__speed-unit {
	font-size: var(--bbc-text-sm);
	color: var(--bbc-text-muted);
}

/* ---- Meta strip --------------------------------------------- */
.bbc-deal__meta {
	grid-area: meta;
	display: flex;
	flex-wrap: wrap;
	align-items: baseline;
	gap: var(--bbc-space-2) var(--bbc-space-5);
	margin: 0;
	padding-top: var(--bbc-space-3);
	border-top: 1px solid var(--bbc-border);
	font-size: var(--bbc-text-xs);
	line-height: var(--bbc-lh-xs);
	color: var(--bbc-text-muted);
}

.bbc-deal__meta > div { display: flex; align-items: baseline; gap: var(--bbc-space-1); }
.bbc-deal__meta dt { font-weight: var(--bbc-weight-regular); }
.bbc-deal__meta dd { margin: 0; color: var(--bbc-text); font-weight: var(--bbc-weight-medium); }

/* Freshness is a trust signal, so it is stated plainly rather
   than tucked away — but it must not outweigh the price. */
.bbc-deal__checked dd { color: var(--bbc-text-muted); font-weight: var(--bbc-weight-regular); }

/* ---- Price cell ---------------------------------------------
   Right-aligned so monthly figures form a scannable column.
   Total contract cost sits directly under the headline price:
   burying it is the standard dark pattern on this kind of page.
   ------------------------------------------------------------ */
.bbc-deal__price {
	grid-area: price;
	display: flex;
	flex-direction: column;
	align-items: stretch;
	gap: var(--bbc-space-2);
	text-align: right;
}

.bbc-deal__price-main {
	font-size: var(--bbc-price);
	line-height: var(--bbc-lh-price);
	font-weight: var(--bbc-weight-bold);
	letter-spacing: -0.03em;
	color: var(--bbc-text);
}

.bbc-deal__price-per {
	font-size: var(--bbc-text-sm);
	font-weight: var(--bbc-weight-regular);
	color: var(--bbc-text-muted);
	margin-left: 0.1em;
}

.bbc-deal__price-total {
	font-size: var(--bbc-text-xs);
	line-height: var(--bbc-lh-xs);
	color: var(--bbc-text-muted);
}

/* Intro pricing. Now that every tier is listed rather than one
   representative row, this line is what explains an ordering that
   would otherwise look wrong — a 900Mb deal above a 150Mb one. It
   sits with the price, not in the meta list, because it qualifies
   the headline number. */
.bbc-deal__promo {
	font-size: var(--bbc-text-xs);
	line-height: var(--bbc-lh-xs);
	color: var(--bbc-text);
	font-weight: var(--bbc-weight-semi);
}

/* Offer deadline. Muted, not urgent-red: green/amber are reserved
   for availability and red is banned as a status colour, so this
   stays typographic. */
.bbc-deal__promo-ends {
	font-size: var(--bbc-text-xs);
	line-height: var(--bbc-lh-xs);
	color: var(--bbc-text-muted);
	font-variant-numeric: tabular-nums;
}

/* Absent or expired price. Deliberately plain — a missing figure
   should read as "we haven't verified this", not as a warning
   about the provider. */
.bbc-deal__price-none {
	font-size: var(--bbc-text-sm);
	line-height: var(--bbc-lh-sm);
	color: var(--bbc-text-muted);
	font-style: italic;
}

/* ---- CTA ----------------------------------------------------
   Unmonetised providers get a visually quieter control that is
   still a full-size tap target: the difference is emphasis, not
   affordance. A whole-of-market list must not make the rows we
   earn nothing from feel like dead ends.
   ------------------------------------------------------------ */
.bbc-cta {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-height: var(--bbc-tap-min);
	padding: var(--bbc-space-2) var(--bbc-space-5);
	background: var(--bbc-cta-bg);
	color: var(--bbc-cta-fg);
	font-family: var(--bbc-font-sans);
	font-size: var(--bbc-text-sm);
	font-weight: var(--bbc-weight-semi);
	text-align: center;
	text-decoration: none;
	border: 1px solid transparent;
	border-radius: var(--bbc-radius-1);
	transition:
		background var(--bbc-dur-1) var(--bbc-ease),
		border-color var(--bbc-dur-1) var(--bbc-ease);
}

.bbc-cta:hover,
.bbc-cta:visited { color: var(--bbc-cta-fg); }
.bbc-cta:hover { background: var(--bbc-cta-bg-hover); }

.bbc-cta--secondary {
	background: transparent;
	color: var(--bbc-text);
	border-color: var(--bbc-grey-400);
}
.bbc-cta--secondary:hover,
.bbc-cta--secondary:visited { color: var(--bbc-text); }
.bbc-cta--secondary:hover {
	background: var(--bbc-surface-2);
	border-color: var(--bbc-border-strong);
}

/* ---- Chips --------------------------------------------------
   Radius comes from the token scale, which is rounded but
   deliberately short of a pill.
   ------------------------------------------------------------ */
.bbc-chip {
	display: inline-flex;
	align-items: center;
	gap: var(--bbc-space-1);
	padding: 0.2rem var(--bbc-space-2);
	border-radius: var(--bbc-radius-1);
	font-family: var(--bbc-font-sans);
	font-size: var(--bbc-text-2xs);
	line-height: var(--bbc-lh-2xs);
	font-weight: var(--bbc-weight-semi);
	white-space: nowrap;
}

.bbc-chip__icon { width: 0.75em; height: 0.75em; flex: none; }

.bbc-chip--available   { background: var(--bbc-avail-bg);   color: var(--bbc-avail-fg); }
.bbc-chip--unavailable { background: var(--bbc-unavail-bg); color: var(--bbc-unavail-fg); }
.bbc-chip--social      { background: var(--bbc-avail-bg);   color: var(--bbc-avail-fg); }

/* Price-varies-by-network. Hardcoded greys like the "Ad" label and for the
   same reason: it is a disclosure about what the number means, so it must not
   be dimmable from Elementor's colour picker. Green and amber stay reserved
   for availability, so this is deliberately neutral. */
.bbc-chip--varies {
	background: var(--bbc-grey-100);
	color: var(--bbc-grey-800);
	border: 1px solid var(--bbc-grey-300);
	font-weight: var(--bbc-weight-normal);
}

/* Partial availability carries a hatch as well as colour, so the
   state survives greyscale printing and colour-blind viewing. */
.bbc-chip--partial {
	background-color: var(--bbc-partial-bg);
	background-image: var(--bbc-hatch);
	color: var(--bbc-partial-fg);
}

/* Editorial flag — earned by the sort, never sold. Outlined
   rather than filled so it cannot outshout the Ad label. */
.bbc-chip--pick {
	background: transparent;
	color: var(--bbc-brand-primary);
	border: 1px solid currentColor;
}

/* ---- Ad label -----------------------------------------------
   Mandatory on every monetised row. CAP is explicit that a
   footer disclaimer is insufficient when only some rows pay.
   Highest-contrast pair in the system and deliberately not wired
   to any Elementor variable, so it cannot be made faint from a
   colour picker. Do not restyle to de-emphasise.
   ------------------------------------------------------------ */
.bbc-ad {
	display: inline-flex;
	align-items: center;
	padding: 0.2rem var(--bbc-space-2);
	background: var(--bbc-ad-bg);
	color: var(--bbc-ad-fg);
	border-radius: var(--bbc-radius-1);
	font-family: var(--bbc-font-sans);
	font-size: var(--bbc-text-2xs);
	line-height: var(--bbc-lh-2xs);
	font-weight: var(--bbc-weight-bold);
	letter-spacing: 0.06em;
	text-transform: uppercase;
	cursor: help;
}

/* ---- Empty state --------------------------------------------- */
.bbc-empty {
	padding: var(--bbc-space-7) var(--bbc-space-5);
	text-align: center;
	color: var(--bbc-text-muted);
	background: var(--bbc-surface-2);
	border: 1px dashed var(--bbc-card-border);
	border-radius: var(--bbc-radius-2);
}

/* ---- Narrow layout ------------------------------------------
   Container query, not a media query: the grid is dropped into
   Elementor columns of unpredictable width, so it has to respond
   to its own box rather than the viewport.
   ------------------------------------------------------------ */
@container (max-width: 46rem) {
	.bbc-deal {
		grid-template-columns: 3.5rem minmax(0, 1fr);
		grid-template-areas:
			"logo body"
			"price price"
			"meta meta";
		column-gap: var(--bbc-space-3);
		padding: var(--bbc-space-4);
	}

	.bbc-deal__logo {
		min-height: 3.5rem;
		padding: var(--bbc-space-1);
	}

	/* The wordmark cannot fit a full provider name at this size,
	   so the tile falls back to the initial from the data
	   attribute; the accessible name still comes from the row
	   heading beside it. */
	.bbc-deal__wordmark { font-size: 0; min-height: 2.5rem; }
	.bbc-deal__wordmark::after {
		content: attr(data-initial);
		position: relative;
		font-size: var(--bbc-text-lg);
		font-weight: var(--bbc-weight-bold);
	}

	.bbc-deal__name { font-size: var(--bbc-text-md); }

	.bbc-deal__price {
		flex-direction: row;
		flex-wrap: wrap;
		align-items: center;
		justify-content: space-between;
		gap: var(--bbc-space-2) var(--bbc-space-4);
		text-align: left;
		padding-top: var(--bbc-space-3);
		border-top: 1px solid var(--bbc-border);
	}

	.bbc-deal__price-total { width: 100%; order: 3; }
	.bbc-deal__price .bbc-cta { flex: 1 1 8rem; }
}

/* Fallback for browsers without container queries: the same
   collapse keyed to the viewport. Harmless where @container is
   supported, because the rules are identical. */
@supports not (container-type: inline-size) {
	@media (max-width: 48rem) {
		.bbc-deal {
			grid-template-columns: 3.5rem minmax(0, 1fr);
			grid-template-areas: "logo body" "price price" "meta meta";
			column-gap: var(--bbc-space-3);
			padding: var(--bbc-space-4);
		}
		.bbc-deal__logo { min-height: 3.5rem; padding: var(--bbc-space-1); }
		.bbc-deal__wordmark { font-size: 0; min-height: 2.5rem; }
		.bbc-deal__wordmark::after {
			content: attr(data-initial);
			position: relative;
			font-size: var(--bbc-text-lg);
			font-weight: var(--bbc-weight-bold);
		}
		.bbc-deal__price {
			flex-direction: row;
			flex-wrap: wrap;
			align-items: center;
			justify-content: space-between;
			text-align: left;
			padding-top: var(--bbc-space-3);
			border-top: 1px solid var(--bbc-border);
		}
		.bbc-deal__price-total { width: 100%; order: 3; }
		.bbc-deal__price .bbc-cta { flex: 1 1 8rem; }
	}
}

/* ---- Provider tile hues ------------------------------------
   Assigned by provider id modulo six in PHP, so a provider keeps
   its colour between visits. Decorative only — the accessible
   identity is the row heading, and state never rides on these.
   ------------------------------------------------------------ */
.bbc-tile-0 .bbc-deal__wordmark { color: var(--bbc-fun-rose-fg); }
.bbc-tile-0 .bbc-deal__wordmark::before { background: var(--bbc-fun-rose-bg); opacity: 1; }
.bbc-tile-1 .bbc-deal__wordmark { color: var(--bbc-fun-teal-fg); }
.bbc-tile-1 .bbc-deal__wordmark::before { background: var(--bbc-fun-teal-bg); opacity: 1; }
.bbc-tile-2 .bbc-deal__wordmark { color: var(--bbc-fun-amber-fg); }
.bbc-tile-2 .bbc-deal__wordmark::before { background: var(--bbc-fun-amber-bg); opacity: 1; }
.bbc-tile-3 .bbc-deal__wordmark { color: var(--bbc-fun-violet-fg); }
.bbc-tile-3 .bbc-deal__wordmark::before { background: var(--bbc-fun-violet-bg); opacity: 1; }
.bbc-tile-4 .bbc-deal__wordmark { color: var(--bbc-fun-green-fg); }
.bbc-tile-4 .bbc-deal__wordmark::before { background: var(--bbc-fun-green-bg); opacity: 1; }
.bbc-tile-5 .bbc-deal__wordmark { color: var(--bbc-fun-sky-fg); }
.bbc-tile-5 .bbc-deal__wordmark::before { background: var(--bbc-fun-sky-bg); opacity: 1; }

/* ---- Postcode search ---------------------------------------
   The hero of the page: a warm two-hue gradient panel with one
   oversized input. The gradient is the cheerfulness budget spent
   in one place — everything inside stays on surface tokens so
   the panel lifts the page without shouting over the results.
   ------------------------------------------------------------ */
.bbc-search {
	container-type: inline-size;
	background: var(--bbc-hero-grad);
	border: 1px solid var(--bbc-card-border);
	border-radius: var(--bbc-radius-3);
	padding: var(--bbc-space-6) var(--bbc-space-5);
	display: grid;
	gap: var(--bbc-space-4);
}

.bbc-search__label {
	display: block;
	font-family: var(--bbc-font-serif);
	font-size: var(--bbc-text-2xl);
	line-height: var(--bbc-lh-2xl);
	font-weight: var(--bbc-weight-semi);
	letter-spacing: -0.01em;
	color: var(--bbc-text);
	text-wrap: balance;
}

.bbc-search__row {
	display: flex;
	flex-wrap: wrap;
	gap: var(--bbc-space-2);
	max-width: 34rem;
}

.bbc-search__input {
	flex: 1 1 12rem;
	min-height: 3.25rem;
	padding: var(--bbc-space-2) var(--bbc-space-4);
	font-family: var(--bbc-font-sans);
	font-size: var(--bbc-text-md);
	letter-spacing: 0.04em;
	text-transform: uppercase;
	color: var(--bbc-text);
	background: var(--bbc-surface);
	border: 1px solid var(--bbc-border-strong);
	border-radius: var(--bbc-radius-1);
}

.bbc-search__input::placeholder { text-transform: none; letter-spacing: 0; color: var(--bbc-text-muted); }

.bbc-search__submit { min-height: 3.25rem; flex: 0 0 auto; }

.bbc-search__error {
	margin: 0;
	font-size: var(--bbc-text-sm);
	color: var(--bbc-error-fg);
	background: var(--bbc-error-bg);
	border-radius: var(--bbc-radius-1);
	padding: var(--bbc-space-2) var(--bbc-space-3);
	justify-self: start;
}

.bbc-search__result {
	background: var(--bbc-surface);
	border: 1px solid var(--bbc-card-border);
	border-radius: var(--bbc-radius-2);
	box-shadow: var(--bbc-shadow-card);
	padding: var(--bbc-space-5);
	display: grid;
	gap: var(--bbc-space-3);
}

.bbc-search__result--miss { color: var(--bbc-text-muted); font-size: var(--bbc-text-sm); }

.bbc-search__heading {
	margin: 0;
	font-family: var(--bbc-font-sans);
	font-size: var(--bbc-text-lg);
	font-weight: var(--bbc-weight-bold);
	letter-spacing: -0.015em;
}

.bbc-tiers {
	list-style: none;
	margin: 0;
	padding: 0;
	display: grid;
	gap: var(--bbc-space-2);
}

.bbc-tier {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: var(--bbc-space-3);
	padding: var(--bbc-space-2) var(--bbc-space-3);
	border: 1px solid var(--bbc-border);
	border-radius: var(--bbc-radius-1);
	font-size: var(--bbc-text-sm);
}

.bbc-tier__label { font-weight: var(--bbc-weight-medium); }

/* The USO note is a right the visitor may not know they have —
   informational tint, not an alarm. */
.bbc-search__uso {
	margin: 0;
	font-size: var(--bbc-text-xs);
	line-height: var(--bbc-lh-xs);
	color: var(--bbc-fun-sky-fg);
	background: var(--bbc-fun-sky-bg);
	border-radius: var(--bbc-radius-1);
	padding: var(--bbc-space-2) var(--bbc-space-3);
}

.bbc-search__source {
	margin: 0;
	font-size: var(--bbc-text-2xs);
	line-height: var(--bbc-lh-2xs);
	color: var(--bbc-text-muted);
}

@container (max-width: 30rem) {
	.bbc-search { padding: var(--bbc-space-5) var(--bbc-space-4); }
	.bbc-search__label { font-size: var(--bbc-text-xl); }
	.bbc-search__submit { flex: 1 1 100%; }
}

@media (forced-colors: active) {
	.bbc-deal, .bbc-chip, .bbc-ad, .bbc-cta, .bbc-tier, .bbc-search { border: 1px solid CanvasText; }
	.bbc-deal__wordmark::before { display: none; }
	.bbc-search { background: Canvas; }
}

/* Three cost windows for rolling monthly tariffs. Shown as a row of
   equal columns so 1 / 9 / 12 months read as one comparison, not as a
   headline plus footnotes — on a no-contract deal the twelve-month
   figure is the one that surprises people, and it must not be the
   small print. */
.bbc-deal__windows {
	display: flex;
	gap: var(--bbc-space-3);
	margin-top: var(--bbc-space-1);
}

.bbc-deal__windows > div {
	display: flex;
	flex-direction: column;
}

.bbc-deal__win-label {
	font-size: var(--bbc-text-xs);
	line-height: 1.3;
	color: var(--bbc-text-muted);
}

.bbc-deal__win-value {
	font-size: var(--bbc-text-sm);
	line-height: 1.25;
	font-weight: var(--bbc-weight-semi);
	color: var(--bbc-text);
	font-variant-numeric: tabular-nums;
}

.bbc-deal__win-note {
	font-size: var(--bbc-text-xs);
	line-height: 1.4;
	color: var(--bbc-text-muted);
	margin-top: var(--bbc-space-1);
	max-width: 34ch;
}

/* Connection-type label. Neutral, not a warning: fixed wireless is the only
   option for many rural homes, so this identifies the product rather than
   cautioning against it. Text carries the meaning — no colour-only signal,
   and green/amber stay reserved for availability. */
.bbc-chip--wireless {
	background: var(--bbc-surface-2);
	border: 1px solid var(--bbc-border-strong);
	color: var(--bbc-text);
}

/* Destination note. Sits directly above the button it qualifies, because a
   caveat the reader meets AFTER clicking is not a caveat. */
.bbc-deal__via {
	font-size: var(--bbc-text-xs);
	line-height: 1.45;
	color: var(--bbc-text);
	background: var(--bbc-fun-amber-bg, var(--bbc-surface-2));
	border-left: 3px solid var(--bbc-fun-amber-fg, var(--bbc-border-strong));
	padding: var(--bbc-space-2) var(--bbc-space-3);
	margin: 0 0 var(--bbc-space-2);
	max-width: 30ch;
}

/* What the visitor gets for clicking. Positive framing — this is a benefit to
   them, not a disclosure against them — so it reads as a highlight rather than
   the amber caveat immediately below it. */
.bbc-deal__offer {
	font-size: var(--bbc-text-sm);
	line-height: 1.35;
	font-weight: var(--bbc-weight-semi);
	color: var(--bbc-text);
	background: var(--bbc-surface-2);
	border: 1px solid var(--bbc-border-strong);
	border-radius: var(--bbc-radius-1, 6px);
	padding: var(--bbc-space-2) var(--bbc-space-3);
	margin: 0 0 var(--bbc-space-2);
	max-width: 30ch;
}

/*
 * The unmonetised escape hatch beside a cashback link.
 * Deliberately quiet — it is an alternative, not a competing CTA — but a
 * real link at full contrast, never grey-on-grey. Someone declining the
 * cashback route should not have to hunt for the plain one.
 */
.bbc-deal__direct,
.bbc-isp__direct {
	display: inline-block;
	margin-top: .35rem;
	font-size: .8125rem;
	line-height: 1.4;
	color: var(--bbc-ink-soft, #4a5568);
	text-decoration: underline;
	text-underline-offset: 2px;
}

.bbc-deal__direct:hover,
.bbc-deal__direct:focus-visible,
.bbc-isp__direct:hover,
.bbc-isp__direct:focus-visible {
	color: var(--bbc-ink, #1a202c);
}

.bbc-isp__direct {
	font-size: .875rem;
}
