/**
 * The shop front.
 *
 * Three layers, and the order is the point.
 *
 * 1. **Tokens.** Every size, colour, radius and duration is named once on
 *    `.pod-landing`, so a section added later reaches for one rather than
 *    inventing a fourth grey.
 * 2. **Utilities**, applied through Elementor's own *CSS Classes* field. That is
 *    the seam this page is built on: the words stay editable by whoever is
 *    writing them, and the look stays here, in version control.
 * 3. **Components** — the tiles, cards and price card our own shortcodes render,
 *    where we own the markup and can name things properly.
 *
 * **Everything is scoped under `.pod-landing`**, a body class added only on the
 * front page. Without it this type scale and these buttons would apply to the
 * shop, the checkout and every product page, which is how a restyle of the home
 * page becomes a site-wide regression nobody connects to the home page. The one
 * exception is the component block, which is unscoped on purpose so the
 * shortcodes can be dropped on any page and bring their own styling.
 *
 * **No breakpoints.** Every size is a `clamp()` and every grid a
 * `minmax( min( 100%, … ), 1fr )`, so the page reflows continuously instead of
 * snapping at three widths somebody picked in 2014. There is no width at which
 * it has nothing to say.
 *
 * **The typeface is Archivo**, set site-wide by the theme and self-hosted; this
 * file never names a family. It does use weight 800, which is downloaded because
 * `bin/provision.php` asks for it by name — see the note there before changing a
 * display weight, because an unrequested weight is silently synthesised rather
 * than refused.
 */

/* --- 1. Tokens ------------------------------------------------------------ */

/*
 * In `tokens.css`, which this stylesheet depends on and which also serves the
 * shop and the cart drawer.
 */

/* The page's text colour. Not in `tokens.css`, which must not style anything. */
.pod-landing,
.pod-shop {
	color: var( --pod-ink );
}

/* --- 2. Type -------------------------------------------------------------- */

/*
 * Exaggerated hierarchy on purpose: the headline is four times the body, not
 * one and a half times it. A page where every level is nearly the size of the
 * one above reads as undesigned, and that was the diagnosis here.
 */
/*
 * The Display tier (`docs/design-standards.md` §3): the hero's headline, the
 * one Display heading on the page. The shop's title used to share this rule
 * and is now the Title tier, in `shop.css`.
 *
 * The heading element selectors are held to the page's own Elementor document
 * with a weightless `:where()`, so the site footer and the cart drawer, which
 * also print headings on this page, keep their own sizes.
 *
 * The Elementor selector carries an extra `.elementor` on purpose. The builder
 * stores a 48px size on the hero heading and prints it as
 * `.elementor-4388 .elementor-element.elementor-element-… .elementor-heading-title`,
 * four classes, which held the headline at 48px on a phone and on a desktop
 * alike. Four classes and an element out-rank it, so the token decides.
 */
.pod-landing :where( [data-elementor-type='wp-page'] ) h1,
.pod-landing .elementor .elementor-widget-heading h1.elementor-heading-title {
	font-size: var( --pod-display-size );
	font-weight: 800;
	letter-spacing: -0.03em;
	line-height: 1.02;
	text-wrap: balance;
}

.pod-landing :where( [data-elementor-type='wp-page'] ) h2,
.pod-landing .elementor-widget-heading h2.elementor-heading-title {
	font-size: var( --pod-h2-size );
	font-weight: 800;
	letter-spacing: var( --pod-title-tracking );
	line-height: 1.08;
	text-wrap: balance;
}

/*
 * The card heading: the steps and the promise cards, and the look of the trust
 * facts' titles, which are paragraphs (`.pod-trust-title`, `bin/build-landing.php`)
 * because the strip comes before the page's first H2.
 */
.pod-landing :where( [data-elementor-type='wp-page'] ) h3,
.pod-landing .elementor-widget-heading h3.elementor-heading-title,
.pod-landing .pod-trust-title .elementor-heading-title {
	font-size: var( --pod-h3-size );
	font-weight: 800;
	letter-spacing: -0.01em;
	line-height: 1.3;
	text-wrap: balance;
}

/*
 * `:where( [data-elementor-type='wp-page'] )` here and on the heading-spacing
 * rules below: the page's own document, not the site footer, which is also an
 * Elementor document (`wp-post`) on this page. Without it these rules restyled the
 * footer on the home page only (17px description, 8px under each heading), so the
 * footer measured differently here from every other page. `:where()` weighs
 * nothing, so no rule's standing against any other changes.
 */
.pod-landing :where( [data-elementor-type='wp-page'] ) .elementor-widget-text-editor {
	color: var( --pod-ink-soft );
	font-size: 1.0625rem;
	line-height: 1.62;
	max-width: 62ch;
}

.pod-landing :where( [data-elementor-type='wp-page'] ) .elementor-widget-text-editor p:last-child {
	margin-bottom: 0;
}

/* --- 3. Utilities --------------------------------------------------------- */

/*
 * A small label above a heading. Carried on Elementor's "CSS Classes" field
 * rather than styled inline, so anybody adding a section later gets the same
 * label by typing `pod-eyebrow` into that field.
 *
 * Keyed off the widget's class and Elementor's `.elementor-heading-title`,
 * never off the tag: an eyebrow is a label, not a heading, and the builder
 * prints it as a paragraph rather than an `h6` so the outline starts at the H1.
 */
.pod-landing .pod-eyebrow .elementor-heading-title,
.pod-landing .pod-eyebrow,
.pod-shop .pod-eyebrow {
	color: var( --pod-accent );
	font-size: 0.8125rem;
	font-weight: 700;
	letter-spacing: 0.02em;
	line-height: 1.2;
}

/*
 * As a paragraph, the eyebrow picks up Astra's `.entry-content p` bottom margin
 * (1.6em, one class and an element), which out-ranks Elementor's own reset on
 * `.elementor-heading-title` and would open the 8px between the label and its
 * heading to nearly 30. The step numbers take the same rule, whatever their tag.
 */
.pod-landing .pod-eyebrow .elementor-heading-title,
.pod-landing .pod-step-num .elementor-heading-title {
	margin: 0;
}

.pod-landing .pod-lead,
.pod-shop .pod-lead {
	font-size: clamp( 1.0625rem, 1.5vw, 1.25rem );
	line-height: 1.55;
}

/*
 * The step numeral. Set at the same weight as the headline and in the accent,
 * so it reads as a label on the step rather than as a heading competing with
 * the one beside it.
 */
.pod-landing .pod-step-num .elementor-heading-title,
.pod-landing .pod-step-num {
	color: var( --pod-accent );
	font-size: 0.8125rem;
	font-weight: 700;
	letter-spacing: 0.02em;
}

/*
 * On the tinted "How it works" section the accent is 4.2:1 against
 * `--pod-surface-2`, short of 4.5:1 for 13px text, so its eyebrow and step
 * labels take the deeper blue (docs/design-standards.md §3, Eyebrow).
 */
.pod-landing .elementor > .e-con:has( .pod-step-num ) :is( .pod-eyebrow, .pod-step-num ) .elementor-heading-title {
	color: var( --pod-accent-deep );
}

/* --- 4. Buttons ----------------------------------------------------------- */

/*
 * The extra `.elementor` is load-bearing. Astra prints
 * `body .elementor-button.elementor-size-sm { border-radius: 0; padding: 16px 28px }`,
 * which is two classes and an element, so without it this rule lost and every
 * builder button came out square with the theme's padding, beside a round price
 * card button.
 *
 * Height is set rather than left to padding and line-height, so a filled button
 * and a bordered one are the same 48px, and so is the price card's button and
 * the fields above it. The transparent border is what keeps the filled one from
 * being two pixels shorter than the outlined one.
 */
.pod-landing .elementor .elementor-button {
	align-items: center;
	border: 1px solid transparent;
	border-radius: var( --pod-radius-pill );
	box-shadow: none;
	box-sizing: border-box;
	display: inline-flex;
	font-size: var( --pod-btn-size );
	font-weight: 700;
	justify-content: center;
	letter-spacing: 0;
	line-height: 1.2;
	min-height: var( --pod-btn-h );
	padding: 0 var( --pod-btn-x );
	text-transform: none;
	transition:
		background-color var( --pod-fast ) var( --pod-ease ),
		border-color var( --pod-fast ) var( --pod-ease ),
		color var( --pod-fast ) var( --pod-ease );
}

/*
 * The primary button, flat (`docs/design-standards.md` §5): no shadow and no
 * lift, the colour carries it. It had a tinted drop shadow and rose a pixel on
 * hover, which no other primary button in the shop did.
 */
.pod-landing .elementor-widget-button:not( .pod-btn-quiet ) .elementor-button {
	background-color: var( --pod-accent );
	border-color: var( --pod-accent );
	color: var( --pod-on-ink );
}

.pod-landing .elementor-widget-button:not( .pod-btn-quiet ) .elementor-button:hover {
	background-color: var( --pod-accent-deep );
	border-color: var( --pod-accent-deep );
	color: var( --pod-on-ink );
}

/*
 * The one focus ring. Without it the filled button showed nothing on focus and
 * the outlined ones a 1px white outline, which is invisible on white.
 */
.pod-landing .elementor .elementor-button:focus-visible {
	outline: var( --pod-focus-width ) solid var( --pod-accent );
	outline-offset: var( --pod-focus-offset );
}

/*
 * The quiet button: the standard's secondary button. `button_type => 'info'` was
 * tried first and emits no distinguishing class at all — both buttons came back
 * with an identical class list and an identical blue — so the secondary action
 * is marked with a class of ours instead.
 */
.pod-landing .pod-btn-quiet .elementor-button {
	background-color: var( --pod-surface );
	border-color: var( --pod-field-border );
	color: var( --pod-ink );
}

.pod-landing .pod-btn-quiet .elementor-button:hover {
	background-color: var( --pod-surface-2 );
	border-color: var( --pod-ink );
	color: var( --pod-ink );
}

/* --- 4b. Spacing ---------------------------------------------------------- */

/*
 * The page gutter, on the one element that is the content column.
 *
 * Elementor caps this at 1200px and centres it; below that width it becomes the
 * full viewport and needs a gutter of its own. It had one by accident — 10px of
 * Elementor's default container padding, doubled to 20px in the sections that
 * happened to nest a row — which is both too tight for a phone and different from
 * section to section.
 */
.pod-landing .elementor > .e-con > .e-con-inner {
	padding-inline: var( --pod-gutter );
}

/*
 * The column gutter, as a symmetric pair: padding on the cells and a matching
 * negative margin on the row, so cards are spaced from each other while the
 * first and last stay flush with the container. A one-sided `padding-right` —
 * which is what this replaces — leaves the last cell in every row narrower than
 * its neighbours.
 *
 * The row cannot simply use `column-gap`. The cells carry explicit percentage
 * widths adding to 100, and a gap on top of that overflows the row and wraps
 * every cell onto its own line.
 *
 * **Mind the depth.** A section is
 *
 *     .e-con-inner  >  .e-con        >  .e-con  >  .e-con
 *                      content box      row        cells
 *
 * and the content box is always there — `section()` emits it whether or not the
 * section has a row. Targeting one level too high puts the gutter on the row and
 * the negative margin on the content box, which is how the hero came out twelve
 * pixels right of every heading below it while measuring as "fixed".
 *
 * **Container spacing is owned here and not in the builder**, which is the second
 * thing on this page Elementor will not let a container have. Its generated rule
 * for a specific container sets `--padding-left: 0px` at three classes of
 * specificity and the computed padding still came back as its own 10px default,
 * on every row on the page. Setting it in the builder as well would be two
 * sources of truth for one number, and the dead one looks authoritative.
 *
 * Reached by structure rather than by a class because **Elementor silently drops
 * `_css_classes` on a container** — checked, not assumed.
 */
.pod-landing .elementor > .e-con > .e-con-inner > .e-con {
	margin-inline: 0;
	padding: 0;
}

.pod-landing .elementor > .e-con > .e-con-inner > .e-con > .e-con {
	margin-inline: calc( -0.5 * var( --pod-apart ) );
	padding: 0;

	/*
	 * The width has to grow by what the margins pull out, or the row is shifted
	 * left rather than widened — Elementor pins every container to `width: 100%`,
	 * so a negative margin moves it and leaves it the same size. The symptom is
	 * the first card sitting flush and the last stopping a gutter short of the
	 * container, which looks like the row is off-centre.
	 */
	max-width: none;
	width: calc( 100% + var( --pod-apart ) );
}

.pod-landing .elementor > .e-con > .e-con-inner > .e-con > .e-con > .e-con {
	padding-block: 0;
	padding-inline: calc( 0.5 * var( --pod-apart ) );
}

/*
 * A row of exactly two is a split — a picture and an argument — and it wants a
 * wider gutter than a row of four, which is four of the same thing.
 *
 * Stated as "a row whose second cell is also its last" rather than with a marker
 * widget, because it is the truth about the layout and cannot fall out of step
 * with it. Every split section on this page has two cells; every grid row has
 * four.
 *
 * **Half the split, but never more than the page gutter.** The row reaches out
 * past the content column by half its gutter on each side, into the page's own
 * gutter. At 768px that gutter is 30.7px and half the split 36, so the row ran
 * 5px past the viewport and the page scrolled sideways. Capping the reach, and
 * the cells' padding by the same amount, keeps the content flush with the
 * headings above it at every width; only the gap between the two halves
 * narrows, and only where the gutter is narrower than 36px.
 */
.pod-landing .elementor > .e-con > .e-con-inner > .e-con > .e-con:has( > .e-con:nth-child( 2 ):last-child ) {
	margin-inline: calc( -1 * min( 0.5 * var( --pod-split ), var( --pod-gutter ) ) );
	width: calc( 100% + 2 * min( 0.5 * var( --pod-split ), var( --pod-gutter ) ) );
}

.pod-landing .elementor > .e-con > .e-con-inner > .e-con > .e-con:has( > .e-con:nth-child( 2 ):last-child ) > .e-con {
	padding-inline: min( 0.5 * var( --pod-split ), var( --pod-gutter ) );
}

/*
 * On a phone the two halves stack, and a gutter between columns that are no
 * longer side by side is just an indent on everything.
 */
@media ( max-width: 767px ) {
	.pod-landing .elementor > .e-con > .e-con-inner > .e-con > .e-con,
	.pod-landing .elementor > .e-con > .e-con-inner > .e-con > .e-con:has( > .e-con:nth-child( 2 ):last-child ) {
		margin-inline: 0;
		width: 100%;
	}

	.pod-landing .elementor > .e-con > .e-con-inner > .e-con > .e-con > .e-con,
	.pod-landing .elementor > .e-con > .e-con-inner > .e-con > .e-con:has( > .e-con:nth-child( 2 ):last-child ) > .e-con {
		padding-inline: 0;
	}

	/*
	 * Sections close up on a phone. The builder's 72px above and below every
	 * section put 144px of blank between two sections on a 390px screen, more
	 * than a third of the view. Two thirds of each section's own padding, on the
	 * 8px grid, keeps their proportions: 72 becomes 48, the 48px strip 32, the
	 * Read from the builder's variables, so a section given new padding there
	 * still shrinks in proportion.
	 */
	.pod-landing .elementor > .e-con > .e-con-inner {
		padding-block-end: round( nearest, calc( var( --padding-block-end ) * 2 / 3 ), 8px );
		padding-block-start: round( nearest, calc( var( --padding-block-start ) * 2 / 3 ), 8px );
	}

	/*
	 * Except the top of the first section. The space between the site header
	 * and the hero stays the builder's full 56px on a phone: shrunk to 40 with
	 * the rest, the headline sat too close under the header. The shop keeps
	 * the same 56 (`shop.css`), so the two pages open alike.
	 */
	.pod-landing .elementor > .e-con:first-child > .e-con-inner {
		padding-block-start: var( --padding-block-start );
	}
}

/*
 * The rhythm inside a section.
 *
 * Elementor has one gap per container, and it is set to the tightest pair on the
 * page — 8px, a label and the heading it belongs to. Everything that needs more
 * air asks for it here, on the widget that needs it, so the three distances read
 * as three rather than as one. Every gap on this page measured 20px before.
 *
 * The `.elementor` in each selector is load-bearing, not decoration. Elementor
 * zeroes widget margins with `.elementor-widget:not( :last-child )`, which is two
 * classes — exactly what `.pod-landing .pod-lead` is — so the two tied and the
 * later stylesheet won. These measured 8px until the extra class went in.
 */
.pod-landing .elementor:where( [data-elementor-type='wp-page'] ) .elementor-widget-heading:not( .pod-eyebrow ):not( .pod-step-num ) {
	margin-bottom: calc( var( --pod-near ) - var( --pod-tight ) );
}

.pod-landing .elementor .pod-lead {
	margin-bottom: calc( var( --pod-break ) - var( --pod-tight ) );
}

/*
 * A lead is an introduction, so it only opens a gap when something follows it.
 */
.pod-landing .elementor .pod-lead:last-child {
	margin-bottom: 0;
}

/*
 * Three steps, not nine lines.
 *
 * Each `Step 0X` starts a group and needs more above it than the lines inside the
 * group have between them — otherwise one step's paragraph and the next step's
 * number sit as far apart as a heading and its own text.
 */
.pod-landing .elementor .pod-step-num {
	margin-top: calc( var( --pod-break ) - var( --pod-tight ) );
}

.pod-landing .elementor .pod-step-num:first-child {
	margin-top: 0;
}

/*
 * Where a step follows the section heading rather than another step, the
 * heading's own bottom margin and the step's top margin would stack to 48 —
 * against the 40 the same break gets everywhere else on the page. One of the two
 * stands down.
 */
.pod-landing .elementor:where( [data-elementor-type='wp-page'] ) .elementor-widget-heading:not( .pod-eyebrow ):not( .pod-step-num ):has( + .pod-step-num ) {
	margin-bottom: 0;
}

/*
 * The gap under a heading scales with the heading.
 *
 * The 16px above is sized for a section heading and its introduction. Under an
 * `h3` — a step or a card title — it put the line 23px below the title against
 * 11px between the label and the title, measured ink to ink, so each line
 * drifted towards the next card instead of belonging to its own. A small title
 * takes the container's 8px alone, about 15px visible once the paragraph's
 * leading is counted, on every card and every step alike.
 */
.pod-landing .elementor:where( [data-elementor-type='wp-page'] ) .elementor-widget-heading:not( .pod-eyebrow ):not( .pod-step-num ):is( :has( h3 ), .pod-trust-title ) {
	margin-bottom: 0;
}

/*
 * A section heading with no lead under it still introduces what follows, so it
 * opens the same 40px break a lead does. Without this, "Popular right now" and
 * "If it is wrong, it is on us" sat 16px above their grids while "What would you
 * like printed?" sat 40px above its own, because only that one had a paragraph
 * to carry the gap.
 */
.pod-landing .elementor:where( [data-elementor-type='wp-page'] ) .elementor-widget-heading:not( .pod-eyebrow ):not( .pod-step-num ):is( :has( + .elementor-widget-shortcode ), :has( + .e-con ) ) {
	margin-bottom: calc( var( --pod-break ) - var( --pod-tight ) );
}

/* --- 5. The hero ---------------------------------------------------------- */

/*
 * The big photographs: the hero, the wall preview and the material shot.
 *
 * **No aspect ratio, deliberately.** A full-bleed crop was tried first and it is
 * the wrong move with this library: every shot is square, so forcing 4:5 took a
 * horizontal banner and cut both ends off it. These pictures are already
 * composed — the crop is the photographer's, not the stylesheet's. The tiles
 * crop because a grid needs one shape; a single large image does not.
 *
 * The lift shadow is what does the work instead. It reads as a print lying on
 * the page rather than a picture pasted into it, which is the whole subject.
 */
.pod-landing .pod-hero-art img,
.pod-hero-shot img {
	border-radius: var( --pod-radius-xl );
	box-shadow: var( --pod-shadow-lift );
	display: block;
	height: auto;
	width: 100%;
}

/*
 * The photograph changes with the dropdown beside it.
 *
 * `is-swapping` is on for the moment between choosing a product and its picture
 * being decoded and ready to paint. It dims rather than hides: the old photograph
 * stays visible and slightly recedes, which reads as "fetching the next one"
 * rather than as the page breaking. Hiding it would leave a hole the size of the
 * hero, and the hole would be longest on the slow connections least able to
 * afford it.
 */
.pod-hero-shot {
	display: block;
	position: relative;
}

.pod-hero-shot img {
	transition: opacity 220ms var( --pod-ease );
}

.pod-hero-shot.is-swapping img {
	opacity: 0.55;
}

@media ( prefers-reduced-motion: reduce ) {
	.pod-hero-shot img {
		transition: none;
	}
}

/* --- 6. Components -------------------------------------------------------- */

/*
 * Unscoped from here down. These are rendered by shortcodes that can be placed
 * on any page, and their styling travels with them.
 */

.pod-tiles,
.pod-grid {
	display: grid;
	gap: var( --pod-apart );

	/*
	 * `min( 100%, … )` and not a bare floor. A column can then never be wider
	 * than the container, which is what stops a single tile overflowing a narrow
	 * phone — and the floor is set from the widest row this catalogue actually
	 * has, so five categories stay on one line rather than breaking 4 + 1.
	 */
	grid-template-columns: repeat( auto-fit, minmax( min( 100%, 11.5rem ), 1fr ) );
}

.pod-tile,
.pod-card {
	background: var( --pod-surface );
	border: 1px solid var( --pod-line );
	border-radius: var( --pod-radius-lg );
	box-shadow: var( --pod-shadow-sm );
	color: inherit;
	display: flex;
	flex-direction: column;
	overflow: hidden;
	position: relative;
	text-decoration: none;
	transition:
		border-color var( --pod-fast ) var( --pod-ease ),
		box-shadow var( --pod-fast ) var( --pod-ease ),
		transform var( --pod-fast ) var( --pod-ease );
}

.pod-tile:hover,
.pod-tile:focus-visible,
.pod-card:hover,
.pod-card:focus-visible {
	border-color: transparent;
	box-shadow: var( --pod-shadow );
	transform: translateY( -3px );
}

/*
 * The one focus ring. The theme's link outline (1px at a 1px offset) out-ranked
 * the shared component's, which weighs nothing. Focus appears at once (§6): the
 * card's shadow and lift, eased on hover, are not eased in on focus.
 */
.pod-tile:focus-visible,
.pod-card:focus-visible {
	outline: var( --pod-focus-width ) solid var( --pod-accent );
	outline-offset: var( --pod-focus-offset );
	transition: none;
}

/*
 * **The picture fills the card.**
 *
 * This is the single change that fixes how the page reads. It was
 * `object-fit: contain` inside a padded well, with `mix-blend-mode: multiply` on
 * top — so a white product on a white ground was shrunk, letterboxed, and then
 * flattened onto a tint, and five categories rendered as five empty boxes. A
 * 4:5 crop that the photograph fills leaves no ground to disappear into.
 */
.pod-tile__art,
.pod-card__art {
	aspect-ratio: 4 / 5;
	background: var( --pod-surface-2 );
	display: block;
	overflow: hidden;
	position: relative;
}

.pod-tile__art img,
.pod-card__art img {
	display: block;
	height: 100%;
	object-fit: cover;
	transition: transform 400ms var( --pod-ease );
	width: 100%;
}

.pod-tile:hover .pod-tile__art img,
.pod-card:hover .pod-card__art img {
	transform: scale( 1.04 );
}

.pod-tile__body {
	display: flex;
	flex-direction: column;
	gap: var( --pod-tight );
	padding: var( --pod-near );
}

.pod-tile__name,
.pod-card__name {
	font-size: 1.0625rem;
	font-weight: 700;
	letter-spacing: -0.01em;
}

/*
 * Prices baseline-align across a row whatever the names above them do, which is
 * what lets the eye read down a column of figures instead of hunting for them.
 */
.pod-tile__from,
.pod-card__price {
	color: var( --pod-ink-soft );
	font-size: 0.9375rem;
	font-weight: 700;
	margin-top: auto;
}

.pod-card__name,
.pod-card__price {
	padding-inline: var( --pod-near );
}

.pod-card__name {
	padding-top: var( --pod-near );
}

.pod-card__price {
	padding-bottom: var( --pod-near );
}

/* WooCommerce's own range strikethrough, which says nothing useful in a grid. */
.pod-card__price del {
	display: none;
}

.pod-card__price ins {
	background: none;
	text-decoration: none;
}

/* --- 7. The price card ---------------------------------------------------- */

/*
 * The one component on this page that does something rather than saying
 * something.
 *
 * It sits over the hero photograph, so it carries a real shadow and an opaque
 * ground: a translucent card on a photograph is a card you cannot read, and this
 * one has numbers in it.
 */
.pod-quote {
	/*
	 * The card is as tall as its contents. It sits in a flex cell that stretches
	 * to the height of the photograph beside it, and without these two it would
	 * stretch with it and spread its rows into the spare height.
	 */
	align-content: start;
	align-self: start;
	background: var( --pod-surface );
	border: 1px solid var( --pod-line );
	border-radius: var( --pod-radius-xl );
	box-shadow: var( --pod-shadow-lift );
	display: grid;
	gap: var( --pod-near );
	max-width: 27rem;
	padding: var( --pod-apart );
}

/*
 * **The card's paragraphs have to out-specify the theme.**
 *
 * These component rules are deliberately unscoped so the shortcodes can be
 * dropped on any page and bring their own styling — and the price of that is
 * that they land at single-class specificity in somebody else's stylesheet.
 * Astra styles body copy as `.entry-content p`, which is one class and one
 * element, so it beat `.pod-quote__price { margin: 0 }` and put 41 pixels of
 * paragraph margin between the figure and the button. Measured, not guessed:
 * the computed `margin-bottom` came back as `40.86px` against a declared `0`.
 *
 * Two classes rather than `!important`, because the next person to need a
 * different margin here should be able to get one.
 */
.pod-quote .pod-quote__title,
.pod-quote .pod-quote__price,
.pod-quote .pod-quote__note {
	margin: 0;
}

.pod-quote__title {
	font-size: 1.0625rem;
	font-weight: 700;
	letter-spacing: -0.01em;
}

.pod-quote__row {
	display: grid;
	gap: var( --pod-tight );
	grid-template-columns: 1fr 1fr 5rem;
}

.pod-quote__field {
	display: grid;
	gap: var( --pod-hair );
	min-width: 0;
}

/* The standard's field label: 0.875rem/600 in ink, 4px above its field. */
.pod-quote__label {
	color: var( --pod-ink );
	font-size: 0.875rem;
	font-weight: 600;
	line-height: 1.4;
}

/*
 * The standard's text field (`docs/design-standards.md` §5): 48px, radius 12,
 * a `--pod-field-border` edge on a surface fill.
 *
 * Two classes throughout. Astra styles `input[type="number"]` at one class and
 * an element, which beat a bare `.pod-quote__input` on the three number fields
 * and not on the select: its 0.75em padding stood the row under "Product" 55px
 * against its 47, and its 2px radius and pale #e2e2e2 border were what the
 * number fields actually showed.
 */
.pod-quote__field .pod-quote__input {
	background: var( --pod-surface );
	border: 1px solid var( --pod-field-border );
	border-radius: var( --pod-radius );
	box-shadow: none;
	box-sizing: border-box;
	color: var( --pod-ink );
	font: inherit;
	font-size: var( --pod-field-size );
	height: var( --pod-btn-h );
	padding-block: 0;
	padding-inline: 0.75rem;

	/* Astra gives fields `transition: all`; the focus border must appear at once (§6). */
	transition: none;
	width: 100%;
}

/*
 * The standard's field focus: the border thickens in the accent, and a
 * transparent outline stays for Windows' forced-colours mode, which drops box
 * shadows.
 */
.pod-quote__field .pod-quote__input:focus {
	border-color: var( --pod-accent );
	box-shadow: 0 0 0 1px var( --pod-accent );
	outline: 2px solid transparent;
}

/*
 * The figure. Big, because it is the answer to the question the card exists to
 * ask, and tabular so it does not jump sideways while somebody is typing.
 */
.pod-quote__price {
	font-size: clamp( 1.75rem, 2.6vw, 2.25rem );
	font-variant-numeric: tabular-nums;
	font-weight: 800;
	letter-spacing: -0.02em;
	line-height: 1.1;
	min-height: 1.1em;
	padding-top: 0.2rem;
}

.pod-quote__note {
	color: var( --pod-ink-soft );
	font-size: 0.875rem;
	line-height: 1.45;
}

/*
 * An empty note takes no room at all.
 *
 * It used to hold a line open with `min-height`, so that the card did not jump
 * when a note appeared. That was worth it while the note was there most of the
 * time — it carried the minimum-charge explanation. With that gone it says
 * nothing until somebody types a quantity above one, so it was reserving a line
 * for nothing and putting 52px between the price and the button: two 16px gaps
 * with 20px of empty element between them.
 *
 * `display: none` rather than a zero height, because a grid still gives a track
 * with no content its gap. Collapsing the track is what closes both.
 */
.pod-quote__note:empty {
	display: none;
}

/*
 * The price card's button: the standard's primary, flat. It had a tinted drop
 * shadow and rose a pixel on hover.
 *
 * `:focus` is restated because Astra paints `button:focus` in its own palette
 * at one class and an element, which out-ranks the bare class; the ring comes
 * from `:focus-visible`, and the hover fill is last so it wins when both apply.
 */
.pod-quote__go,
.pod-quote__go:focus {
	background: var( --pod-accent );
	border: 1px solid var( --pod-accent );
	border-radius: var( --pod-radius-pill );
	box-shadow: none;
	color: var( --pod-on-ink );
	cursor: pointer;
	font: inherit;
	font-size: var( --pod-btn-size );
	font-weight: 700;
	letter-spacing: 0;
	min-height: var( --pod-btn-h );
	padding: 0 var( --pod-btn-x );
	text-transform: none;
	transition:
		background-color var( --pod-fast ) var( --pod-ease ),
		border-color var( --pod-fast ) var( --pod-ease );
}

.pod-quote__go:focus-visible {
	outline: var( --pod-focus-width ) solid var( --pod-accent );
	outline-offset: var( --pod-focus-offset );
}

.pod-quote__go:hover {
	background: var( --pod-accent-deep );
	border-color: var( --pod-accent-deep );
	color: var( --pod-on-ink );
}

@media ( max-width: 24rem ) {
	.pod-quote__row {
		grid-template-columns: 1fr 1fr;
	}

	.pod-quote__field--narrow {
		grid-column: 1 / -1;
	}
}

/* --- 8. Icons ------------------------------------------------------------- */

/*
 * A line icon on a white disc.
 *
 * It began as a tinted rounded square with coral crop marks on two corners,
 * which at 46px was three decorations competing inside one small element, and
 * went to a bare line in the accent colour. Bare, at 28px, it floated: nothing
 * gave it an edge, and on the tinted strip and the promise cards it read as
 * smaller than the title under it. A plain white disc is one decoration, not
 * three, and both places that use icons sit on a tint for it to stand against.
 * 48px puts it on the same step as the buttons and fields.
 */
.pod-landing .pod-icon-badge {
	align-items: center;
	background: var( --pod-surface );
	border-radius: var( --pod-radius-pill );
	color: var( --pod-accent );
	display: inline-flex;
	height: 48px;
	justify-content: center;
	margin-bottom: calc( var( --pod-near ) - var( --pod-tight ) );
	width: 48px;
}

.pod-icon {
	height: 28px;
	width: 28px;
}

.pod-landing .pod-icon-badge .pod-icon {
	height: 24px;
	width: 24px;
}

/* --- 8a. The trust strip -------------------------------------------------- */

/*
 * Four facts in a row, lighter than the promises further down.
 *
 * It is "a reassurance, not a chapter" (see `bin/build-landing.php`), and the
 * promises are now cards, so this must not become a second row of cards. It
 * gets structure from hairline dividers instead of surfaces, and its lines step
 * down to 15px. It sits right under the hero, where the price card is the thing
 * to read.
 *
 * Keyed off `pod-mark-trust` on each icon widget, since Elementor drops
 * `_css_classes` on a container.
 *
 * Desktop keeps the icon above the text: a quarter of the row leaves about 250px,
 * and an icon beside that would squeeze each line to four. Once the cells are
 * half or full width the icon moves beside the text, which is the shorter and
 * more usual shape for a list of facts. The breakpoints are Elementor's own,
 * because those are the widths at which the builder changes the cells from 25%
 * to 50% to 100%.
 */
/*
 * 15px, with a floor under it. The theme shrinks the root size on smaller
 * screens, which took a plain `0.9375rem` to 13.7px on a phone, smaller than
 * the body copy anywhere else on the page.
 */
.pod-landing .elementor > .e-con:has( .pod-mark-trust ) .elementor-widget-text-editor {
	font-size: max( 0.9375rem, 15px );
	line-height: 1.55;
}

@media ( min-width: 768px ) {
	/* A wider gutter than a grid of cards, so a divider has room either side. */
	.pod-landing .elementor > .e-con:has( .pod-mark-trust ) .e-con > .e-con:has( > .e-con > .pod-mark-trust ) {
		margin-inline: calc( -1 * var( --pod-apart ) );
		width: calc( 100% + 2 * var( --pod-apart ) );
	}

	.pod-landing .elementor > .e-con:has( .pod-mark-trust ) .e-con > .e-con > .e-con:has( > .pod-mark-trust ) {
		padding-inline: var( --pod-apart );
	}
}

@media ( min-width: 1025px ) {
	.pod-landing .elementor > .e-con:has( .pod-mark-trust ) .e-con > .e-con > .e-con:has( > .pod-mark-trust ) + .e-con {
		border-inline-start: 1px solid var( --pod-line );
	}
}

@media ( max-width: 1024px ) {
	.pod-landing .elementor > .e-con:has( .pod-mark-trust ) .e-con > .e-con > .e-con:has( > .pod-mark-trust ) {
		align-content: start;
		column-gap: var( --pod-near );
		display: grid;
		grid-template-columns: 48px minmax( 0, 1fr );
		row-gap: var( --pod-tight );
	}

	.pod-landing .elementor > .e-con:has( .pod-mark-trust ) .pod-mark-trust {
		grid-row: 1 / span 2;
	}

	.pod-landing .elementor > .e-con:has( .pod-mark-trust ) .pod-icon-badge {
		margin-bottom: 0;
	}
}

@media ( min-width: 768px ) and ( max-width: 1024px ) {
	.pod-landing .elementor > .e-con:has( .pod-mark-trust ) .e-con > .e-con > .e-con:has( > .pod-mark-trust ):nth-child( even ) {
		border-inline-start: 1px solid var( --pod-line );
	}
}

@media ( max-width: 767px ) {
	.pod-landing .elementor > .e-con:has( .pod-mark-trust ) .e-con > .e-con:has( > .e-con > .pod-mark-trust ) {
		row-gap: var( --pod-apart );
	}

	.pod-landing .elementor > .e-con:has( .pod-mark-trust ) .e-con > .e-con > .e-con:has( > .pod-mark-trust ) + .e-con {
		border-top: 1px solid var( --pod-line );
		padding-top: var( --pod-apart );
	}
}

/* --- 8b. The promises ----------------------------------------------------- */

/*
 * Four promises, each one a card you could point at.
 *
 * As bare columns they read as the same strip of reassurances the page opens
 * with, a second time and in smaller type, and nothing held a promise together
 * but its column. A filled surface gives each one an edge, so the row reads as
 * four separate guarantees rather than a paragraph cut into quarters. Filled,
 * not outlined or raised: these are statements, not controls, so they take no
 * shadow and no hover.
 *
 * Keyed off `pod-mark-promise` on the eyebrow, for the same reason the closing
 * panel is: Elementor drops `_css_classes` on a container.
 *
 * The row becomes a grid, so the cards keep one gutter and one height at every
 * width. The builder's 25% cells and the padding gutter from section 4b would
 * put the card surface under the gutter as well.
 *
 * **Breakpoints here, against this file's rule, because four is the wrong
 * number for `auto-fit`.** A fluid `minmax()` grid went 4 → 3 → 1, and three
 * columns of four cards left the fourth alone on a second row at tablet width.
 * Four cards divide cleanly by four, two and one, so those are the only three
 * layouts.
 */
.pod-landing .elementor > .e-con:has( .pod-mark-promise ) .e-con > .e-con:has( > .e-con .pod-icon-badge ) {
	display: grid;
	gap: var( --pod-apart );
	grid-template-columns: 1fr;
	margin-inline: 0;
	width: 100%;
}

@media ( min-width: 600px ) {
	.pod-landing .elementor > .e-con:has( .pod-mark-promise ) .e-con > .e-con:has( > .e-con .pod-icon-badge ) {
		grid-template-columns: repeat( 2, minmax( 0, 1fr ) );
	}
}

@media ( min-width: 1100px ) {
	.pod-landing .elementor > .e-con:has( .pod-mark-promise ) .e-con > .e-con:has( > .e-con .pod-icon-badge ) {
		grid-template-columns: repeat( 4, minmax( 0, 1fr ) );
	}
}

.pod-landing .elementor > .e-con:has( .pod-mark-promise ) .e-con > .e-con > .e-con:has( > .elementor-widget .pod-icon-badge ) {
	--width: auto;
	background: var( --pod-surface-2 );
	border-radius: var( --pod-radius-lg );
	padding: var( --pod-apart );
	width: auto;
}


/* --- 9. Motion ------------------------------------------------------------ */

/*
 * Sections arrive as they are scrolled to — but **only once `landing.js` has
 * added `pod-reveal-ready`**. No script, nothing hidden. That is not defensive
 * habit; it is the bug this was rewritten to fix, when an observer delivered no
 * callbacks and the whole shop front sat at zero opacity.
 */
.pod-landing.pod-reveal-ready .pod-reveal {
	opacity: 0;
	transform: translateY( 14px );
	transition:
		opacity 520ms var( --pod-ease ),
		transform 520ms var( --pod-ease );
	will-change: opacity, transform;
}

.pod-landing.pod-reveal-ready .pod-reveal.is-in {
	opacity: 1;
	transform: none;
}

@media ( prefers-reduced-motion: reduce ) {
	.pod-landing.pod-reveal-ready .pod-reveal,
	.pod-landing.pod-reveal-ready .pod-reveal.is-in {
		opacity: 1;
		transform: none;
		transition: none;
	}

	.pod-landing .elementor .elementor-button,
	.pod-tile,
	.pod-card,
	.pod-tile__art img,
	.pod-card__art img,
	.pod-quote__go {
		transition: none;
	}

	.pod-tile:hover,
	.pod-tile:focus-visible,
	.pod-card:hover,
	.pod-card:focus-visible,
	.pod-tile:hover .pod-tile__art img,
	.pod-card:hover .pod-card__art img {
		transform: none;
	}
}

/* --- 10. The closing panel ------------------------------------------------ */

/*
 * One band of ink at the foot of the page, so the call to action is the thing
 * the eye lands on after a page of white.
 *
 * Reached with `:has()` off a marker widget rather than `:last-child`, because
 * **Elementor silently drops `_css_classes` on a container** — checked, not
 * assumed: the eyebrows and rules rendered and the three container-level classes
 * came back with zero matches in the DOM. Keying off a widget inside also means
 * the section keeps its treatment when somebody reorders the page in the
 * builder, which is the whole reason the page is in a builder.
 */
/*
 * Square, and hard against the footer.
 *
 * It was a rounded panel with 72px of white under it, which made it read as a
 * card sitting on the page. Run to the full width with no corners and it reads as
 * the end of the page instead — the band the footer starts from rather than the
 * last thing floating above it.
 */
/*
 * The on-ink colours from the tokens: white for the heading, the quieter white
 * for the copy (it was 72% here and 82% on the links beside it; one value now),
 * and the lighter blue for the eyebrow, which stays legible on ink where the
 * accent does not.
 */
.pod-landing .elementor > .e-con:has( .pod-mark-finish ) {
	background: var( --pod-ink );
	color: var( --pod-on-ink );
}

.pod-landing .elementor > .e-con:has( .pod-mark-finish ) .elementor-heading-title {
	color: var( --pod-on-ink );
}

.pod-landing .elementor > .e-con:has( .pod-mark-finish ) .pod-eyebrow .elementor-heading-title {
	color: var( --pod-on-ink-accent );
}

.pod-landing .elementor > .e-con:has( .pod-mark-finish ) .elementor-widget-text-editor {
	color: var( --pod-on-ink-soft );
}

/*
 * On ink, the secondary actions stop being buttons and become links. Four
 * equal-weight buttons is four equal non-decisions; one filled button beside
 * three links is a recommendation.
 */
.pod-landing .elementor > .e-con:has( .pod-mark-finish ) .pod-btn-quiet .elementor-button {
	background-color: transparent;
	border-color: transparent;
	color: var( --pod-on-ink-soft );
	padding-inline: 0.35rem;
	text-decoration: underline;
	text-underline-offset: 0.25em;
}

.pod-landing .elementor > .e-con:has( .pod-mark-finish ) .pod-btn-quiet .elementor-button:hover,
.pod-landing .elementor > .e-con:has( .pod-mark-finish ) .pod-btn-quiet .elementor-button:focus-visible {
	background-color: transparent;
	border-color: transparent;
	color: var( --pod-on-ink );
}

/*
 * The actions sit together, a fixed 16px apart.
 *
 * Their cells carry builder widths of 28/24/24/24%, which suits four cards and
 * not four buttons: each button is only as wide as its label, so the leftover
 * share of each cell became the gap, and the three gaps measured 138, 101 and
 * 108px. Sizing each cell to its button and halving the gutter makes the group
 * one row of actions with the primary first. A phone keeps the builder's
 * full-width stack.
 */
@media ( min-width: 768px ) {
	.pod-landing .elementor > .e-con:has( .pod-mark-finish ) .e-con > .e-con:has( > .e-con > .elementor-widget-button ) {
		margin-inline: calc( -0.5 * var( --pod-near ) );
		width: calc( 100% + var( --pod-near ) );
	}

	.pod-landing .elementor > .e-con:has( .pod-mark-finish ) .e-con > .e-con > .e-con:has( > .elementor-widget-button ) {
		--width: auto;
		flex: 0 0 auto;
		padding-inline: calc( 0.5 * var( --pod-near ) );
		width: auto;
	}
}
