/* ==========================================================================
   Wayvo — hero  [wayvo_hero]

   Enqueued by the shortcode only, so this sheet is not in the global
   $child_stylesheets list in functions.php.

   Built from the Figma export for "Frame 2341266", a 1440x800 frame.
   designs/hero-section.png is 1440x800 — exactly 1x — so the scale is 1.0 and
   the export's values go in literally. The two places the export is wrong, and
   why, are in the header of shortcodes/wayvoHeroSection.php.

   ── --wvh-scale IS A LENGTH, AND THAT IS THE WHOLE POINT ────────────────────
   "How many rendered px per design px." The literals it multiplies are
   therefore UNITLESS Figma measurements: calc(56 * var(--wvh-scale)), not
   calc(56px * ...). Same convention as wayvo-frogger-grid.css and
   wayvo-how-it-works.css, and for the same reason: a Figma frame is exactly one
   width and a browser is every width.

   IT READS BOTH AXES, WHICH THE OTHER TWO DO NOT NEED TO. They are as tall as
   their content; this one is told its height and has to fit 800 design units of
   padding and copy inside it. On a 1920x800 window the width term alone would
   scale to 1.334 and lay out 1067px of content in an 800px box. So the height
   term caps it, and at 1440x800 both come to exactly 1 — the design, 1:1.

       1440 x  800   min(1.000, 1.000) -> 1.000   the frame itself
       1920 x 1080   min(1.333, 1.350) -> 1.333   content 1066 of 1080
       1920 x  800   min(1.333, 1.000) -> 1.000   height wins
       1280 x  800   min(0.889, 1.000) -> 0.889   width wins

   SINCE 2026-10-21 THE WIDTH TERM READS --wv-cw, NOT 100cqw (Paul: content
   max 1440, tokens.css), so it stops at 1 and the 1.334 rows above no longer
   happen — 1920 x 1080 now renders at 1.000 like the frame. The cards are
   the exception: the deck is sized in vw, and stays full-bleed.

   The 0.6 floor is where it stops shrinking. At 767 and below the PHONE
   LAYOUT takes over (the block at the bottom of this sheet, from
   designs/hero-mobile.png) and sets its own sizes in px.
   ========================================================================== */

/* The section cannot be its own container query container, so the scale is read
   from this wrapper.

   FULL-BLEED. The hero is measured from the SCREEN edge — the cards are cut off
   by it and the toggle sits 40 in from it — so it breaks out of whatever boxed
   container the page builder put it in. Same as .wv-frogger-wrap, and the same
   caveat: on a platform with a classic (non-overlay) scrollbar, 100vw is the
   scrollbar's width wider than the page, which shows as ~17px of horizontal
   scroll. If that bites, set the Elementor section to full width with no gaps
   and drop the two lines below. */
.wv-hero-wrap {
	container-type: inline-size;
	width: 100vw;
	margin-left: calc(50% - 50vw);

	/* THE HEIGHT IS THE SCREEN LESS WHATEVER SITS ABOVE THE HERO (2026-10-10).
	   A plain 100svh started BELOW the site header, so the bottom of the hero
	   — the toggle and the dots — was always under the fold, at every screen
	   size. The design has the nav floating over the hero; the site does not.

	   --wvh-height-base is the height attribute, set inline by the shortcode
	   (100svh by default). --wvh-top is how far down the page the hero starts,
	   measured by js/wayvo-hero-section.js on load and resize — header,
	   announcement banner and admin bar included, whatever they are that day.
	   Only measured when the height is viewport-based; a fixed height="700px"
	   is left as asked. Without the script it is 0, which is the old 100svh.

	   Everything inside scales off --wvh-height (see --wvh-scale), so a
	   shorter hero shrinks its content to fit rather than cropping it. */
	--wvh-height: calc(var(--wvh-height-base, 100svh) - var(--wvh-top, 0px));
}

.wv-hero {

	/* Rendered px per design px. See the note at the top before changing it. */
	--wvh-scale: max(
		0.6px,
		min(
			calc(var(--wv-cw, 100cqw) / 1440),
			calc(var(--wvh-height) / 800),
			1.334px
		)
	);

	/* THE TEXT AND CONTROLS NEVER SHRINK (Paul, 2026-10-10). Headline, copy,
	   buttons, toggle and dots — and the widths that decide where the copy
	   wraps — use this instead of --wvh-scale: the design's own size as a
	   floor, still growing with the hero on big screens. What DOES shrink on a
	   smaller screen is the room around them: the section padding, the card
	   deck and the Business cards, and how far in the toggle and dots sit.

	   Consequence on a short or narrow screen: full-size type in a smaller
	   hero leaves the cards less room between headline and copy. The mobile
	   layout is where that gets resolved. */
	--wvh-ui: max(var(--wvh-scale), 1px);

	/* Geist is loaded outside this theme (Elementor / the customizer), so the
	   family name lives here as the single place to correct it. */
	--wvh-font: "Geist", "Geist Sans", sans-serif;

	--wvh-ink: var(--wv-ink, #101011);
	--wvh-grey-200: var(--wv-grey-200, #f5f5f5);

	/* MEASURED, NOT A TOKEN. The export flattened the headline to one colour;
	   sampled off the PNG the second clause is #898989. The nearest thing in the
	   ramp is --wv-grey-500 at #8d8b8b, which is close enough to look like a
	   match and is not one — so this is a literal, and if it ever earns a place
	   in the ramp it should go in there first and be referenced from here. */
	--wvh-muted: #898989;

	/* The video's own ground, run over the WHOLE section rather than over the
	   card band. Sampled down the design: 245 at the top, 255 at the bottom,
	   monotonic across all 800 of it. The export's flat #F5F5F5 is the fallback
	   underneath the designer's flattened video still, not the ground itself. */
	--wvh-bg: linear-gradient(180deg, #f5f5f5 0%, #ffffff 100%);

	/* The swipe between Personal and Business. */
	--wvh-swipe: 700ms;
	--wvh-swipe-ease: cubic-bezier(0.65, 0, 0.35, 1);

	/* Frame 2341266 — the box and the ground. Its layout (padding, flex) is
	   on each .wv-hero__panel now, since 2026-10-10, because there are two
	   panels and each is a whole hero. The gradient stays here so it does
	   not move when they do. */
	position: relative;
	isolation: isolate;
	display: block;
	width: 100%;
	height: var(--wvh-height);
	/* THE LAST RESORT ON A SHORT SCREEN (2026-10-15). The script guarantees the
	   cards a minimum band between headline and copy. It first takes the room
	   from the top padding (--wvh-squeeze, below); if that is not enough, it
	   sets this, and the hero runs a little past the fold rather than putting
	   the cards over the text. Unset — so a no-op — whenever the screen fits. */
	min-height: var(--wvh-min-h, 0px);
	background: var(--wvh-bg);
	overflow: hidden;

	/* The deck is sized against this; it inherits down to the layer. */
	--wvhd-height: var(--wvh-height);

	/* The design's card band is NOT centred — its centre line is y=435 of 800,
	   35 below the section's own middle. */
	--wvhd-offset-y: calc(35 * var(--wvh-scale));
}

/* ── The two panels ──────────────────────────────────────────────────────────
   Each is the whole section's box with the design's padding, stacked on top
   of each other. The one not on show sits off to its own side — Business to
   the right, Personal to the left — so switching slides both at once:
   Business comes in from the right, Personal comes back from the left.

   visibility follows the transform: switched on at once when a panel comes
   in, and off only AFTER it has slid out, so the leaving panel is visible for
   the whole swipe and unreachable once it is gone. The script also sets
   `inert` on the hidden panel; this is the no-JS half of the same thing. */
.wv-hero__panel {
	position: absolute;
	inset: 0;
	box-sizing: border-box;
	display: flex;
	flex-direction: column;
	justify-content: center;
	align-items: center;
	padding:
		calc(133 * var(--wvh-scale))
		calc(60 * var(--wvh-scale))
		calc(60 * var(--wvh-scale));
	/* --wvh-squeeze is set by the script when the cards' band between headline
	   and copy would be too thin: the top padding gives way first, down to 40.
	   0 whenever the screen fits. */
	padding-top: max(
		calc(40 * var(--wvh-scale)),
		calc(133 * var(--wvh-scale) - var(--wvh-squeeze, 0px))
	);

	/* CLIPPED TO ITS OWN BOX (2026-10-21). Both card rows run past the
	   panel's edges — the Business cards up to three slots to the left, the
	   Personal deck's outer cards to the right. At rest the section's own
	   overflow hides that, but during the swipe those overhanging cards
	   travelled across the OTHER panel, hung on screen after their panel had
	   gone, and then blinked out when visibility flipped at the end. Clipped
	   here, each row leaves and arrives with its panel's edge. No change at
	   rest: the panel is the section's size. */
	overflow: hidden;

	/* --wvh-drag is the finger's offset while the section is being swiped
	   (js/wayvo-hero-section.js, initSwipe); 0 otherwise. */
	transform: translateX(var(--wvh-drag, 0px));
	visibility: visible;
	transition:
		transform var(--wvh-swipe) var(--wvh-swipe-ease),
		visibility 0s linear 0s;
}

.wv-hero[data-wv-hero-state="personal"] .wv-hero__panel--business,
.wv-hero[data-wv-hero-state="business"] .wv-hero__panel--personal {
	visibility: hidden;
	transition:
		transform var(--wvh-swipe) var(--wvh-swipe-ease),
		visibility 0s linear var(--wvh-swipe);
}

.wv-hero[data-wv-hero-state="personal"] .wv-hero__panel--business {
	transform: translateX(calc(100% + var(--wvh-drag, 0px)));
}

.wv-hero[data-wv-hero-state="business"] .wv-hero__panel--personal {
	transform: translateX(calc(-100% + var(--wvh-drag, 0px)));
}

/* ── Swiping (2026-10-21) ────────────────────────────────────────────────────
   Vertical scrolling stays the browser's; sideways is the script's, which
   drags the panels with the finger. While the finger is down both panels
   show and nothing eases — the transition takes over again on release.
   Selectors one class up on the hidden-panel rules above, so they win. */
.wv-hero {
	touch-action: pan-y pinch-zoom;
}

.wv-hero.is-dragging .wv-hero__panel.wv-hero__panel {
	visibility: visible;
	transition: none;
}

@media (prefers-reduced-motion: reduce) {
	.wv-hero__panel,
	.wv-hero[data-wv-hero-state] .wv-hero__panel {
		transition: none;
	}
}

/* ── Personal deck: capped by the band it sits in (2026-10-15) ───────────────
   The deck sizes its card from the hero's WHOLE height (0.9254 x height), which
   knows nothing about the headline and copy it sits between. On a short window
   that card was taller than the gap and ran over both. The script measures the
   gap — exactly as it does for the Business cards — and sets --wvhd-fit-w and
   --wvhd-offset-y on the deck, so the card is never more than its share of
   the gap and sits in the middle of it. The deck's own size is kept as the
   upper limit; without the script the cap is inert. */
.wv-hero .wv-hero-deck {
	--wvhd-card-w: min(
		23.54vw,
		calc(0.9254 * var(--wvhd-height)),
		var(--wvhd-fit-w, 100000px)
	);
}

/* ── Business carousel ───────────────────────────────────────────────────────
   From designs/hero-business-carousel.mp4 and designs/Hero_Business.png
   (2026-10-10). Grey cards until the photos arrive.

   MEASURED. The video is 1920 wide and the design 1422; they agree to within
   a pixel once each is divided by its own width:

       centre card   256 x 338 of 1920   190 x 251 of 1422   -> 192 x 253 at 1440
       other cards   0.719 of the centre (184 / 256, 136 / 190)
       slot          472 of 1920         349 of 1422         -> 354 at 1440
       centre line   y 444 of the design's 800               -> 44 below the middle

   So the card and the slot are the design's numbers times --wvh-scale, like
   everything else in the hero that is allowed to shrink. The card's own
   contents (pill, title) are in em off the card's width, so they scale with it
   — they are part of the card's artwork, not hero text, and the "text never
   shrinks" rule does not apply to them.

   Placement: every card is centred, then moved by --o (slots from the
   centre) and scaled by --k, both written by the script each frame.

   ── SIZED BY HEIGHT, NOT WIDTH (2026-10-10) ─────────────────────────────────
   Paul: prioritise a suitable height; five cards on screen is not required.
   The script measures the gap between the headline and the copy on the
   Business panel and sets --wvhb-w so the centre card is 66% of that gap's
   height — the design's proportion, 253 of its 385 — and --wvhb-offset-y so
   the row sits in the middle of it. So the cards are as big as the height
   allows, and can never run into the text, which they did at the phone
   breakpoint when they were sized off the width.

   The slot follows the card (1.84 cards apart, 354 / 192), so a bigger card
   spreads the row and fewer show. The values below are the no-script
   fallback only. */
.wv-hero-biz {
	--wvhb-w: calc(192 * var(--wvh-scale));
	--wvhb-slot-ratio: 1.84;
	--wvhb-slot: calc(var(--wvhb-w) * var(--wvhb-slot-ratio));
	--wvhb-offset-y: calc(44 * var(--wvh-scale));

	position: absolute;
	inset: 0;
	transform: translateY(var(--wvhb-offset-y));
	pointer-events: none;
}

.wv-hero-biz__card {
	position: absolute;
	top: 50%;
	left: 50%;
	box-sizing: border-box;
	width: var(--wvhb-w);
	height: calc(var(--wvhb-w) * 1.32);
	overflow: hidden;

	/* 16 card units at the design's 192 — the em everything inside is set in. */
	font-size: calc(var(--wvhb-w) / 12);
	border-radius: 0.75em;

	/* The placeholder grey. Dark enough for the white title to read on it,
	   which a light grey would not be. Goes when the photos arrive. */
	background: #9a9a9a;

	transform:
		translate(-50%, -50%)
		translateX(calc(var(--o, 0) * var(--wvhb-slot)))
		scale(var(--k, 1));
	will-change: transform;
}

.wv-hero-biz__media {
	position: absolute;
	inset: 0;
}

.wv-hero .wv-hero-biz__img {
	display: block;
	width: 100%;
	height: 100%;
	max-width: none;
	object-fit: cover;
	object-position: center;
}

/* A fade under the white title, ONLY when there is a photo. Several of the
   photos are pale at the bottom — the wicker tray, the white tablecloth, the
   cardboard box — and white type on them was illegible. Bottom 45% of the card,
   clear above that, so the pill at the top and the picture itself are left
   alone. The grey placeholder needs none, so :has() keeps it off. */
.wv-hero-biz__media:has(img)::after {
	content: "";
	position: absolute;
	inset: 55% 0 0;
	background: linear-gradient(180deg, rgba(16, 16, 17, 0) 0%, rgba(16, 16, 17, 0.55) 100%);
	pointer-events: none;
}

/* Pill: 20 tall, 13 label, 8 padding, 18 in from the top and left — the
   design's numbers at its 190 card. The pill sets its own font-size, which
   changes what its em means, so its box is in thirteenths of that em.
   Colour per card, inline. */
.wv-hero-biz__pill {
	position: absolute;
	top: calc(18em / 13);
	left: calc(18em / 13);
	z-index: 1;
	display: inline-flex;
	align-items: center;
	height: calc(20em / 13);
	padding: 0 calc(8em / 13);
	border-radius: 9999px;
	background: var(--wv-hero-biz-pill, #e5e5e5);

	font-family: var(--wvh-font);
	font-size: 0.8125em;
	font-weight: 500;
	line-height: 1;
	letter-spacing: -0.02em;
	white-space: nowrap;
	color: var(--wvh-ink);
}

/* Title: 23, white, 18 in from the bottom and sides, wrapping over up to
   three lines as the long ones do in the video. In twenty-thirds of its own
   em for the same reason as the pill. */
.wv-hero-biz__title {
	position: absolute;
	left: calc(18em / 23);
	right: calc(18em / 23);
	bottom: calc(18em / 23);
	z-index: 1;

	font-family: var(--wvh-font);
	font-size: 1.4375em;
	font-weight: 500;
	line-height: 1;
	letter-spacing: -0.02em;
	color: #ffffff;
}

/* ── Frame 530 ───────────────────────────────────────────────────────────────
   space-between over the full 607, which is what puts the headline on the top
   edge and the copy on the bottom one with the cards passing through the gap.
   The export also carries gap: 220 — that is Figma stating the gap it happened
   to measure, and space-between overrides it. Building both would fight. */
.wv-hero__inner {
	position: relative;
	z-index: 1;
	display: flex;
	flex-direction: column;
	justify-content: space-between;
	align-items: center;
	flex: 1 1 auto;
	width: 100%;
	min-height: 0;
}

/* Frame 2341274. */
.wv-hero__head {
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: calc(20 * var(--wvh-ui));
	width: calc(538 * var(--wvh-ui));
	max-width: 100%;
}

/* H2 in the export, h1 in the markup — it is the page's heading, and Figma
   names its type styles by size rather than by level.

   The export's `display: flex; align-items: center` on the text node is Figma
   describing its own vertical centring and is not built. */
.wv-hero__heading {
	margin: 0;
	font-family: var(--wvh-font);
	font-weight: 500;
	font-size: calc(56 * var(--wvh-ui));
	line-height: 100%;
	letter-spacing: -0.02em;
	text-align: center;
	color: var(--wvh-ink);
}

.wv-hero__heading-muted {
	color: var(--wvh-muted);
}

/* Frame 2341263. */
.wv-hero__foot {
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: calc(20 * var(--wvh-ui));
	width: 100%;
}

/* P4. 408 wide is what makes it break over two lines where the design does. */
.wv-hero__text {
	margin: 0;
	width: calc(408 * var(--wvh-ui));
	max-width: 100%;
	font-family: var(--wvh-font);
	font-weight: 400;
	font-size: calc(16 * var(--wvh-ui));
	line-height: 140%;
	letter-spacing: -0.01em;
	text-align: center;
	color: var(--wvh-ink);
}

/* ── Frame 2341275 ───────────────────────────────────────────────────────────
   The site button system, resized IN THIS SCOPE ONLY.

   The export draws 46px pills with 16px type, which is exactly the size the
   tokens were pulled back from on 2026-09-16 — applied site-wide it grew every
   button, some by 92%. It is still the right size HERE, for the same reason it
   is right on the gift card product page: a wide, uncluttered section with two
   large controls. So it is set as a local override of the button tokens, never
   by touching tokens.css. Precedent: giftCardProduct.css:140 and
   wayvo-how-it-works.css:847.

       15 + 16 + 15 = 46, and 20 + 139 + 20 = 179 for the grey one. */
.wv-hero__actions {
	display: flex;
	flex-direction: row;
	align-items: center;
	gap: calc(10 * var(--wvh-ui));

	--wv-btn-pad-y: calc(15 * var(--wvh-ui));
	--wv-btn-pad-x: calc(20 * var(--wvh-ui));
	--wv-btn-min-h: calc(46 * var(--wvh-ui));
	--wv-btn-size: calc(16 * var(--wvh-ui));
}

/* ── The toggle and the dots ─────────────────────────────────────────────────
   Both are placed against the SECTION, not against the copy: 40 in from the
   screen edge and 40 up from the bottom, outside the 60 padding. In the export
   that reads as top: 728 on a 32-tall pill and top: 752 on an 8-tall dot —
   different tops, the same bottom edge at 760.

   They switch the panels (js/wayvo-hero-section.js). The toggle is the tablist;
   the dots are the same switch again for the pointer, kept in step by the
   script. Both sit outside the panels, so they stay put while the panels
   slide. */
.wv-hero__toggle,
.wv-hero__dots {
	position: absolute;
	bottom: calc(40 * var(--wvh-scale));
	z-index: 2;
	display: flex;
	flex-direction: row;
	align-items: center;
}

/* Frame 684. 40 in from the CONTENT edge, not the screen's, since
   2026-10-21: the first term is the margin either side of a 1440 column. */
.wv-hero__toggle {
	left: calc((100cqw - var(--wv-cw, 100cqw)) / 2 + 40 * var(--wvh-scale));
	justify-content: center;
	padding: calc(4 * var(--wvh-ui));
	background: var(--wvh-grey-200);
	border-radius: 99999px;
}

/* ── THESE ARE <button>s, AND TWO VENDORS PAINT EVERY <button> ──────────────
   Elementor's Site Settings -> Buttons writes `.elementor-kit-N button` (0,1,1)
   and `.elementor-kit-N button:hover, … button:focus` (0,2,1), in a sheet that
   loads after this one. OceanWP's customizer writes `body button` (0,1,1) and
   `body button:hover` (0,2,1) the same way. A single class here is 0,1,0 and
   loses every property either of them sets — which is how the unselected
   toggle and both dots turned solid black when the kit's buttons were set.

   So: the class is DOUBLED (0,2,0) on every rule that sets a property a kit
   can set, and colour is restated for :hover/:focus/:active at 0,3,0. Geometry
   stays out of the state rules, or the phone sizes below (0,2,0) would lose to
   them under the cursor. Same convention as tokens.css. */
.wv-hero__toggle-btn.wv-hero__toggle-btn {
	position: relative;
	appearance: none;
	-webkit-appearance: none;
	display: flex;
	justify-content: center;
	align-items: center;
	height: calc(20 * var(--wvh-ui));
	min-height: 0;
	margin: 0;
	padding: 0 calc(6 * var(--wvh-ui));
	border: 0;
	border-radius: 9999px;
	box-shadow: none;
	cursor: pointer;

	font-family: var(--wvh-font);
	font-style: normal;
	font-weight: 500;
	/* 12 in the export, +15% (Paul, 2026-10-10). */
	font-size: calc(13.8 * var(--wvh-ui));
	line-height: 140%;
	letter-spacing: -0.02em;
	text-transform: none;
	text-decoration: none;
	text-shadow: none;
	font-feature-settings: 'tnum' on, 'lnum' on;

	/* Colour only — the ghost pill below fades in, and selecting fades the
	   black in rather than snapping. Nothing that changes size is listed. */
	transition: background-color 150ms ease, color 150ms ease;
}

.wv-hero__toggle-btn.wv-hero__toggle-btn,
.wv-hero__toggle-btn.wv-hero__toggle-btn:hover,
.wv-hero__toggle-btn.wv-hero__toggle-btn:focus,
.wv-hero__toggle-btn.wv-hero__toggle-btn:active {
	background: transparent;
	color: #1c1d1d;
	/* The whole border, not just its colour, in every state. `border: 0` on
	   the base rule only covers the resting state; the kit's :hover/:focus
	   rule (0,2,1) out-ranks that, and a border appearing under the cursor
	   nudged the pill by its width (2026-10-15). */
	border: 0;
	box-shadow: none;
}

/* #000000, and that is the export's value — not --wv-ink, which is #101011.
   Kept literal because it is what was drawn; if it turns out to be a slip it
   should be corrected in Figma and come back through an export.
   Each state here is one attribute more specific than its unselected twin,
   so it wins by specificity rather than by sitting after them. */
.wv-hero__toggle-btn.wv-hero__toggle-btn[aria-selected="true"],
.wv-hero__toggle-btn.wv-hero__toggle-btn[aria-selected="true"]:hover,
.wv-hero__toggle-btn.wv-hero__toggle-btn[aria-selected="true"]:focus,
.wv-hero__toggle-btn.wv-hero__toggle-btn[aria-selected="true"]:active {
	background: #000000;
	color: #ffffff;
}

/* ── Hover: a ghost pill (Paul, 2026-10-15) ───────────────────────────────────
   The unselected option shows a faint pill in exactly the selected one's
   shape — a preview of what clicking will do. White on the desktop's grey
   track; the phone's track is white, so it is grey there (below). The
   selected option does not react, since clicking it does nothing.

   (hover: hover) so a tap on a phone does not leave a ghost stuck on the
   option just tapped. 0,4,0 — above the unselected states (0,3,0); the
   :not() means it can never meet the selected rules at all. */
@media (hover: hover) {
	.wv-hero__toggle-btn.wv-hero__toggle-btn:hover:not([aria-selected="true"]) {
		background: #ffffff;
	}
}

@media (prefers-reduced-motion: reduce) {
	.wv-hero__toggle-btn.wv-hero__toggle-btn {
		transition: none;
	}
}

/* The pill is 32 tall and the button inside it is 20, so the 4 of padding
   either side is dead to the pointer. This claims it back without moving
   anything. */
.wv-hero__toggle-btn::after {
	content: "";
	position: absolute;
	inset: calc(-4 * var(--wvh-ui)) 0;
}

/* Ellipse 1 and 2. The 10 gap is 1392 - (1374 + 8). */
.wv-hero__dots {
	right: calc((100cqw - var(--wv-cw, 100cqw)) / 2 + 40 * var(--wvh-scale));
	gap: calc(10 * var(--wvh-ui));
}

/* Doubled for the same reason as the toggle — see above. */
.wv-hero__dot.wv-hero__dot {
	position: relative;
	appearance: none;
	-webkit-appearance: none;
	width: calc(8 * var(--wvh-ui));
	height: calc(8 * var(--wvh-ui));
	min-height: 0;
	margin: 0;
	padding: 0;
	border: 0;
	border-radius: 50%;
	box-shadow: none;
	cursor: pointer;
}

.wv-hero__dot.wv-hero__dot,
.wv-hero__dot.wv-hero__dot:hover,
.wv-hero__dot.wv-hero__dot:focus,
.wv-hero__dot.wv-hero__dot:active {
	background: var(--wv-grey-300, #e5e5e5);
	border: 0;
	box-shadow: none;
}

.wv-hero__dot.wv-hero__dot[data-active="true"],
.wv-hero__dot.wv-hero__dot[data-active="true"]:hover,
.wv-hero__dot.wv-hero__dot[data-active="true"]:focus,
.wv-hero__dot.wv-hero__dot[data-active="true"]:active {
	background: var(--wvh-ink);
}

/* An 8px target is not a target. The dot stays 8px and the pointer gets 24. */
.wv-hero__dot::after {
	content: "";
	position: absolute;
	inset: calc(-8 * var(--wvh-ui));
}


/* ==========================================================================
   PHONE — 767 and below. From designs/hero-mobile.png, a 400 x 690 frame
   (2026-10-10).

   ── THE EXPORT MIXES TWO SCALES ──────────────────────────────────────────────
   The type is real px: headline 32 at 120%, copy 16 at 140%, button labels 12.
   Everything else is the DESKTOP value x 0.711 — 14.22 is 20, 32.71 is 46,
   2.84 is 4, 11.38 is 16, 5.69 is 8 — a component scaled down on the canvas.
   Those are rounded to whole px here. The toggle's 9.8px label is one of the
   scaled ones (13.79 x 0.711); drawn at 10, built at 11.5 after Paul asked
   for the toggle text 15% bigger on 2026-10-10.

   This block deliberately does NOT follow the desktop rule that text and
   controls never shrink: the phone design draws them smaller, and that is
   what is built.

   ── THE LAYOUT ──────────────────────────────────────────────────────────────
   Toggle on top, centred, then the headline; the cards through the middle;
   copy, buttons, then the dots underneath. The toggle and dots are still
   OUTSIDE the panels — they must not slide with them — so they are placed
   absolutely at the panel's padding edges, and the head and foot reserve the
   room they would have taken in the flow (toggle 26 + gap 14 = 40 above the
   headline). The dots no longer take room: since 2026-10-21 they sit halfway
   down the bottom padding, below the buttons.

   ── THE HEIGHT ──────────────────────────────────────────────────────────────
   Still the fitted screen height (screen less the header, see .wv-hero-wrap),
   not the export's 690. The export's 160 / 80 padding is held as a proportion
   of that height (23% / 11.6%), capped at the export's values and floored so a
   short phone still fits. Content needs about 250 of the height plus the
   cards; on a 667 phone after the header there is room.
   ========================================================================== */

@media (max-width: 767px) {

	.wv-hero {
		/* Less --wvh-squeeze on a short screen (see .wv-hero__panel), down to
		   24 — the toggle sits at this line, so it moves up with it.

		   55% of the export's 160 / 23.2% since 2026-10-21 (Paul: "reduce
		   by just less than half" — too much blank under the menu). The room
		   goes to the band, so the cards grow into it; see the deck below. */
		--wvhm-pt: max(
			24px,
			calc(clamp(24px, calc(var(--wvh-height) * 0.128), 88px) - var(--wvh-squeeze, 0px))
		);
		--wvhm-pb: clamp(32px, calc(var(--wvh-height) * 0.116), 80px);

		/* 40 at the design's 400 wide, 20 at 360 — so the 320 content column
		   (and the 289 of buttons in it) still fits on a 360 phone. */
		--wvhm-px: clamp(16px, calc((100vw - 320px) / 2), 40px);

		/* The cards' centre line sits midway between the headline and the
		   copy: (top padding - bottom padding + head 113 - foot 133) / 2 from
		   the panel's centre. At the export's own numbers that is 30, and the
		   design's centre card sits at 25 — close enough to be the same rule. */
		--wvhd-offset-y: calc((var(--wvhm-pt) - var(--wvhm-pb)) / 2);
	}

	.wv-hero__panel {
		padding: var(--wvhm-pt) var(--wvhm-px) var(--wvhm-pb);
	}

	/* ── The cards ───────────────────────────────────────────────────────────
	   The deck's desktop sizing gives a 94px card at 400 wide. The phone
	   design's centre card is 165 of 400 (41.25vw), with the neighbours about
	   50px in from each edge, which puts them 52vw away. Set ON the deck
	   element, at 0,2,0, because the deck declares these on itself and an
	   inherited value would be shadowed. card-h, slot, perspective and depth
	   all follow from these two. */
	.wv-hero .wv-hero-deck {
		/* 48vw, was the design's 41.25 (Paul, 2026-10-21: the animation
		   scales up into the room the smaller top padding frees). The band
		   fit (--wvhd-fit-w) still caps it on a short phone. The gap keeps
		   the design's 52 : 41.25, so a neighbour still peeks in each side. */
		--wvhd-card-w: min(
			var(--wvhd-phone-w, 48vw),
			calc(0.9254 * var(--wvhd-height)),
			var(--wvhd-fit-w, 100000px)
		);
		/* 60 : 48, the same spacing at any card size. --wvhd-phone-w is
		   the script's: the card grown so the room above and below it is a
		   third less (2026-10-21, fitPersonalDeck). Without the script, 48vw. */
		--wvhd-gap: calc(1.25 * var(--wvhd-card-w));
	}

	/* The Business carousel. Sized by the script from the gap, as on desktop;
	   the phone only packs the row tighter — 1.28 cards apart rather than
	   1.84, so a neighbour peeks in at each edge as on the personal deck. No
	   phone version in the video or designs, so that ratio is my choice. The
	   width and offset here are the no-script fallback. */
	.wv-hero-biz {
		--wvhb-w: 36vw;
		--wvhb-slot-ratio: 1.28;
		--wvhb-offset-y: var(--wvhd-offset-y);
	}

	/* ── Copy ──────────────────────────────────────────────────────────────── */

	.wv-hero__head {
		gap: 14px;
		width: 332px;
		/* Room for the toggle, which is placed over it (see above): its 26
		   plus the 14 gap. */
		padding-top: 40px;
	}

	/* Type sizes from here down, 2026-10-21 (Paul, "sizes" taken as px, as
	   for the phone menu): headline and copy +1, buttons and toggle +2. */
	.wv-hero__heading {
		font-size: 33px;
		line-height: 120%;
	}

	/* No room reserved for the dots any more: they sit lower, inside the
	   bottom padding (see the dots). */
	.wv-hero__foot {
		gap: 14px;
	}

	.wv-hero__text {
		width: 272px;
		font-size: 17px;
	}

	/* 35 tall, 14 either side, 15px labels (one up from 14, 2026-10-21, with
	   every phone button in tokens.css), 11 apart. ALWAYS ONE LINE (Paul,
	   2026-10-21): the pair may run wider than the column, out to 16px from
	   the screen edge; only past that does the script (fitButtons) step the
	   label size down. Neither the row
	   nor a label may wrap, or the script would have nothing to measure. */
	.wv-hero__actions {
		/* Its own width, which may be wider than the copy column: centred in
		   it, the pair spreads evenly into the panel's side padding. */
		width: max-content;
		flex-wrap: nowrap;
		justify-content: center;
		gap: 11px;

		--wv-btn-pad-y: 7px;
		--wv-btn-pad-x: 14px;
		--wv-btn-min-h: 35px;
		--wv-btn-size: 15px;
	}

	.wv-hero__actions > .wv-btn {
		flex-shrink: 0;
		white-space: nowrap;
	}

	/* ── Toggle: top centre, white ─────────────────────────────────────────── */

	.wv-hero__toggle {
		top: var(--wvhm-pt);
		bottom: auto;
		left: 50%;
		transform: translateX(-50%);
		padding: 3px;

		/* White on the phone (#FFFFFF in the export); grey on desktop. */
		background: #ffffff;
	}

	.wv-hero__toggle-btn.wv-hero__toggle-btn {
		height: 20px;
		padding: 0 8px;
		/* 10 as drawn, +15% (Paul, 2026-10-10), then +2 (2026-10-21). */
		font-size: 13.5px;
	}

	.wv-hero__toggle-btn::after {
		inset: -3px 0;
	}

	/* The ghost pill on the white phone track — see the desktop rule. One
	   class more, so it wins on specificity rather than by coming later. */
	@media (hover: hover) {
		.wv-hero .wv-hero__toggle-btn.wv-hero__toggle-btn:hover:not([aria-selected="true"]) {
			background: var(--wvh-grey-200);
		}
	}

	/* ── Dots: bottom centre, under the buttons ────────────────────────────── */

	.wv-hero__dots {
		right: auto;
		left: 50%;
		/* Halfway down the bottom padding, not on its top edge (Paul,
		   2026-10-21: dots lower). */
		bottom: calc(var(--wvhm-pb) / 2);
		transform: translateX(-50%);
		gap: 7px;
	}

	.wv-hero__dot.wv-hero__dot {
		width: 6px;
		height: 6px;
	}

	.wv-hero__dot::after {
		inset: -6px;
	}
}
