.tz-airtime-widget{--tz-widget-accent:#ea580c;--tz-widget-ink:#141312;--tz-widget-muted:#8a8580;--tz-widget-line:#e5e1da;--tz-widget-soft:#f4f2ef;container-type:inline-size;width:100%;box-sizing:border-box;padding:20px;border:1px solid var(--tz-widget-line);border-radius:16px;background:#fff;color:var(--tz-widget-ink);font-family:Helvetica,Arial,sans-serif}.tz-airtime-widget *{box-sizing:border-box}.tz-airtime-widget__copy h2{margin:0;color:var(--tz-widget-ink);font-size:clamp(1.2rem,2vw,1.55rem);line-height:1.15;letter-spacing:-.02em}.tz-airtime-widget__copy p{margin:6px 0 0;color:var(--tz-widget-muted);font-size:.9rem;line-height:1.45}.tz-airtime-widget__form{display:flex;gap:8px;margin-top:16px}.tz-airtime-widget__form label{flex:1;min-width:0}.tz-airtime-widget__form input{width:100%;min-height:48px;padding:10px 13px;border:1.5px solid var(--tz-widget-line);border-radius:12px;background:#faf8f5;color:var(--tz-widget-ink);font:600 1rem Helvetica,Arial,sans-serif;letter-spacing:.03em}.tz-airtime-widget__form input:focus{border-color:var(--tz-widget-accent);outline:3px solid rgba(234,88,12,.16);outline-offset:1px}.tz-airtime-widget__form button,.tz-airtime-widget__link{display:inline-flex;min-height:48px;align-items:center;justify-content:center;padding:11px 17px;border:1px solid var(--tz-widget-accent);border-radius:12px;background:var(--tz-widget-accent);color:#fff;font:700 .9rem Helvetica,Arial,sans-serif;text-align:center;text-decoration:none;white-space:nowrap}.tz-airtime-widget__form button:hover,.tz-airtime-widget__link:hover{background:#c2410c;color:#fff}.tz-airtime-widget--banner{display:flex;flex-wrap:wrap;align-items:center;gap:24px;padding:18px 20px;background:#f1efea}.tz-airtime-widget--banner .tz-airtime-widget__copy{flex:1}.tz-airtime-widget--banner .tz-airtime-widget__form{flex:1.25;margin-top:0}.tz-airtime-widget--sidebar{max-width:360px}.tz-airtime-widget--sidebar .tz-airtime-widget__form{flex-direction:column}.tz-airtime-widget--compact{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:18px;padding:13px 16px}.tz-airtime-widget--compact .tz-airtime-widget__copy p{display:none}.tz-airtime-widget--compact .tz-airtime-widget__copy h2{font-size:1rem;letter-spacing:0}.tz-airtime-widget--compact .tz-airtime-widget__link{min-height:42px;padding:8px 14px}.tz-airtime-widget--catalogue{padding:24px;background:#f1efea}.tz-airtime-widget__catalogue{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:10px;margin-top:18px}.tz-airtime-widget__catalogue a{display:flex;min-height:92px;flex-direction:column;justify-content:space-between;padding:15px;border:1px solid #ede8df;border-radius:14px;background:#fff;color:var(--tz-widget-ink);text-decoration:none}.tz-airtime-widget__catalogue a:hover{border-color:var(--tz-widget-accent)}.tz-airtime-widget__catalogue strong{color:var(--tz-widget-accent);font-size:1rem;font-weight:700}.tz-airtime-widget__catalogue span{color:var(--tz-widget-muted);font-size:.78rem}.tz-airtime-widget--catalogue>.tz-airtime-widget__link{margin-top:16px}@container (max-width:760px){.tz-airtime-widget--banner .tz-airtime-widget__copy,.tz-airtime-widget--banner .tz-airtime-widget__form{flex:1 1 100%}.tz-airtime-widget--banner .tz-airtime-widget__form{margin-top:15px}.tz-airtime-widget__catalogue{grid-template-columns:repeat(2,minmax(0,1fr))}}@container (max-width:440px){.tz-airtime-widget__form{flex-direction:column}.tz-airtime-widget--compact .tz-airtime-widget__copy,.tz-airtime-widget--compact .tz-airtime-widget__link{flex:1 1 100%}.tz-airtime-widget--compact .tz-airtime-widget__link{width:100%}.tz-airtime-widget__catalogue{grid-template-columns:repeat(2,minmax(0,1fr))}}
.tz-airtime-widget__form{display:block}.tz-airtime-widget__form-row{display:flex;gap:8px}.tz-airtime-widget__form-row label{flex:1;min-width:0}.tz-airtime-widget__amount-picker{margin-top:12px}.tz-airtime-widget__amount-picker>span{display:block;margin-bottom:7px;color:var(--tz-widget-muted);font-size:.78rem}.tz-airtime-widget__amount-picker>div{display:flex;gap:6px;overflow-x:auto;padding:1px 1px 4px;scrollbar-width:none}.tz-airtime-widget__amount-picker>div::-webkit-scrollbar{display:none}.tz-airtime-widget__amount-picker button{flex:0 0 auto;min-height:38px;padding:7px 12px;border:1.5px solid var(--tz-widget-line);border-radius:10px;background:#fff;color:var(--tz-widget-ink);font-size:.82rem}.tz-airtime-widget__amount-picker button.is-selected{border-color:var(--tz-widget-accent);background:#fff7ed;color:var(--tz-widget-accent)}.tz-airtime-widget--banner .tz-airtime-widget__form-row{display:flex}.tz-airtime-widget--sidebar .tz-airtime-widget__form-row{flex-direction:column}@container (max-width:440px){.tz-airtime-widget__form-row{flex-direction:column}}
.tz-airtime-widget__amount-picker .tz-airtime-widget__amount-grid{display:grid;grid-template-columns:repeat(6,minmax(0,1fr));gap:10px;overflow:visible;padding:0}.tz-airtime-widget__amount-picker .tz-airtime-widget__amount-grid button{min-width:0;min-height:56px;padding:12px 4px;border-radius:13px;font-size:1rem;font-weight:700;text-align:center}.tz-airtime-widget__amount-picker .tz-airtime-widget__amount-grid--more{margin-top:9px}.tz-airtime-widget__amount-picker .tz-airtime-widget__amount-grid--more button{min-height:48px;font-size:.94rem;font-weight:600}.tz-airtime-widget__amount-picker .tz-airtime-widget__amount-toggle{display:block;min-height:0;margin-top:11px;padding:0;border:0;background:transparent;color:var(--tz-widget-accent);font-size:.81rem;font-weight:600;text-align:left}.tz-airtime-widget__amount-picker .tz-airtime-widget__amount-toggle:hover{background:transparent;color:#c2410c}@container (max-width:600px){.tz-airtime-widget__amount-picker .tz-airtime-widget__amount-grid{grid-template-columns:repeat(3,minmax(0,1fr));gap:8px}}
.tz-airtime-widget-modal{max-height:min(90dvh,760px);margin:auto;padding:0;border:0;border-radius:18px;background:#f1efea;color:#141312;box-shadow:0 24px 60px rgba(0,0,0,.24)}.tz-airtime-widget-modal::backdrop{background:rgba(20,19,18,.4)}.tz-airtime-widget-modal__header{position:sticky;z-index:10;top:0;display:flex;align-items:center;justify-content:space-between;gap:16px;padding:14px 18px;border-bottom:1px solid #eae6e0;background:#fff;font-family:Helvetica,Arial,sans-serif}.tz-airtime-widget-modal__header>div{display:flex;align-items:baseline;gap:14px}.tz-airtime-widget-modal__header strong{font-size:1rem}.tz-airtime-widget-modal__header a{color:#ea580c;font-size:.82rem;font-weight:600;text-decoration:none}.tz-airtime-widget-modal__header button{min-height:40px;padding:8px 13px;border:1.5px solid #e5e1da;border-radius:10px;background:#fff;color:#57534e;font:600 .82rem Helvetica,Arial,sans-serif}.tz-airtime-widget-modal__body{padding:0 12px 12px}.tz-airtime-widget-modal__body .tz-airtime{margin-top:12px;margin-bottom:0}@media(max-width:600px){.tz-airtime-widget-modal{border-radius:20px 20px 0 0}.tz-airtime-widget-modal__header{align-items:flex-start}.tz-airtime-widget-modal__header>div{align-items:flex-start;flex-direction:column;gap:3px}.tz-airtime-widget-modal__body{padding:0}.tz-airtime-widget-modal__body .tz-airtime{margin:0}}

/*
 * Aligned with the buying block, so the two do not read as different products when they sit on
 * the same page: white bordered box means "type here", soft fill means "tap this".
 */
.tz-airtime-widget{--tz-widget-field-line:#d0c7b8}
.tz-airtime-widget__form input{min-height:56px;padding:0 15px;border:1.5px solid var(--tz-widget-field-line);border-radius:14px;background:#fff;font-size:16px}
.tz-airtime-widget__form input:focus{border-color:var(--tz-widget-accent);outline:0;box-shadow:0 0 0 3px rgba(234,88,12,.13)}
.tz-airtime-widget__form input::placeholder{color:#a8a29e;font-weight:500;opacity:1}
.tz-airtime-widget__form button,.tz-airtime-widget__link{min-height:56px;border-radius:14px;font-size:16px}
.tz-airtime-widget--compact .tz-airtime-widget__link{min-height:44px}
.tz-airtime-widget__amount-picker .tz-airtime-widget__amount-grid button{border-color:transparent;background:var(--tz-widget-soft);border-radius:12px}
.tz-airtime-widget__amount-picker .tz-airtime-widget__amount-grid button:hover{background:#eae6df}
.tz-airtime-widget__amount-picker .tz-airtime-widget__amount-grid button.is-selected{border-color:var(--tz-widget-accent);background:#fff7ed;color:var(--tz-widget-accent)}
/* Catalogue tiles are buttons when they open the modal, so they need the card styling too. */
.tz-airtime-widget__catalogue button{display:flex;width:100%;min-height:92px;flex-direction:column;justify-content:space-between;gap:6px;padding:15px;border:1px solid #ede8df;border-radius:14px;background:#fff;color:var(--tz-widget-ink);font-family:inherit;text-align:left;cursor:pointer}
.tz-airtime-widget__catalogue button:hover{border-color:var(--tz-widget-accent);background:#fff}
.tz-airtime-widget__catalogue button strong{color:var(--tz-widget-accent);font-size:1rem;font-weight:700}
.tz-airtime-widget__catalogue button span{color:var(--tz-widget-muted);font-size:.78rem;font-weight:400}
/* A phone-width sheet: the buying block inside it then uses its narrow layout. */

.tz-airtime-widget-modal__body{padding:0 14px 14px}
/*
 * The dialog had a max-height but nothing to scroll, so anything past it overflowed behind the
 * sticky Buy bar — including the EcoCash field. Header fixed, body scrolls.
 */
.tz-airtime-widget-modal[open]{display:flex;flex-direction:column;overflow:hidden}
.tz-airtime-widget-modal__header{flex:none}
.tz-airtime-widget-modal__body{flex:1;min-height:0;overflow-y:auto;-webkit-overflow-scrolling:touch}


/* The Buy bar, lifted out of the scrolling body into the dialog's own footer. */
.tz-airtime-widget-modal__footer{flex:none;padding:12px 14px;border-top:1px solid #eae6e0;background:#fff;box-shadow:0 -6px 18px rgba(0,0,0,.06)}
/* It arrives carrying the sticky/bleed styling it needed while inside the card. */
.tz-airtime-widget-modal__footer .tz-airtime__summary-footer{position:static;margin:0;padding:0;border-top:0;background:none;box-shadow:none}
/*
 * The bar is lifted out of .tz-airtime, so --tz-accent no longer resolves and the
 * button rendered white-on-white — present and clickable but invisible. The dialog
 * carries the token itself now, and the button repeats it with a literal fallback
 * so it can never come out unpainted again.
 */
.tz-airtime-widget-modal{--tz-accent:#ea580c}
.tz-airtime-widget-modal__footer .tz-airtime__primary{width:100%;min-height:54px;border:1px solid var(--tz-accent,#ea580c);border-radius:13px;background:var(--tz-accent,#ea580c);box-shadow:0 6px 16px rgba(234,88,12,.32);color:#fff;font-size:1.0625rem;font-weight:800;letter-spacing:.01em}
.tz-airtime-widget-modal__footer .tz-airtime__primary:disabled{border-color:#d6d1ca;background:#d6d1ca;box-shadow:none;color:#fff}
/* Close is an icon now, so it should read as one rather than as a labelled button. */
.tz-airtime-widget-modal__header{gap:12px}
.tz-airtime-widget-modal__header button[data-close-airtime-modal]{display:flex;flex:none;align-items:center;justify-content:center;width:38px;min-width:38px;height:38px;min-height:38px;padding:0;border:1.5px solid #e5e1da;border-radius:50%;background:#fff;color:#57534e;cursor:pointer}
.tz-airtime-widget-modal__header button[data-close-airtime-modal]:hover{border-color:#d0c7b8;color:#141312}
.tz-airtime-widget-modal__header button[data-close-airtime-modal] svg{display:block}

/* Title and close sit on one line, vertically centred against each other. */
.tz-airtime-widget-modal__header{align-items:center;justify-content:space-between;padding:14px 18px}
.tz-airtime-widget-modal__header strong{font-size:1.15rem;font-weight:800;letter-spacing:-.01em;line-height:1.2}
/* Room to breathe before the first field, at every width. */
.tz-airtime-widget-modal__body{padding-top:10px}
.tz-airtime-widget-modal__body .tz-airtime{margin-top:0}
.tz-airtime-widget-modal__body .tz-airtime__panel{padding-top:20px}

/* ==========================================================================
   Modal, rebuilt for phones.

   vh and vw are both wrong here. vh follows the layout viewport, so when the
   keyboard opens the sheet keeps its full height and the Buy bar at its foot
   slides underneath the keyboard — the button vanishes exactly when it is
   needed. vw counts the scrollbar gutter, so a 100vw sheet is wider than the
   page and drags the whole document sideways.

   dvh follows the visible viewport, and percentages follow the element. Both
   shrink when the keyboard appears; neither can overflow.

   The geometry is pinned with !important on purpose: the pages this sits on
   also run ad scripts and theme CSS that reach for bare `dialog` selectors
   and inline styles, and any of those winning drags the sheet off screen and
   opens a horizontal scrollbar. Nothing outside this file may size or place
   the dialog.
   ========================================================================== */
.tz-airtime-widget-modal.tz-airtime-widget-modal{
	width:min(520px,calc(100% - 24px)) !important;max-width:calc(100% - 24px) !important;
	height:95dvh;max-height:95dvh !important;
	overscroll-behavior:contain
}
.tz-airtime-widget-modal__body{overflow-x:hidden;overscroll-behavior:contain}
.tz-airtime-widget-modal *{min-width:0}

/*
 * A closed <dialog> is display:none only by UA default; a foreign `dialog{display:…}`
 * rule makes it render in-flow at the foot of the page — a stray box out of view that
 * widens the document sideways. While open it lives in the top layer, so position,
 * inset and transform are pinned too, out of reach of ad scripts' inline styles.
 */
.tz-airtime-widget-modal.tz-airtime-widget-modal:not([open]){display:none !important}
.tz-airtime-widget-modal.tz-airtime-widget-modal[open]{
	position:fixed !important;
	inset:0 !important;
	margin:auto !important;
	transform:none !important;
	z-index:2147483600
}

/* On a phone it is a sheet: bottom edge, thumb-first, a breath of air each side. */
@media (max-width:600px){
	.tz-airtime-widget-modal.tz-airtime-widget-modal{
		width:calc(100% - 20px) !important;max-width:calc(100% - 20px) !important;
		height:95dvh;max-height:95dvh !important;
		border-radius:20px 20px 0 0
	}
	.tz-airtime-widget-modal.tz-airtime-widget-modal[open]{margin:auto auto 0 !important}
	.tz-airtime-widget-modal__header{padding:14px 16px 12px}
	.tz-airtime-widget-modal__body{padding:0 12px 12px}
	.tz-airtime-widget-modal__footer{padding:12px 12px calc(12px + env(safe-area-inset-bottom))}
}

/* A sheet wants something to grab. */
@media (max-width:600px){
	.tz-airtime-widget-modal__header::before{
		content:"";position:absolute;top:7px;left:50%;
		width:38px;height:4px;margin-left:-19px;
		border-radius:99px;background:#ddd8d0
	}
	.tz-airtime-widget-modal__header{position:relative;padding-top:18px}
}

.tz-airtime-widget-modal::backdrop{background:rgba(20,19,18,.55);backdrop-filter:blur(2px)}

/* ==========================================================================
   The entry widgets share their pages with ad scripts too.

   Auto-placed ads pick their own insertion points and will happily drop an
   <ins> inside the widget card or the dialog, blowing the layout apart from
   the inside. Nothing that isn't ours renders inside either. And whatever
   the page around a widget does, the widget itself stays inside its column
   and clips anything that tries to poke past its own edge.
   ========================================================================== */
/* The class is doubled so a same-specificity rule loading after us still loses. */
.tz-airtime-widget.tz-airtime-widget{max-width:100% !important;position:static !important;transform:none !important;overflow-x:clip}
.tz-airtime-widget .google-auto-placed,
.tz-airtime-widget ins.adsbygoogle,
.tz-airtime-widget-modal .google-auto-placed,
.tz-airtime-widget-modal ins.adsbygoogle{display:none !important}
