/* Smile&Pay Bill Payments — front end.
 *
 * Palette taken from the active Electro theme so the page reads as part of the
 * store rather than a bolted-on widget: primary #0787ea, body text #333e48,
 * borders #d9d9d9, grey surfaces #f8f9fa.
 *
 * Full width by default — the biller grid needs the room for 51 billers.
 * Scoped under .sbp-app so nothing leaks into the theme.
 */

.sbp-app {
	/* Electro blue */
	--sbp-primary:      #0787ea;
	--sbp-primary-hover:#067ad4;
	--sbp-primary-dark: #045696;
	--sbp-primary-soft: #e7f3fd;
	--sbp-primary-tint: #f3f9fe;

	/* Electro neutrals */
	--sbp-text:   #333e48;
	--sbp-heading:#212121;
	--sbp-muted:  #6c757d;
	--sbp-border: #d9d9d9;
	--sbp-border-soft: #e9ecef;
	--sbp-card:   #ffffff;
	--sbp-surface:#f8f9fa;
	--sbp-surface-alt: #f5f5f5;

	/* States */
	--sbp-success: #198754;
	--sbp-success-bg: #e8f5ee;
	--sbp-danger:  #dc3545;
	--sbp-danger-bg: #fdecee;
	--sbp-warn:    #b8860b;
	--sbp-warn-bg: #fff8e1;

	--sbp-r:       6px;
	--sbp-r-card:  8px;
	--sbp-shadow:  0 1px 3px rgba(51, 62, 72, .08);
	--sbp-shadow-lift: 0 6px 18px -6px rgba(7, 135, 234, .28);

	--sbp-body: inherit;

	width: 100%;
	max-width: 100%;
	margin: 0;
	padding-top: 1.75rem;
	font-family: var(--sbp-body);
	font-size: 15px;
	line-height: 1.55;
	color: var(--sbp-text);
}

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

/* Defensive reset.
 * The Electro theme styles bare `button` and form elements with negative
 * margins (margin:-.5rem -1rem), floats and absolute positioning — which is
 * what made the filter chips collide. Neutralise the properties that break
 * layout, without touching the ones this stylesheet sets deliberately. */
/* :where() contributes no specificity, so this reset beats the theme's bare
 * element selectors while every rule below — even a single class — still wins
 * over it. Without that, .sbp-app input (0,1,1) silently overrode .sbp-search
 * (0,1,0) and ate the search field's margin.
 *
 * `label` is in the list because Electro sets `label { margin-bottom: .857em }`,
 * which every label this plugin renders is a `label`: the mode tabs, the
 * payment methods and each form field. On the mode tabs it was measurable —
 * "Pay for a package" came out 38.5px tall inside a 52.1px frame with a 12.6px
 * gap beneath it, while "Top up any amount" filled to 50.1px because an
 * unrelated :last-child rule happened to zero its margin. Two tabs in one
 * segmented control, different heights, for no reason visible in this
 * stylesheet. .sbp-field sets its own margin-bottom and still wins here. */
.sbp-app :where(button, input, select, table, label) {
	position: static;
	float: none;
	margin: 0;
	min-width: 0;
	max-width: 100%;
	height: auto;
	min-height: 0;
	text-transform: none;
	letter-spacing: normal;
	text-shadow: none;
	box-shadow: none;
	vertical-align: middle;
}

.sbp-app :where(button) {
	-webkit-appearance: none;
	appearance: none;
	background-image: none;
	text-align: center;
	text-decoration: none;
	line-height: 1.3;
}

.sbp-app :where(button)::before,
.sbp-app :where(button)::after { content: none; }

/* ------------------------------------------------------------- headings */

.sbp-title {
	margin: 0 0 1.25rem;
	font-size: 1.6rem;
	font-weight: 600;
	line-height: 1.2;
	color: var(--sbp-heading);
}

.sbp-h3 {
	margin: 0 0 1rem;
	font-size: 1.05rem;
	font-weight: 600;
	color: var(--sbp-heading);
}

.sbp-note {
	margin: 0 0 1rem;
	font-size: 0.85rem;
	color: var(--sbp-muted);
}

/* ----------------------------------------------------------- step rail */

.sbp-steps {
	display: flex;
	gap: 0;
	list-style: none;
	margin: 0 0 1.5rem;
	padding: 0;
	counter-reset: sbp-step;
	border: 1px solid var(--sbp-border-soft);
	border-radius: var(--sbp-r-card);
	overflow: hidden;
	background: var(--sbp-card);
}

.sbp-steps li {
	flex: 1 1 0;
	display: flex;
	align-items: center;
	justify-content: center;
	gap: 0.5rem;
	padding: 0.75rem 0.5rem;
	font-size: 0.8rem;
	font-weight: 500;
	color: var(--sbp-muted);
	background: var(--sbp-surface);
	counter-increment: sbp-step;
	border-right: 1px solid var(--sbp-border-soft);
}

.sbp-steps li:last-child { border-right: none; }

.sbp-steps li::before {
	content: counter(sbp-step);
	flex: 0 0 auto;
	width: 1.4rem;
	height: 1.4rem;
	border-radius: 50%;
	display: grid;
	place-items: center;
	background: var(--sbp-border);
	color: #fff;
	font-size: 0.72rem;
	font-weight: 700;
}

.sbp-steps li.is-active {
	background: var(--sbp-card);
	color: var(--sbp-primary);
	font-weight: 600;
	box-shadow: inset 0 -3px 0 var(--sbp-primary);
}

.sbp-steps li.is-active::before { background: var(--sbp-primary); }

.sbp-steps li.is-done { color: var(--sbp-text); }
.sbp-steps li.is-done::before { content: '\2713'; background: var(--sbp-success); }

/* --------------------------------------------------------------- panel */

.sbp-panel {
	border: 1px solid var(--sbp-border-soft);
	border-radius: var(--sbp-r-card);
	background: var(--sbp-card);
	padding: 1.75rem 1.5rem 1.5rem;
	box-shadow: var(--sbp-shadow);
}

.sbp-loading,
.sbp-empty {
	margin: 0;
	padding: 2rem 0;
	text-align: center;
	color: var(--sbp-muted);
	font-size: 0.9rem;
}

.sbp-alert {
	display: none;
	margin-bottom: 1rem;
	padding: 0.8rem 1rem;
	border: 1px solid #f5c2c7;
	border-left: 4px solid var(--sbp-danger);
	border-radius: var(--sbp-r);
	background: var(--sbp-danger-bg);
	color: #842029;
	font-size: 0.875rem;
}

.sbp-alert.is-visible { display: block; }

/* --------------------------------------------------------- search + filter */

.sbp-search {
	width: 100%;
	margin-bottom: 1.35rem;
	padding: 0.7rem 1rem;
	border: 1px solid var(--sbp-border);
	border-radius: var(--sbp-r);
	background: var(--sbp-card);
	font-family: inherit;
	font-size: 0.95rem;
	color: var(--sbp-text);
	transition: border-color .15s, box-shadow .15s;
}

.sbp-search:focus {
	outline: none;
	border-color: var(--sbp-primary);
	box-shadow: 0 0 0 3px rgba(7, 135, 234, .15);
}

/* Category chips wrap onto as many rows as they need. No horizontal scroll:
   with 13 categories a scroller hides most of them, and a squeezed single row
   overlaps once the theme's own flex rules get involved. */
.sbp-filters {
	display: flex;
	flex-wrap: wrap;
	align-items: flex-start;
	row-gap: 0.5rem;
	gap: 0.45rem;
	margin: 1.35rem 0;
	padding: 0;
	overflow: visible;
	list-style: none;
}

.sbp-filter {
	/* Never grow, never shrink below the label — shrinking is what caused the
	   chips to collide. min-width:auto overrides the flex default of 0. */
	flex: 0 0 auto;
	min-width: auto;
	max-width: 100%;
	display: inline-flex;
	align-items: center;
	gap: 0.35rem;
	margin: 0;
	padding: 0.32rem 0.4rem 0.32rem 0.75rem;
	border: 1px solid var(--sbp-border);
	border-radius: 999px;
	background: var(--sbp-card);
	font-family: inherit;
	font-size: 0.78rem;
	font-weight: 500;
	line-height: 1.3;
	color: var(--sbp-text);
	white-space: nowrap;
	overflow: hidden;
	text-overflow: ellipsis;
	cursor: pointer;
	transition: background .15s, border-color .15s, color .15s;
}

.sbp-filter:hover { border-color: var(--sbp-primary); color: var(--sbp-primary); }

.sbp-filter.is-active {
	background: var(--sbp-primary);
	border-color: var(--sbp-primary);
	color: #fff;
}

/* Counter pill. Sized as a circle that stretches for 2-3 digits, with
   tabular-nums so the widths line up across chips. The old grey-on-grey had
   almost no contrast; these use the blue ramp instead. */
.sbp-filter__count {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-width: 1.4rem;
	height: 1.4rem;
	padding: 0 0.32rem;
	border-radius: 999px;
	background: var(--sbp-primary-soft);
	color: var(--sbp-primary-dark);
	font-size: 0.7rem;
	font-weight: 700;
	line-height: 1;
	font-variant-numeric: tabular-nums;
	letter-spacing: 0;
	transition: background .15s, color .15s;
}

.sbp-filter:hover .sbp-filter__count {
	background: #cfe6fb;
	color: var(--sbp-primary-dark);
}

/* On the selected chip the pill inverts: solid white on blue reads clearly and
   uses the dark blue for text so the contrast holds at this size. */
.sbp-filter.is-active .sbp-filter__count {
	background: #fff;
	color: var(--sbp-primary-dark);
}

/* ---------------------------------------------------------- biller grid */

/* Logo-led cards: the image is the card, the name is a caption.
   grid-auto-rows:1fr keeps every row the same height, and the caption is
   clamped to two lines — biller names run from 5 to 45 characters, so without
   both the cards end up different heights and the hover lift looks ragged. */
.sbp-grid {
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(116px, 1fr));
	grid-auto-rows: 1fr;
	gap: 0.6rem;
}

.sbp-biller {
	display: flex;
	flex-direction: column;
	height: 100%;
	padding: 0;
	border: 1px solid var(--sbp-border-soft);
	border-radius: var(--sbp-r-card);
	background: var(--sbp-card);
	font-family: inherit;
	cursor: pointer;
	overflow: hidden;
	text-align: center;
	transition: border-color .15s, box-shadow .15s, transform .15s;
}

.sbp-biller:hover:not(:disabled),
.sbp-biller:focus-visible {
	border-color: var(--sbp-primary);
	box-shadow: var(--sbp-shadow-lift);
	transform: translateY(-2px);
	outline: none;
}

.sbp-biller__logo {
	display: grid;
	place-items: center;
	flex: 1 1 auto;
	width: 100%;
	min-height: 58px;
	padding: 0.6rem;
	background: var(--sbp-card);
	border-bottom: 1px solid var(--sbp-border-soft);
}

.sbp-biller__logo img {
	max-width: 100%;
	max-height: 46px;
	object-fit: contain;
}

/* Fallback when a logo is missing or 404s. */
.sbp-biller__logo.is-initial {
	font-size: 1.5rem;
	font-weight: 700;
	color: var(--sbp-primary);
	background: var(--sbp-primary-tint);
}

.sbp-biller__name {
	display: -webkit-box;
	-webkit-line-clamp: 2;
	-webkit-box-orient: vertical;
	overflow: hidden;
	flex: 0 0 auto;
	/* Two lines' worth, always, so short and long names give the same card. */
	min-height: calc(2 * 1.25em + 0.9rem);
	padding: 0.45rem 0.4rem;
	font-size: 0.75rem;
	font-weight: 500;
	line-height: 1.25;
	color: var(--sbp-text);
	background: var(--sbp-surface);
}

.sbp-biller:hover .sbp-biller__name { color: var(--sbp-primary); }

.sbp-biller__cat {
	display: block;
	padding: 0 0.4rem 0.4rem;
	font-size: 0.62rem;
	letter-spacing: .03em;
	text-transform: uppercase;
	color: var(--sbp-muted);
	background: var(--sbp-surface);
}

/* Selected-biller pill on later steps. */
.sbp-selected { margin-bottom: 1.1rem; }

.sbp-chip {
	display: inline-flex;
	align-items: center;
	gap: 0.5rem;
	padding: 0.35rem 0.85rem 0.35rem 0.4rem;
	border: 1px solid var(--sbp-border);
	border-radius: 999px;
	background: var(--sbp-card);
	font-size: 0.85rem;
	font-weight: 600;
	color: var(--sbp-heading);
}

.sbp-chip img {
	width: 28px;
	height: 28px;
	border-radius: 4px;
	object-fit: contain;
	background: #fff;
}

/* --------------------------------------------------------------- forms */

/* Forms stay readable on a full-width page rather than stretching — and are
   centred, so every step sits in the same place as the receipt instead of the
   layout jumping left when you move off the biller grid. */
.sbp-panel form,
.sbp-panel .sbp-summary,
.sbp-panel .sbp-selected,
.sbp-panel > .sbp-h3,
.sbp-panel > .sbp-note,
.sbp-panel > .sbp-modes,
.sbp-panel > .sbp-modes__help,
.sbp-waiting,
.sbp-receipt {
	max-width: 640px;
	margin-left: auto;
	margin-right: auto;
}

/* The biller grid is the exception: it should use the full width. */
.sbp-panel .sbp-grid,
.sbp-panel .sbp-search,
.sbp-panel .sbp-filters { max-width: none; }

/* Step headings and the selected-biller chip read better centred above a
   centred form; field labels stay left so the form is still scannable. */
.sbp-panel > .sbp-h3,
.sbp-panel .sbp-selected { text-align: center; }

/* Step 1 keeps its heading left, since the grid below it is full width. */
.sbp-panel .sbp-grid ~ .sbp-h3,
.sbp-panel > .sbp-h3:first-child { text-align: left; }

.sbp-field { display: block; margin-bottom: 1rem; }

.sbp-label {
	display: block;
	margin-bottom: 0.35rem;
	font-size: 0.85rem;
	font-weight: 600;
	color: var(--sbp-heading);
}

.sbp-label em { color: var(--sbp-danger); font-style: normal; }

.sbp-field input,
.sbp-field select {
	width: 100%;
	padding: 0.7rem 0.95rem;
	border: 1px solid var(--sbp-border);
	border-radius: var(--sbp-r);
	background: var(--sbp-card);
	font-family: inherit;
	font-size: 0.95rem;
	color: var(--sbp-text);
	transition: border-color .15s, box-shadow .15s;
}

.sbp-field input:focus,
.sbp-field select:focus {
	outline: none;
	border-color: var(--sbp-primary);
	box-shadow: 0 0 0 3px rgba(7, 135, 234, .15);
}

.sbp-field input[readonly] {
	background: var(--sbp-surface);
	color: var(--sbp-muted);
	cursor: default;
}

.sbp-help {
	display: block;
	margin-top: 0.3rem;
	font-size: 0.78rem;
	line-height: 1.45;
	color: var(--sbp-muted);
}

/* ------------------------------------------------------------- summary */

.sbp-summary {
	margin: 0 0 1.25rem;
	padding: 1rem 1.1rem;
	border: 1px solid var(--sbp-border-soft);
	border-radius: var(--sbp-r-card);
	background: var(--sbp-surface);
}

.sbp-summary__row {
	display: flex;
	justify-content: space-between;
	align-items: baseline;
	gap: 1rem;
	padding: 0.32rem 0;
	font-size: 0.9rem;
}

.sbp-summary__row dt { margin: 0; color: var(--sbp-muted); }

.sbp-summary__row dd {
	margin: 0;
	font-weight: 600;
	text-align: right;
	word-break: break-word;
	color: var(--sbp-text);
}

.sbp-summary__row.is-total {
	margin-top: 0.55rem;
	padding-top: 0.75rem;
	border-top: 1px solid var(--sbp-border);
}

.sbp-summary__row.is-total dt { color: var(--sbp-heading); font-weight: 600; }

.sbp-summary__row.is-total dd {
	font-size: 1.3rem;
	font-weight: 700;
	color: var(--sbp-primary);
}

/* ------------------------------------------------------------- buttons */

.sbp-actions {
	display: flex;
	gap: 0.65rem;
	margin-top: 1.35rem;
}

.sbp-btn {
	flex: 1 1 auto;
	padding: 0.8rem 1.3rem;
	border: 1px solid var(--sbp-primary);
	border-radius: var(--sbp-r);
	background: var(--sbp-primary);
	color: #fff;
	font-family: inherit;
	font-size: 0.925rem;
	font-weight: 600;
	cursor: pointer;
	transition: background .15s, border-color .15s, opacity .15s;
}

.sbp-btn:hover:not(:disabled) {
	background: var(--sbp-primary-hover);
	border-color: var(--sbp-primary-hover);
}

.sbp-btn:focus-visible {
	outline: none;
	box-shadow: 0 0 0 3px rgba(7, 135, 234, .35);
}

.sbp-btn:disabled { opacity: .6; cursor: not-allowed; }
.sbp-btn.is-busy { opacity: .75; }

.sbp-btn--ghost {
	flex: 0 0 auto;
	background: var(--sbp-card);
	border-color: var(--sbp-border);
	color: var(--sbp-muted);
}

.sbp-btn--ghost:hover:not(:disabled) {
	background: var(--sbp-surface);
	border-color: var(--sbp-border);
	color: var(--sbp-text);
}

/* ------------------------------------------------------------- waiting */

.sbp-waiting { padding: 2.25rem 1rem; text-align: center; }

.sbp-spinner {
	width: 40px;
	height: 40px;
	margin: 0 auto 1.1rem;
	border: 3px solid var(--sbp-border-soft);
	border-top-color: var(--sbp-primary);
	border-radius: 50%;
	animation: sbp-spin .9s linear infinite;
}

.sbp-waiting p { margin: 0 auto .5rem; max-width: 34em; }

@keyframes sbp-spin { to { transform: rotate(360deg); } }

@media (prefers-reduced-motion: reduce) {
	.sbp-spinner { animation-duration: 3s; }
	.sbp-biller, .sbp-btn, .sbp-filter { transition: none; }
}

/* ------------------------------------------------------------- receipt */

.sbp-receipt { text-align: center; }

.sbp-receipt__icon {
	width: 56px;
	height: 56px;
	margin: 0 auto 1rem;
	border-radius: 50%;
	display: grid;
	place-items: center;
	font-size: 1.7rem;
	font-weight: 700;
	color: #fff;
}

.sbp-receipt.is-ok .sbp-receipt__icon  { background: var(--sbp-success); }
.sbp-receipt.is-bad .sbp-receipt__icon { background: var(--sbp-danger); }

.sbp-receipt__error {
	margin: 0 auto 1rem;
	max-width: 34em;
	color: var(--sbp-danger);
	font-size: 0.9rem;
}

.sbp-receipt .sbp-summary { text-align: left; }

.sbp-token {
	margin: 0 0 1.25rem;
	padding: 1rem;
	border: 2px dashed var(--sbp-primary);
	border-radius: var(--sbp-r-card);
	background: var(--sbp-primary-tint);
}

.sbp-token__label {
	display: block;
	margin-bottom: 0.35rem;
	font-size: 0.72rem;
	font-weight: 700;
	letter-spacing: .06em;
	text-transform: uppercase;
	color: var(--sbp-primary-dark);
}

.sbp-token__value {
	display: block;
	font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
	font-size: 1.3rem;
	font-weight: 700;
	letter-spacing: .05em;
	word-break: break-all;
	background: none;
	padding: 0;
	color: var(--sbp-heading);
}

/* ------------------------------------------------------------- history */

.sbp-history {
	width: 100%;
	border-collapse: collapse;
	font-size: 0.875rem;
	background: var(--sbp-card);
	border: 1px solid var(--sbp-border-soft);
	border-radius: var(--sbp-r-card);
	overflow: hidden;
}

.sbp-history th,
.sbp-history td {
	padding: 0.75rem 0.8rem;
	text-align: left;
	vertical-align: top;
	border-bottom: 1px solid var(--sbp-border-soft);
}

.sbp-history tbody tr:last-child td { border-bottom: none; }
.sbp-history tbody tr:hover td { background: var(--sbp-surface); }

.sbp-history th {
	background: var(--sbp-surface);
	font-size: 0.72rem;
	font-weight: 600;
	letter-spacing: .04em;
	text-transform: uppercase;
	color: var(--sbp-muted);
}

.sbp-history code { font-size: 0.8rem; background: none; padding: 0; color: var(--sbp-text); }

.sbp-badge {
	display: inline-block;
	padding: 0.18rem 0.55rem;
	border-radius: 999px;
	font-size: 0.68rem;
	font-weight: 700;
	letter-spacing: .03em;
	text-transform: uppercase;
	background: var(--sbp-surface-alt);
	color: var(--sbp-muted);
}

.sbp-badge--completed { background: var(--sbp-success-bg); color: var(--sbp-success); }
.sbp-badge--failed    { background: var(--sbp-danger-bg);  color: var(--sbp-danger); }
.sbp-badge--paid,
.sbp-badge--posting   { background: var(--sbp-warn-bg);    color: var(--sbp-warn); }
.sbp-badge--expired   { background: var(--sbp-surface-alt); color: var(--sbp-muted); }

/* --------------------------------------------------------- responsive */

@media (min-width: 1200px) {
	/* Full width means more columns, not bigger cards. */
	.sbp-grid { grid-template-columns: repeat(auto-fill, minmax(124px, 1fr)); }
}

@media (max-width: 640px) {
	.sbp-app { padding-top: 1rem; }
	.sbp-panel { padding: 1.25rem 1rem 1rem; }
	.sbp-actions { flex-direction: column-reverse; }
	.sbp-btn, .sbp-btn--ghost { width: 100%; }
	.sbp-grid { grid-template-columns: repeat(auto-fill, minmax(110px, 1fr)); gap: .6rem; }
	.sbp-filters { gap: .3rem; }
	.sbp-filter { font-size: .72rem; padding: .28rem .34rem .28rem .65rem; }
	.sbp-filter__count { min-width: 1.25rem; height: 1.25rem; font-size: .66rem; }
	.sbp-biller__logo { padding: .6rem; }
	.sbp-steps li { flex-direction: column; gap: .25rem; font-size: .65rem; padding: .55rem .25rem; }
	.sbp-title { font-size: 1.35rem; }
	/* A wide table scrolls inside itself rather than pushing the page sideways. */
	.sbp-history { display: block; overflow-x: auto; white-space: nowrap; }
}

/* --------------------------------------------------------------- print */

@media print {
	.sbp-steps, .sbp-actions, .sbp-alert, .sbp-search, .sbp-filters { display: none !important; }
	.sbp-panel { border: none; box-shadow: none; padding: 0; }
	.sbp-token { border-color: #000; background: none; }
}

/* ------------------------------------------------ My Account tab */

.sbp-link {
	color: var(--sbp-primary);
	font-weight: 500;
	text-decoration: none;
}

.sbp-link:hover { color: var(--sbp-primary-dark); text-decoration: underline; }

.sbp-pager {
	display: flex;
	align-items: center;
	justify-content: center;
	gap: 1rem;
	margin-top: 1.25rem;
}

.sbp-pager .sbp-btn {
	flex: 0 0 auto;
	text-decoration: none;
	display: inline-flex;
	align-items: center;
}

.sbp-pager__count {
	font-size: 0.85rem;
	color: var(--sbp-muted);
}

/* A payment that is collected but not yet confirmed by the biller. */
.sbp-receipt.is-pending .sbp-receipt__icon {
	background: var(--sbp-warn);
	font-size: 1.4rem;
}

.sbp-badge--awaiting_payment { background: var(--sbp-primary-soft); color: var(--sbp-primary-dark); }
.sbp-badge--quoted { background: var(--sbp-surface-alt); color: var(--sbp-muted); }

/* ------------------------------------------- payment method tiles */

.sbp-methods {
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(126px, 1fr));
	gap: 0.55rem;
}

.sbp-method {
	position: relative;
	display: flex;
	align-items: center;
	gap: 0.6rem;
	min-height: 58px;
	padding: 0.6rem 0.7rem;
	border: 1px solid var(--sbp-border);
	border-radius: var(--sbp-r-card);
	background: var(--sbp-card);
	cursor: pointer;
	transition: border-color .15s, box-shadow .15s, background .15s;
}

/* The radio drives state but is not shown; the tile is the control. */
.sbp-method input[type="radio"] {
	position: absolute;
	opacity: 0;
	width: 1px;
	height: 1px;
	margin: 0;
	pointer-events: none;
}

.sbp-method:hover { border-color: var(--sbp-primary); }

.sbp-method.is-selected {
	border-color: var(--sbp-primary);
	background: var(--sbp-primary-tint);
	box-shadow: 0 0 0 1px var(--sbp-primary) inset;
}

/* Keyboard focus has to be visible even though the radio is hidden. */
.sbp-method:focus-within {
	outline: none;
	box-shadow: 0 0 0 3px rgba(7, 135, 234, .3);
}

.sbp-method__logo {
	flex: 0 0 auto;
	display: grid;
	place-items: center;
	width: 34px;
	height: 34px;
}

.sbp-method__logo img {
	max-width: 100%;
	max-height: 100%;
	object-fit: contain;
}

.sbp-method__name {
	flex: 1 1 auto;
	font-size: 0.82rem;
	font-weight: 600;
	line-height: 1.25;
	color: var(--sbp-text);
}

.sbp-method.is-selected .sbp-method__name { color: var(--sbp-primary-dark); }

/* Tick appears only on the chosen tile. */
.sbp-method__tick {
	position: absolute;
	top: 0.35rem;
	right: 0.45rem;
	display: none;
	font-size: 0.7rem;
	font-weight: 700;
	color: var(--sbp-primary);
}

.sbp-method.is-selected .sbp-method__tick { display: block; }

@media (max-width: 640px) {
	.sbp-methods { grid-template-columns: repeat(auto-fill, minmax(108px, 1fr)); gap: .45rem; }
	.sbp-method { min-height: 52px; padding: .5rem .55rem; gap: .45rem; }
	.sbp-method__logo { width: 28px; height: 28px; }
	.sbp-method__name { font-size: .76rem; }
}

@media (prefers-reduced-motion: reduce) {
	.sbp-method { transition: none; }
}

/* ---------------------------------------- My Account list header */

.sbp-listhead {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: space-between;
	gap: 0.75rem;
	margin-bottom: 1rem;
}

.sbp-listhead__count {
	font-size: 0.9rem;
	font-weight: 600;
	color: var(--sbp-heading);
}

/* Links styled as buttons need the anchor defaults neutralised. */
.sbp-app a.sbp-btn {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	text-decoration: none;
}

.sbp-app a.sbp-btn:hover { text-decoration: none; color: #fff; }
.sbp-app a.sbp-btn--ghost:hover { color: var(--sbp-text); }

.sbp-btn--compact {
	flex: 0 0 auto;
	padding: 0.55rem 1.1rem;
	font-size: 0.85rem;
}

.sbp-empty-action {
	margin: 0;
	text-align: center;
}

.sbp-empty-action .sbp-btn { flex: 0 0 auto; }

@media (max-width: 640px) {
	.sbp-listhead { flex-direction: column; align-items: stretch; }
	.sbp-btn--compact { width: 100%; }
}

/* ---------------------------------------- My Account history filter
 *
 * Namespaced .sbp-hf, not .sbp-filter: that one is the round category chip on
 * the biller picker, and sharing the name would have the two sets of rules
 * fighting over padding and border-radius. */

.sbp-hf {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
	align-items: end;
	gap: 0.7rem 0.85rem;
	margin: 0 0 1.35rem;
	padding: 0.95rem 1.05rem;
	border: 1px solid var(--sbp-border-soft);
	border-radius: var(--sbp-r-card);
	background: var(--sbp-surface);
}

/* min-width:0 is what stops a date input — which carries its own intrinsic
   width — from pushing its grid column wider than the share it was given. */
.sbp-hf__field {
	min-width: 0;
	margin: 0;
}

.sbp-hf__field--wide { grid-column: span 2; }

.sbp-hf .sbp-label {
	margin-bottom: 0.3rem;
	font-size: 0.78rem;
	font-weight: 600;
	letter-spacing: 0.01em;
	color: var(--sbp-muted);
}

.sbp-hf input,
.sbp-hf select {
	width: 100%;
	min-width: 0;
	max-width: 100%;
	height: auto;
	margin: 0;
	padding: 0.5rem 0.7rem;
	border: 1px solid var(--sbp-border);
	border-radius: var(--sbp-r);
	background: var(--sbp-card);
	font-family: inherit;
	font-size: 0.88rem;
	line-height: 1.4;
	color: var(--sbp-text);
	transition: border-color .15s, box-shadow .15s;
}

.sbp-hf input:focus,
.sbp-hf select:focus {
	outline: none;
	border-color: var(--sbp-primary);
	box-shadow: 0 0 0 3px var(--sbp-primary-soft);
}

.sbp-hf__actions {
	display: flex;
	align-items: center;
	gap: 0.85rem;
	margin: 0;
}

.sbp-hf__actions .sbp-btn { flex: 0 0 auto; }

.sbp-hf__clear {
	font-size: 0.85rem;
	white-space: nowrap;
}

@media (max-width: 640px) {
	.sbp-hf {
		grid-template-columns: 1fr 1fr;
		padding: 0.85rem;
	}
	.sbp-hf__field--wide,
	.sbp-hf__actions { grid-column: 1 / -1; }

	/* .sbp-btn--compact goes full width on a phone for the list header, where
	   it is alone on its line. Here it shares the row with Clear, and letting
	   it take the whole width pushed Clear off the right edge. */
	.sbp-hf__actions .sbp-btn--compact {
		width: auto;
		flex: 1 1 auto;
	}
}

.sbp-ref {
	display: block;
	margin-top: 0.15rem;
	font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
	font-size: 0.72rem;
	color: var(--sbp-muted);
	word-break: break-all;
}

.sbp-badge--reversing { background: var(--sbp-warn-bg); color: var(--sbp-warn); }

.sbp-note--warn {
	padding: 0.7rem 0.9rem;
	border-left: 3px solid var(--sbp-warn);
	border-radius: var(--sbp-r);
	background: var(--sbp-warn-bg);
	color: var(--sbp-warn);
	font-weight: 500;
}

/* --------------------------------------------------- card payment */

.sbp-card {
	margin-top: 0.25rem;
	padding: 1rem;
	border: 1px solid var(--sbp-border);
	border-radius: var(--sbp-r-card);
	background: var(--sbp-surface);
}

.sbp-card__note {
	margin: 0 0 0.85rem;
	font-size: 0.78rem;
	line-height: 1.45;
	color: var(--sbp-muted);
}

.sbp-card__row {
	display: grid;
	grid-template-columns: 1fr 1fr;
	gap: 0.75rem;
}

.sbp-card .sbp-field:last-child { margin-bottom: 0; }

/* Card entry reads more clearly in a monospaced face. */
.sbp-card input[name="pan"],
.sbp-card input[name="expiry"],
.sbp-card input[name="cvv"] {
	font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
	letter-spacing: 0.06em;
}

/* ------------------------------------------- 3-D Secure challenge */

.sbp-challenge { padding: 0.5rem 0; }

.sbp-challenge__frame {
	min-height: 420px;
	margin-top: 0.75rem;
	border: 1px solid var(--sbp-border-soft);
	border-radius: var(--sbp-r-card);
	overflow: hidden;
	background: var(--sbp-card);
}

.sbp-challenge__frame iframe {
	display: block;
	width: 100%;
	min-height: 420px;
	border: 0;
}

@media (max-width: 640px) {
	.sbp-card__row { grid-template-columns: 1fr; gap: 0; }
	.sbp-challenge__frame,
	.sbp-challenge__frame iframe { min-height: 520px; }
}

/* ---- InnBucks payment code ----
   InnBucks does not push a prompt: the customer types this code into their
   app, so on the waiting screen it is the most important thing present. */
.sbp-code {
    max-width: 22rem;
    margin: 0 auto 1.5rem;
    padding: 1.25rem 1rem;
    border: 2px solid #0787ea;
    border-radius: 6px;
    background: #f4faff;
    text-align: center;
}

.sbp-code__label {
    font-size: .6875rem;
    font-weight: 700;
    letter-spacing: .1em;
    text-transform: uppercase;
    color: #0787ea;
}

.sbp-code__value {
    margin: .5rem 0 .75rem;
    font-family: ui-monospace, "SF Mono", Menlo, monospace;
    font-size: 2rem;
    font-weight: 700;
    letter-spacing: .12em;
    color: #333e48;
    word-break: break-all;
}

.sbp-code__copy,
.sbp-code__open {
    display: inline-block;
    margin: 0 .25rem;
    padding: .5rem 1rem;
    border-radius: 4px;
    font-size: .8125rem;
    font-weight: 600;
    cursor: pointer;
    text-decoration: none;
}

.sbp-code__copy {
    border: 1px solid #0787ea;
    background: #fff;
    color: #0787ea;
}

.sbp-code__open {
    border: 1px solid #0787ea;
    background: #0787ea;
    color: #fff;
}

.sbp-code__copy:hover { background: #eaf5ff; }
.sbp-code__open:hover { background: #0670c4; border-color: #0670c4; }

.sbp-code__help {
    margin: .875rem 0 0;
    font-size: .8125rem;
    line-height: 1.5;
    color: #6b7480;
}

@media print {
    .sbp-code__copy,
    .sbp-code__open { display: none; }
}

/* ---------------------------------------------------------------- modes
 * Where a biller sells two different things — a DSTV package renewal or an
 * open top-up — the choice comes first, because it changes the questions.
 *
 * A segmented control, not a pair of cards: it is a binary choice whose option
 * names carry the meaning, and as cards it took four times the height of the
 * fields it governed and outweighed the step's own heading.
 *
 * Each option carries its own colour, named in the biller profile rather than
 * set here, so the two purchases are told apart at a glance and not only by
 * which one happens to be filled in. Equal columns, the width of the form
 * below, so neither option looks like the lesser of the two.
 */
.sbp-modes {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(8.5rem, 1fr));
	margin: 0 auto 0.55rem;
	background: var(--sbp-surface);
	border: 1px solid var(--sbp-border-soft);
	border-radius: 0.55rem;
	/* The options fill the frame edge to edge — no padding and no gap between
	   them. Inset by a few pixels, the chosen one floated inside a pale border
	   on every side and read as not reaching full height. The frame does the
	   rounding, and clips the corners of whichever option is filled. */
	overflow: hidden;
}

.sbp-mode {
	/* Overridden per option by the [data-accent] rules below. */
	--mode: var(--sbp-primary-dark);
	--mode-tint: var(--sbp-primary-soft);
	--mode-hover: var(--sbp-primary-dark);
	--mode-tint-hover: #d6e9fb;

	display: flex;
	align-items: center;
	justify-content: center;
	position: relative;
	padding: 0.65rem 0.85rem;
	background: var(--mode-tint);
	font-size: 0.85rem;
	font-weight: 600;
	line-height: 1.3;
	text-align: center;
	color: var(--mode);
	cursor: pointer;
	transition: background .15s, color .15s, box-shadow .15s;
}

/* Kept in the tab order and focusable, just not drawn: the control reads as
 * one thing, and a visible radio beside a filled tab says it twice. */
.sbp-mode input {
	position: absolute;
	width: 1px;
	height: 1px;
	opacity: 0;
	margin: 0;
	pointer-events: none;
}

.sbp-mode + .sbp-mode { border-left: 1px solid var(--sbp-border-soft); }

/* Hover deepens the option's own colour — the wash and the label together —
 * instead of drawing an inset ring. On a segmented control a ring appearing
 * under the pointer reads as the selection moving, which is the one thing
 * hover must not say.
 *
 * Both steps spend nothing on contrast, they buy it: measured, blue goes from
 * 4.98:1 to 6.73:1 and teal from 5.25:1 to 7.46:1. That mattered — the tint
 * alone could only be darkened one step before the label fell under 4.5:1,
 * so the label darkens with it. */
.sbp-mode:hover {
	background: var(--mode-tint-hover);
	color: var(--mode-hover);
}

/* The chosen one is filled. White on these accents clears 4.5:1, which the
 * brand blue itself does not at this size — hence the darker variants. */
.sbp-mode.is-active {
	background: var(--mode);
	color: #fff;
}

/* Already filled, so it deepens the fill rather than taking a wash. White on
 * these clears 7.9:1 and 8.9:1. */
.sbp-mode.is-active:hover {
	background: var(--mode-hover);
	color: #fff;
}

/* Drawn inside: an outline outside the element is clipped away by the
 * frame's overflow, which would leave keyboard focus invisible. */
.sbp-mode:focus-within {
	box-shadow: inset 0 0 0 2px var(--sbp-heading);
}

/* The palette. Analogous to the Electro blue so the pair sits together, and
 * clear of the state colours — green, amber and red mean something already. */
/* Each accent has to clear 4.5:1 twice over — white on the filled tab, and
 * the accent itself on its own tint for the tab that is not chosen. The
 * unchosen label is the tighter of the two, and it is what pushed both of
 * these darker than they first were. */
.sbp-mode[data-accent="blue"] {
	--mode: #0a6ab5;
	--mode-tint: #e7f3fd;
	--mode-hover: #064a82;
	--mode-tint-hover: #c6e1fa;
}

.sbp-mode[data-accent="teal"] {
	--mode: #0b6e77;
	--mode-tint: #e4f3f4;
	--mode-hover: #074850;
	--mode-tint-hover: #c2e2e5;
}

/* One line, for the option actually chosen. */
.sbp-modes__help {
	margin: 0 auto 1.2rem;
	text-align: center;
	font-size: 0.8rem;
	line-height: 1.45;
	color: var(--sbp-muted);
}

/* A figure that was worked out rather than typed, so it reads as an answer and
 * not as an empty box someone forgot to fill in. */
.sbp-field--total input[data-sbp-derived] {
	font-weight: 600;
	color: var(--sbp-heading);
	background: var(--sbp-surface);
}

/* ------------------------------------------------------- confirm payment
 * The last look before money moves. Drawn over the review step rather than
 * replacing it: the payment reads the mobile number and any card details
 * straight out of the form underneath, and a fresh panel would discard them.
 */
.sbp-confirm {
	position: absolute;
	inset: 0;
	z-index: 20;
	display: flex;
	align-items: flex-start;
	justify-content: center;
	padding: 1.5rem 1rem;
	overflow-y: auto;
	background: rgba(33, 33, 33, .45);
}

.sbp-panel { position: relative; }

.sbp-confirm__inner {
	width: 100%;
	max-width: 26rem;
	padding: 1.35rem 1.35rem 1.1rem;
	border-radius: 0.6rem;
	background: var(--sbp-card);
	box-shadow: 0 12px 34px -10px rgba(33, 33, 33, .45);
}

.sbp-confirm__title {
	margin: 0 0 1rem;
	font-size: 1.05rem;
	font-weight: 600;
	color: var(--sbp-heading);
}

.sbp-confirm__total {
	display: flex;
	align-items: baseline;
	justify-content: space-between;
	gap: 1rem;
	margin-top: 0.9rem;
	padding-top: 0.8rem;
	border-top: 1px solid var(--sbp-border);
	font-size: 0.9rem;
	color: var(--sbp-muted);
}

.sbp-confirm__total strong {
	font-size: 1.15rem;
	color: var(--sbp-heading);
}

.sbp-confirm__note {
	margin: 0.75rem 0 0;
	font-size: 0.8rem;
	line-height: 1.45;
	color: var(--sbp-muted);
}

.sbp-confirm .sbp-actions { margin-top: 1.1rem; }

/* ---------------------------------------- select caret
 *
 * The theme sets appearance:none on select and supplies its own arrow as a
 * background image. Every rule above that paints a select uses the
 * `background` shorthand, which resets background-image to none — so the
 * arrow disappeared and a dropdown read as a plain text box. That was true of
 * the currency, package and reason pickers on the payment form long before
 * the history filter existed.
 *
 * Drawing our own means the control looks the same whatever the theme does.
 * It has to sit last in the file: it sets the longhand, and any shorthand
 * declared after it at equal specificity would wipe it again. */

.sbp-app select {
	-webkit-appearance: none;
	appearance: none;
	padding-right: 2.1rem;
	background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6' viewBox='0 0 10 6'%3E%3Cpath fill='none' stroke='%236c757d' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round' d='M1 1l4 4 4-4'/%3E%3C/svg%3E");
	background-repeat: no-repeat;
	background-position: right 0.8rem center;
	background-size: 10px 6px;
}

/* Months given free, said beside the total they have already come off.

   Green because it is a saving, and stated in money as well as months —
   "one month free" is an offer, "USD 38.00 off" is the reason to take it. */
.sbp-free {
	display: block;
	margin-top: 6px;
	font-size: 13px;
	font-weight: 600;
	color: #1d7a42;
}

.sbp-free[hidden] { display: none; }
