/* ==========================================================================
   LAYER 4 — SECTIONS
   Page-level compositions. Each block here maps 1:1 to a template part in
   template-parts/home/, so visual changes stay localised.
   ========================================================================== */

/* ---- hero carousel ---------------------------------------------------
   A plain image rotator. There is no text column and no drawn artwork: the
   slide is an <img> and nothing else unless the editor typed an overlay.

   Slides are stacked in one grid cell rather than pulled out of the flow when
   inactive. Two reasons: the stage is then always as tall as its tallest slide
   so rotating never shifts the page below it, and `visibility` (rather than
   `display`) keeps that height contribution intact.
   --------------------------------------------------------------------- */
/*
 * The banner is a fixed 1800 × 405 band, centred.
 *
 * This is the whole answer to "why do my banners come out soft". A full-bleed
 * band takes the width of whatever monitor it is on — 1350 on a laptop, 2560 on
 * a desktop — so no single piece of artwork can be 1:1 everywhere, and the
 * wider screens scale the file up. Capping the band means the artwork is never
 * displayed larger than it was drawn: below 1800 the image is cropped from the
 * middle at 1:1, above it the band simply stops growing. One export, sharp
 * everywhere, and the numbers can be written down (they are, in the admin).
 *
 * The cost is honest and deliberate: on a 2560 monitor the band is centred with
 * ink either side instead of bleeding to the edges.
 */
.vp-hero {
	position: relative;
	max-width: 1800px;
	margin: 0 auto;
	background: var(--vp-ink);
	color: #fff;
}

.vp-hero__stage { position: relative; display: grid; }

.vp-hero__stage > [data-vp-hero-slide] { grid-area: 1 / 1; }

.vp-hero__stage > [data-vp-hero-slide]:not(.is-active) {
	visibility: hidden;
	opacity: 0;
	pointer-events: none;
}

.vp-hero__slide,
.vp-hero__link { position: relative; display: block; color: inherit; }

/*
 * One fixed band height for every slide, so the artwork does not have to share
 * an aspect ratio and rotating never changes the page height. With the band
 * capped at 1800 the height is the artwork's own height: `cover` then never
 * has to scale it up, only crop it sideways on a narrower screen.
 */
.vp-hero__img {
	display: block;
	width: 100%;
	height: 405px;
	object-fit: cover;
}

/* <picture> is inline by default, which would leave a gap under the artwork. */
.vp-hero__pic { display: block; }

/*
 * Phones, but only for a slide that actually ships a 4:3 file.
 *
 * Keyed to the slide rather than applied to every hero on small screens: a
 * 4:3 box is taller than the wide artwork, so forcing it on a slide with no
 * mobile image would scale that artwork *up* on a 600pt screen — the opposite
 * of the point. A slide without one keeps the wide band and the wide crop.
 */
@media (max-width: 640px) {
	.vp-hero__img--4x3 { height: auto; aspect-ratio: 4 / 3; }
}

/*
 * No overlay. The artwork carries its own type — a designed 1800 × 405 banner
 * has already decided where its words go, and a second layer of copy on top of
 * it duplicates the message and fights the composition. The slide's headline is
 * still editable: it ships as the page's visually hidden <h1>, so the strongest
 * sentence is real text in the HTML for a crawler and for a screen reader,
 * without being drawn twice for everyone else.
 */

/* Slim control bar under the artwork. Deliberately not overlaid on the image:
   the dots have to stay reachable at every width. */
.vp-hero__foot {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 20px;
	padding: 12px max(24px, calc((100% - var(--vp-max)) / 2 + var(--vp-gutter)));
	border-top: 1px solid #232C36;
}

.vp-hero__dots { display: flex; gap: 8px; }

.vp-hero__dots button {
	width: 8px;
	height: 8px;
	padding: 0;
	border-radius: 50%;
	background: #3B4653;
	cursor: pointer;
}

.vp-hero__dots button[aria-current="true"] { width: 24px; border-radius: 4px; background: var(--vp-accent); }

.vp-hero__arrows { display: flex; gap: 8px; }

.vp-hero__arrows button {
	width: 30px;
	height: 30px;
	border: 1px solid #333E4A;
	border-radius: 8px;
	display: grid;
	place-items: center;
	color: #B9C2CC;
	font-size: 13px;
	background: transparent;
	cursor: pointer;
}

.vp-hero__arrows button:hover { border-color: #4C5866; color: #fff; }

/* ---- icon trust bar -------------------------------------------------- */
.vp-iconbar { padding: 19px 0; border-bottom: 1px solid var(--vp-line); background: #fff; }
.vp-iconbar .vp-wrap { display: grid; grid-template-columns: repeat(4, 1fr); gap: 18px; }

.vp-ib { display: flex; align-items: center; justify-content: center; gap: 11px; color: var(--vp-accent-dk); }
.vp-ib b { display: block; font-size: var(--vp-f-base); font-weight: 600; color: var(--vp-text); }
.vp-ib span { font-size: var(--vp-f-sm); color: var(--vp-muted); }

/* ---- promo banners --------------------------------------------------- */
.vp-promos { padding: 22px 0; border-bottom: 1px solid var(--vp-line); background: #fff; }
.vp-promos__grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 16px; }

.vp-promo {
	position: relative;
	display: flex;
	flex-direction: column;
	justify-content: center;
	height: 152px;
	padding: 22px;
	border-radius: var(--vp-r);
	overflow: hidden;
	color: #fff;
}

.vp-promo::after {
	content: "";
	position: absolute;
	right: -30px;
	bottom: -40px;
	width: 150px;
	height: 150px;
	border-radius: 50%;
	background: rgba(255,255,255,.09);
}

.vp-promo small {
	position: relative;
	font-size: var(--vp-f-xs);
	font-weight: 700;
	letter-spacing: .13em;
	text-transform: uppercase;
	opacity: .78;
}

.vp-promo__title { position: relative; margin-top: 7px; font-size: 21px; font-weight: 700; line-height: 1.2; letter-spacing: -.02em; }

.vp-promo__go {
	position: relative;
	align-self: flex-start;
	margin-top: 13px;
	padding-bottom: 2px;
	border-bottom: 1.5px solid rgba(255,255,255,.5);
	font-size: 12.5px;
	font-weight: 700;
	display: inline-flex;
	align-items: center;
	gap: 6px;
}

.vp-promo--1 { background: #3A2A6E; }
.vp-promo--2 { background: #B0501B; }
.vp-promo--3 { background: #0D5B5B; }
.vp-promo--4 { background: #1E3A5F; }

/*
 * Image-backed tiles. The artwork fills the tile and the copy rides on top, so
 * one markup shape covers all three states: colour block, pure image, image
 * plus text.
 */
.vp-promo__img {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	object-fit: cover;
}

/* The decorative corner circle is a colour-block device; over artwork it just
   reads as a smudge. */
.vp-promo.has-image::after { display: none; }

/* Scrim, only when there is copy to keep readable. An image-only tile is left
   exactly as the designer drew it. */
.vp-promo.has-image.has-copy::before {
	content: "";
	position: absolute;
	inset: 0;
	background: linear-gradient(90deg, rgba(9,14,20,.80) 0%, rgba(9,14,20,.38) 62%, rgba(9,14,20,.10) 100%);
}

/* Paint the copy above the artwork. Order already does it — the <img> is first
   in the DOM — but z-index makes it independent of that. */
.vp-promo small,
.vp-promo__title,
.vp-promo__go { z-index: 1; }

/* ---- access band (login / apply / rep) ------------------------------- */
.vp-access { padding: 46px 0 40px; border-bottom: 1px solid var(--vp-line); background: #fff; }

.vp-access__head {
	display: grid;
	grid-template-columns: 1fr auto;
	gap: 36px;
	align-items: center;
	margin-bottom: 30px;
}

.vp-access__head h2 { max-width: 660px; font-size: clamp(23px, 2.5vw, 31px); font-weight: 700; line-height: 1.22; letter-spacing: -.025em; }
.vp-access__head p { max-width: 720px; margin-top: 11px; font-size: 14.5px; color: var(--vp-muted); }

.vp-stamp {
	width: 106px;
	height: 106px;
	flex: 0 0 auto;
	border: 2px solid var(--vp-accent);
	border-radius: 10px;
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	gap: 3px;
	color: var(--vp-accent-dk);
	text-align: center;
}

.vp-stamp b { font-size: 15px; font-weight: 800; line-height: 1.1; text-transform: uppercase; }
.vp-stamp span { font-size: 9.5px; font-weight: 700; letter-spacing: .14em; text-transform: uppercase; opacity: .85; }

.vp-access__cards { display: grid; grid-template-columns: 1.15fr 1fr 1fr; gap: 18px; }

.vp-ecard {
	display: flex;
	flex-direction: column;
	padding: 22px;
	border: 1px solid var(--vp-line);
	border-radius: var(--vp-r);
	background: #fff;
}

.vp-ecard h3 { margin-bottom: 6px; font-size: var(--vp-f-md); font-weight: 600; }
.vp-ecard > p { margin-bottom: 16px; font-size: var(--vp-f-base); line-height: 1.55; color: var(--vp-muted); }
.vp-ecard ul { display: flex; flex-direction: column; gap: 9px; margin-bottom: 18px; }

.vp-ecard li {
	display: flex;
	gap: 9px;
	align-items: flex-start;
	font-size: var(--vp-f-base);
	color: #3C4553;
}

.vp-ecard li::before {
	content: "";
	width: 5px;
	height: 5px;
	margin-top: 7px;
	border-radius: 50%;
	background: var(--vp-accent);
	flex: 0 0 auto;
}

/* The form is the flex child, so it carries the push-to-bottom rather than the
   button row inside it. */
.vp-loginform { display: flex; flex-direction: column; margin-top: auto; }

.vp-ecard__row { display: flex; align-items: center; gap: 16px; margin-top: auto; }
.vp-ecard__row .vp-btn { flex: 0 0 auto; padding: 11px 24px; }
.vp-ecard__row a { font-size: 12.5px; color: var(--vp-muted); text-decoration: underline; white-space: nowrap; }
.vp-ecard > .vp-btn { margin-top: auto; }

.vp-rep-phone {
	display: block;
	margin-bottom: 3px;
	font-size: 23px;
	font-weight: 700;
	letter-spacing: -.025em;
	color: var(--vp-ink);
}

.vp-rep-phone:hover { color: var(--vp-accent-dk); }
.vp-ecard__note { margin-bottom: 18px; font-size: 12.5px; color: var(--vp-muted); }

/* ---- offer banner band ------------------------------------------------
   A pair of promo panels above a product row. Rendered inside the row's own
   `.vp-row` so it inherits the zebra background instead of cutting a seam
   across it; the margin is what separates it from the row heading below. */

.vp-promoband {
	display: grid;
	grid-template-columns: 1fr 1fr;
	gap: 18px;
	margin-bottom: 30px;
}

.vp-pbanner {
	position: relative;
	overflow: hidden;
	display: flex;
	flex-direction: column;
	justify-content: space-between;
	gap: 16px;
	min-height: 132px;
	padding: 20px 22px;
	border-radius: var(--vp-r-lg);
	color: #fff;
	background: linear-gradient(115deg, #0C1116, #1D2A38);
	transition: transform .18s, box-shadow .18s;
}

.vp-pbanner:hover { transform: translateY(-2px); box-shadow: var(--vp-sh-2); }

/* Tone set. `color` drives the kicker, the glow and the CTA edge, so a new
   tone is one line rather than four. */
.vp-pbanner--ink    { background: linear-gradient(115deg, #0C1116, #1D2A38); color: #00D68F; }
.vp-pbanner--violet { background: linear-gradient(115deg, #2A1F5C, #4B32A8); color: #C4B5FD; }
.vp-pbanner--orange { background: linear-gradient(115deg, #5A2409, #A8500F); color: #FDBA74; }
.vp-pbanner--teal   { background: linear-gradient(115deg, #08312C, #0E6B62); color: #5EEAD4; }
.vp-pbanner--rose   { background: linear-gradient(115deg, #4A1029, #8A2148); color: #FDA4AF; }

/* Image-backed panels. Same three states as the promo tiles: tone gradient,
   pure image, or image under a scrim with the copy on top. */
.vp-pbanner__img {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	object-fit: cover;
}

/* Both decorations belong to the colour-block look; over artwork they read as
   smudges and clutter. */
.vp-pbanner.has-image .vp-pbanner__glow,
.vp-pbanner.has-image .vp-pbanner__art { display: none; }

/* Scrim, only when there is copy to keep readable. */
.vp-pbanner.has-image.has-copy::before {
	content: "";
	position: absolute;
	inset: 0;
	background: linear-gradient(90deg, rgba(9,14,20,.84) 0%, rgba(9,14,20,.44) 62%, rgba(9,14,20,.12) 100%);
}

/* The right-hand padding exists to clear the drawn silhouettes. With artwork
   there are none, and the scrim already guarantees contrast. */
.vp-pbanner.has-image .vp-pbanner__copy { padding-right: 0; }

/* Paint the copy above the artwork. DOM order already does it, but z-index
   makes it independent of where the <img> sits. */
.vp-pbanner__copy,
.vp-pbanner__foot { z-index: 1; }

.vp-pbanner__glow {
	position: absolute;
	top: -70px;
	right: -30px;
	width: 220px;
	height: 220px;
	border-radius: 50%;
	background: radial-gradient(circle, currentColor, transparent 70%);
	opacity: .22;
	pointer-events: none;
}

.vp-pbanner__copy {
	position: relative;
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	/* Keeps the text clear of the silhouettes parked on the right. */
	padding-right: 86px;
}

.vp-pbanner__kicker {
	font-size: 10.5px;
	font-weight: 800;
	letter-spacing: .16em;
	text-transform: uppercase;
	color: currentColor;
}

.vp-pbanner__offer {
	margin-top: 7px;
	font-size: clamp(20px, 2vw, 26px);
	font-weight: 900;
	line-height: 1.08;
	letter-spacing: -.02em;
	color: #fff;
}

.vp-pbanner__sub {
	margin-top: 7px;
	font-size: 12.5px;
	line-height: 1.5;
	color: rgba(255, 255, 255, .72);
}

.vp-pbanner__bullets { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 10px; }

.vp-pbanner__bullet {
	padding: 3px 8px;
	border: 1px solid rgba(255, 255, 255, .22);
	border-radius: 999px;
	font-size: 10.5px;
	font-weight: 700;
	letter-spacing: .02em;
	color: rgba(255, 255, 255, .86);
}

.vp-pbanner__foot { position: relative; }

.vp-pbanner__cta {
	display: inline-flex;
	align-items: center;
	gap: 7px;
	padding: 8px 15px;
	border-radius: 999px;
	background: rgba(255, 255, 255, .14);
	border: 1px solid rgba(255, 255, 255, .24);
	font-size: 12.5px;
	font-weight: 800;
	letter-spacing: .01em;
	color: #fff;
	transition: background .18s, border-color .18s;
}

.vp-pbanner:hover .vp-pbanner__cta { background: rgba(255, 255, 255, .24); border-color: rgba(255, 255, 255, .4); }

/* Translucent shapes rather than the hero's solid bars: the hero's silhouettes
   are lit against near-black, these sit on five different colours. */
.vp-pbanner__art {
	position: absolute;
	right: 16px;
	bottom: 0;
	display: flex;
	align-items: flex-end;
	gap: 9px;
	pointer-events: none;
}

.vp-pbanner__art .vp-dev {
	width: 24px;
	border-radius: 12px;
	box-shadow: none;
	background: rgba(255, 255, 255, .13);
	border: 1px solid rgba(255, 255, 255, .16);
}

.vp-pbanner__art .vp-dev::after { display: none; }
.vp-pbanner__art .vp-dev--2 { height: 74px; }
.vp-pbanner__art .vp-dev--4 { height: 58px; }

/* ---- brand wall ------------------------------------------------------ */
/* ---- brand marquee ---------------------------------------------------
   Sits inside .vp-wrap (the ~1200px shell, matching the reference site). The
   track is `--vp-brands-copies` identical copies of the brand set and is
   translated by exactly one copy width (`-100% / copies`), which is what makes
   the loop point invisible: at the moment the animation restarts, copy 2 sits
   precisely where copy 1 began. The copy count is set inline by the template —
   the two must agree. */

.vp-brands {
	--vp-brands-copies: 3;
	position: relative;
	overflow: hidden;
	padding: 4px 0;

	/* Fade the cut edges rather than ending on a hard clip. */
	-webkit-mask-image: linear-gradient(90deg, transparent 0, #000 56px, #000 calc(100% - 56px), transparent 100%);
	mask-image: linear-gradient(90deg, transparent 0, #000 56px, #000 calc(100% - 56px), transparent 100%);
}

.vp-brands__track {
	display: flex;
	width: max-content;
	animation: vp-brands-scroll 52s linear infinite;
}

/* Padding, not `gap`, carries the spacing: a trailing gap would make each copy
   slightly wider than the distance we translate by, and the loop would drift. */
.vp-brands__set {
	display: flex;
	gap: 14px;
	padding-right: 14px;
}

/* Squarer than a typical logo strip on purpose: the reference wall this is
   modelled on uses tiles a little taller than they are wide, and a centred
   wordmark sits better in that space than in a wide pill. Brand logos drop
   into the same box when they exist — `object-fit: contain` handles it. */
.vp-brands__card {
	display: grid;
	place-items: center;
	flex: 0 0 auto;
	width: 150px;
	height: 96px;
	padding: 0 14px;
	background: #fff;
	border: 1px solid var(--vp-line);
	border-radius: var(--vp-r);
	font-size: 15px;
	font-weight: 800;
	letter-spacing: .07em;
	text-align: center;
	color: #333D4A;
	transition: border-color .18s ease, color .18s ease, box-shadow .18s ease, transform .18s ease;
}

.vp-brands__card:hover {
	border-color: var(--vp-ink);
	color: var(--vp-ink);
	box-shadow: 0 6px 18px rgba(12, 17, 22, .08);
	transform: translateY(-2px);
}

.vp-brands__card img { max-height: 56px; width: auto; object-fit: contain; }

/* Holding still on hover lets someone actually read a brand they spotted
   mid-scroll. Pointer-only, so a touch device is unaffected. */
@media (hover: hover) {
	.vp-brands:hover .vp-brands__track { animation-play-state: paused; }
}

@keyframes vp-brands-scroll {
	to { transform: translateX(calc(-100% / var(--vp-brands-copies))); }
}

/* Motion sensitivity is not a preference to override: park the track and let
   the visitor scroll it by hand instead. */
@media (prefers-reduced-motion: reduce) {
	.vp-brands { overflow-x: auto; }
	.vp-brands__track { animation: none; }
}

/* ---- deals strip ----------------------------------------------------- */
.vp-deals { padding: 34px 0; border-bottom: 1px solid var(--vp-line); background: var(--vp-bg-2); }

.vp-deals__head {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 20px;
	margin-bottom: 18px;
	flex-wrap: wrap;
}

.vp-deals__lab { display: flex; align-items: center; gap: 11px; }

.vp-deals__tag {
	padding: 5px 10px;
	border-radius: 6px;
	background: var(--vp-ink);
	color: #fff;
	font-size: var(--vp-f-xs);
	font-weight: 700;
	letter-spacing: .11em;
	text-transform: uppercase;
}

.vp-deals__head h2 { font-size: 17px; font-weight: 600; }
.vp-deals__head a { font-size: var(--vp-f-base); font-weight: 600; color: var(--vp-accent-dk); }

/* ---- how wholesale works -------------------------------------------- */
.vp-how { border-top: 1px solid var(--vp-line); border-bottom: 1px solid var(--vp-line); background: #fff; }

/* When the strip carries its own heading (every landing page) it needs the
   vertical rhythm of a real section; on the homepage it has no heading and
   stays flush, which is why the padding lives on the modifier. */
.vp-how-block--headed { padding: 52px 0 44px; }

.vp-how-block--headed .vp-how { border: 1px solid var(--vp-line); border-radius: var(--vp-r); overflow: hidden; }
.vp-how .vp-wrap { display: grid; grid-template-columns: repeat(3, 1fr); gap: 0; }
.vp-how__step { display: flex; gap: 14px; align-items: flex-start; padding: 26px 26px 26px 0; }
.vp-how__step + .vp-how__step { border-left: 1px solid var(--vp-line); padding-left: 26px; }

.vp-how__n {
	flex: 0 0 auto;
	width: 30px;
	height: 30px;
	border: 1px solid var(--vp-line);
	border-radius: 8px;
	background: #fff;
	display: grid;
	place-items: center;
	color: var(--vp-accent-dk);
	font-size: 12.5px;
	font-weight: 800;
}

.vp-how h3 { margin-bottom: 3px; font-size: 14px; font-weight: 600; }
.vp-how p { font-size: 12.5px; line-height: 1.5; color: var(--vp-muted); }

/* ---- trust strip ----------------------------------------------------- */
.vp-trust { border-bottom: 1px solid var(--vp-line); background: var(--vp-bg-2); }
.vp-trust .vp-wrap { display: grid; grid-template-columns: repeat(3, 1fr); }

.vp-trust__cell {
	display: flex;
	gap: 14px;
	align-items: flex-start;
	padding: 26px 28px;
	border-right: 1px solid var(--vp-line-2);
}

.vp-trust__cell:last-child { border-right: 0; }

.vp-trust__ico {
	flex: 0 0 auto;
	width: 34px;
	height: 34px;
	border-radius: 9px;
	background: #E9FBF4;
	color: var(--vp-accent-dk);
	display: grid;
	place-items: center;
}

.vp-trust h3 { margin-bottom: 2px; font-size: 14px; font-weight: 600; }
.vp-trust p { font-size: var(--vp-f-base); line-height: 1.5; color: var(--vp-muted); }

/* ---- apply CTA ------------------------------------------------------- */
.vp-apply {
	position: relative;
	overflow: hidden;
	display: grid;
	grid-template-columns: 1fr auto;
	gap: 32px;
	align-items: center;
	padding: 44px 48px;
	border-radius: var(--vp-r-lg);
	background: var(--vp-ink);
	color: #fff;
}

.vp-apply::before {
	content: "";
	position: absolute;
	inset: 0;
	background: radial-gradient(560px 260px at 88% 20%, rgba(0,214,143,.16), transparent 60%);
}

.vp-apply > * { position: relative; }
.vp-apply h2 { font-size: 26px; font-weight: 700; letter-spacing: -.02em; }
.vp-apply p { max-width: 620px; margin-top: 10px; font-size: 14.5px; color: #A9B3BE; }

.vp-apply__steps { display: flex; gap: 26px; margin-top: 20px; flex-wrap: wrap; }
.vp-apply__steps div { display: flex; align-items: center; gap: 8px; font-size: 12.5px; color: #8D99A6; }
.vp-apply__steps b { color: var(--vp-accent); font-weight: 700; }

/* ---- responsive ------------------------------------------------------ */
@media (max-width: 1020px) {
	.vp-iconbar .vp-wrap { grid-template-columns: repeat(2, 1fr); gap: 14px 18px; }
	.vp-ib { justify-content: flex-start; }
	.vp-promos__grid { grid-template-columns: 1fr; }
	.vp-access__head { grid-template-columns: 1fr; gap: 22px; }
	.vp-stamp { display: none; }
	.vp-access__cards { grid-template-columns: 1fr; }
	.vp-brands__card { width: 134px; height: 86px; font-size: 14px; }
	.vp-how .vp-wrap { grid-template-columns: 1fr; }
	.vp-how__step { padding: 20px 0; }
	.vp-how__step + .vp-how__step { border-left: 0; border-top: 1px solid var(--vp-line); padding-left: 0; }
	.vp-apply { grid-template-columns: 1fr; padding: 32px 26px; }
	.vp-deals__grid { grid-template-columns: repeat(2, 1fr); }
}

@media (max-width: 640px) {
	/*
	 * Four claims, four bands of the phone — 258px, a third of a viewport, for
	 * four short lines of type. Two by two halves it, and the icon gets its own
	 * column so both rows align on one left edge.
	 */
	.vp-iconbar { padding: 14px 0; }
	.vp-iconbar .vp-wrap { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px 14px; }
	.vp-ib { align-items: flex-start; gap: 8px; }
	.vp-ib svg { flex: 0 0 auto; width: 18px; height: 18px; margin-top: 1px; }
	.vp-ib b { font-size: 13px; line-height: 1.3; }
	.vp-ib span { font-size: 11.5px; line-height: 1.35; }

	/*
	 * Three promo cards, three across — all of them, at every phone width.
	 *
	 * Two-up with the odd card spanning was the earlier shape. It reads as a
	 * deliberate block but costs a whole extra row, and all three cards are the
	 * same shape: one short offer and one link. On one row they are ~112px at
	 * 390px, which still holds a three-line headline — the type steps down, the
	 * count does not. No `:last-child` span here: three columns means there is
	 * no orphan left to rescue.
	 */
	.vp-promos { padding: 16px 0; }
	.vp-promos__grid { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 9px; }
	.vp-promo { height: auto; min-height: 126px; padding: 12px 11px; }
	.vp-promo::after { right: -26px; bottom: -34px; width: 104px; height: 104px; }
	.vp-promo small { font-size: 9px; letter-spacing: .09em; }
	.vp-promo__title { margin-top: 5px; font-size: 13.5px; line-height: 1.2; }
	.vp-promo__go { margin-top: 7px; font-size: 10.5px; gap: 4px; }

	/*
	 * Offer banners sit above a product row's own heading. They stay two-up on
	 * a phone as well: half a row is where the band belongs, and stacking them
	 * spends the whole top of the row on banners before the row has started.
	 *
	 * Half a phone is ~170px, which cannot hold the drawn silhouettes *and* a
	 * reading column — the art goes and the copy takes the full card. The offer
	 * type steps down a notch with it: at 19px "FREE FREIGHT OVER $1,500" wraps
	 * to four lines in 146px of text box; at 15.5px it lands on three, which is
	 * what keeps the pair no taller than the stack it replaces.
	 */
	.vp-pbanner { gap: 9px; padding: 13px 12px; min-height: 0; }
	.vp-pbanner__copy { padding-right: 0; }
	.vp-pbanner__art { display: none; }
	.vp-pbanner__kicker { font-size: 9px; letter-spacing: .12em; }
	.vp-pbanner__offer { margin-top: 4px; font-size: 15.5px; line-height: 1.12; }
	.vp-pbanner__sub { margin-top: 4px; font-size: 11px; line-height: 1.35; }
	.vp-pbanner__bullets { margin-top: 6px; gap: 4px; }
	.vp-pbanner__bullet { padding: 2px 5px; font-size: 9px; }
	/* 150px of text box: "See shipping terms" needs ~138px at 11px with the
	   arrow, and at 11.5px/11px padding it broke onto two lines. */
	.vp-pbanner__cta { gap: 4px; padding: 6px 10px; font-size: 11px; }
	.vp-pbanner__glow { top: -46px; right: -22px; width: 128px; height: 128px; }

	/* The three access cards are tall because each carries a list; tightening
	   the internal rhythm takes ~300px off the section without losing a line. */
	.vp-access { padding: 30px 0 26px; }
	.vp-access__head { gap: 14px; margin-bottom: 18px; }
	.vp-access__cards { gap: 12px; }
	.vp-ecard { padding: 17px; }
	.vp-ecard > p { margin-bottom: 12px; font-size: 13.5px; line-height: 1.5; }
	.vp-ecard ul { gap: 7px; margin-bottom: 14px; }

	/*
	 * Three cards, two columns, the odd one spanning the row. Single-file they
	 * were the fourth-longest block on the phone; paired they cost half that,
	 * and a 170px card still holds a heading, a line and a short list — the CTA
	 * below is the only thing that has to wrap, which it already does.
	 */
	.vp-access__cards { grid-template-columns: repeat(2, minmax(0, 1fr)); }
	.vp-access__cards > :last-child:nth-child(odd) { grid-column: 1 / -1; }
	.vp-ecard__row { flex-wrap: wrap; gap: 10px; }

	/*
	 * The rep card goes on a phone (2026-09-17, client request). Its whole
	 * content is the phone number the section heading prints two cards above
	 * it, and at 234px it was a third of this section's height for a line of
	 * type, a caption and a button that the footer already carries.
	 */
	.vp-ecard--rep { display: none; }

	.vp-brands__card { width: 120px; height: 76px; font-size: 13px; }
	.vp-promoband { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; }
	.vp-trust .vp-wrap { grid-template-columns: 1fr; }
	.vp-trust__cell { border-right: 0; border-bottom: 1px solid var(--vp-line-2); }
	.vp-apply__steps { gap: 14px; }
	.vp-deals__grid { grid-template-columns: 1fr; }
}
