/*
Theme Name: Fit4Life
Theme URI: https://github.com/DG-AI-First/fit4life
Description: Child theme for the Fit4Life storefront. Brand tokens live in theme.json. Design changes made in the Site Editor are exported here with the Create Block Theme plugin so they stay versioned in git.
Author: DG AI First
Template: twentytwentyfive
Version: 1.10.0
Requires at least: 6.7
Tested up to: 6.9
Requires PHP: 8.2
License: GPL-2.0-or-later
License URI: https://www.gnu.org/licenses/gpl-2.0.html
Text Domain: fit4life
*/

/* ==========================================================================
   Colours come from theme.json. Never hardcode a brand colour here — use the
   generated custom properties so changing a token restyles the whole site.
   ========================================================================== */

/* --- Full-bleed seams ----------------------------------------------------
   WordPress separates root-level children with `margin-block-start: 1.2rem`
   and pads `.wp-site-blocks` top and bottom. Every section here is alignfull
   and carries its own vertical padding, so that gap does not space anything
   out — it just exposes the page background as a white seam between the
   header and the hero, and between the last section and the footer.

   The core rules use `:where()`, which has zero specificity, so a plain class
   selector overrides them without `!important`.
   -------------------------------------------------------------------------- */

.wp-site-blocks {
	padding-top: 0;
	padding-bottom: 0;
}

.wp-site-blocks > *,
main.wp-block-group > * {
	margin-block-start: 0;
	margin-block-end: 0;
}

/* --- Sticky footer -------------------------------------------------------
   On short pages — order confirmation, an empty cart, a filtered shop with
   two results — the document ends before the viewport does and the page
   background shows below the footer as a pale band under the dark panel.

   `min-height` on the body plus `margin-block-start: auto` on the footer
   pushes it to the bottom of the viewport when the content is short, and
   leaves it exactly where it falls when the content is long. `flex-shrink: 0`
   on the root children keeps sections from being squeezed to fit the viewport
   instead of overflowing it normally.
   -------------------------------------------------------------------------- */

body {
    min-height: 100vh;
    /* Small-viewport unit: on mobile 100vh includes the space taken by the
       browser chrome, which pushes the footer just out of reach. */
    min-height: 100svh;
    display: flex;
    flex-direction: column;
}

.wp-site-blocks {
    flex: 1 0 auto;
    display: flex;
    flex-direction: column;
}

.wp-site-blocks > * {
    flex-shrink: 0;
}

.wp-site-blocks > footer {
    margin-block-start: auto;
}

/* --- Sticky header -------------------------------------------------------
   Follows the scroll so the navigation and the cart stay reachable from the
   bottom of a long shop page.
   -------------------------------------------------------------------------- */

.wp-site-blocks > header.wp-block-template-part {
	position: sticky;
	top: 0;
	z-index: 100;

	/* The header is a flex item of .wp-site-blocks. A flex item can shrink
	   below its content, and a shrunken sticky header detaches from the top
	   edge as you scroll. */
	flex-shrink: 0;
}

/* Logged in, WordPress pins its own 32px bar over the top of the page, so the
   header has to start below it or it hides underneath. Core drops to 46px and
   makes the bar non-fixed under 783px, hence the two rules. */
body.admin-bar .wp-site-blocks > header.wp-block-template-part {
	top: 32px;
}

@media (max-width: 782px) {
	body.admin-bar .wp-site-blocks > header.wp-block-template-part {
		top: 0;
	}
}

.f4l-header {
	transition: box-shadow 0.3s ease, border-color 0.3s ease;
}

/* A little more air than the block default, so the bar reads as a considered
   height rather than text with a border under it.

   The horizontal padding has to be the page gutter, not the block default. The
   header and the footer are template parts rendered straight under
   `.wp-site-blocks`, outside `main`, so they never receive the padding that
   puts every section's content at 44px. While the page was capped at 1280 and
   centred that difference was invisible — both were centred in a much wider
   viewport. Full-width, it shows: the logo and the nav sat 20px outside the
   headings they are supposed to line up with. */
.f4l-header,
.f4l-footer {
	padding-inline: var(--f4-gutter) !important;
}

.f4l-header {
	padding-block: 1.5rem !important;
}

/* The mini-cart shipped as a bare icon with no fill and no hover state,
   sitting right next to a solid mint button — it read as decoration, not a
   control. A permanent tinted circle gives it the same visual weight as the
   nav items instead of only appearing once someone happens to hover it. */
.wc-block-mini-cart__button {
	border-radius: 999px;
	padding: 0.5rem;
	background-color: rgb(15 61 48 / 6%);
	color: var(--wp--preset--color--contrast);
	transition: background-color 0.2s ease;
}

.wc-block-mini-cart__icon {
	width: 22px;
	height: 22px;
}

.wc-block-mini-cart__button:hover,
.wc-block-mini-cart__button:focus-visible {
	background-color: var(--wp--preset--color--mint-light);
}

/* Only once the page has actually moved. A shadow sitting there from the first
   paint says "this floats" before anything floats. */
.f4l-header.is-stuck {
	border-bottom-color: transparent;
	box-shadow: 0 6px 24px rgb(15 61 48 / 8%);
}

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

/* --- Cart feedback --------------------------------------------------------
   WooCommerce's default confirmation rewrites the button to "1 in cart" and
   pushes a "View cart" link into the card. The product moves on the page as a
   reward for clicking it, the button's width jumps with the new string, and
   the confirmation appears nowhere near the cart.
   -------------------------------------------------------------------------- */

/* Out of the flow, so the card keeps its height when the link appears. */
.f4l-product__button .added_to_cart {
	position: absolute;
	width: 1px;
	height: 1px;
	padding: 0;
	margin: -1px;
	overflow: hidden;
	clip-path: inset(50%);
	white-space: nowrap;
	border: 0;
}

/* Reserve the width the longest state needs, so "Add to cart" -> "1 in cart"
   resizes nothing. */
.f4l-product__button .wp-element-button,
.f4l-product__button .wc-block-components-product-button__button {
	min-height: 46px;
}

/* The badge on the mini-cart is where the confirmation now happens: it is the
   thing that actually changed, and it is what the visitor will click next.
   The colours are !important on purpose: WooCommerce sets them inline via
   the Interactivity API, computed by swapping the mini-cart button's own
   color/background — which broke the moment the button got a real
   background (see the comment on .wc-block-mini-cart__button), because a
   6%-opacity dark fill computes to a near-invisible number. Fixed values
   beat trying to keep that computation happy. */
.wc-block-mini-cart__badge {
	transition: background-color 0.25s ease;
	background-color: var(--wp--preset--color--mint-deep) !important;
	color: var(--wp--preset--color--white) !important;
}

.wc-block-mini-cart__badge.is-bumping {
	animation: f4l-bump 0.5s cubic-bezier(0.22, 1, 0.36, 1);
}

@keyframes f4l-bump {
	0%   { transform: scale(1); }
	28%  { transform: scale(1.45); }
	60%  { transform: scale(0.94); }
	100% { transform: scale(1); }
}

/* The whole cart button leans in with it, so the movement is legible even at
   the size of a badge. */
.wc-block-mini-cart__button:has(.is-bumping) {
	animation: f4l-tilt 0.5s ease;
}

@keyframes f4l-tilt {
	0%   { transform: rotate(0); }
	30%  { transform: rotate(-9deg); }
	60%  { transform: rotate(5deg); }
	100% { transform: rotate(0); }
}

/* Motion is the whole mechanism here, so there is nothing to soften — it is
   removed entirely, and the count still updates. */
@media (prefers-reduced-motion: reduce) {
	.wc-block-mini-cart__badge.is-bumping,
	.wc-block-mini-cart__button:has(.is-bumping) {
		animation: none;
	}
}
/* --- Navigation: sliding underline ---------------------------------------
   Grows from the left on hover and retracts to the right on leave, so the
   motion reads as directional instead of just appearing and vanishing.
   -------------------------------------------------------------------------- */

.wp-block-navigation .wp-block-navigation-item__content,
.wp-block-navigation .wp-block-navigation-item__content:hover,
.wp-block-navigation .wp-block-navigation-item__content:focus,
.wp-block-navigation .wp-block-navigation-item__content:active {
	position: relative;
	padding-block-end: 0.35rem;

	/* The parent theme underlines nav links on hover. Left in place it renders
	   on top of the bar below, so the item shows two underlines at once. The
	   bar replaces it — it is present on hover, focus and current page, so no
	   state loses its affordance. */
	text-decoration: none;
	text-underline-offset: unset;
}

.wp-block-navigation .wp-block-navigation-item__content::after {
	content: "";
	position: absolute;
	inset-inline: 0;
	bottom: 0;
	height: 2px;
	background-color: var(--wp--preset--color--mint);
	border-radius: 2px;
	opacity: 0;
	transform: scaleX(0.35);
	transform-origin: left center;
	transition:
		transform 0.42s cubic-bezier(0.16, 1, 0.3, 1),
		opacity 0.28s ease-out;
}

.wp-block-navigation .wp-block-navigation-item__content:hover::after,
.wp-block-navigation .wp-block-navigation-item__content:focus-visible::after,
.wp-block-navigation .current-menu-item > .wp-block-navigation-item__content::after {
	opacity: 1;
	transform: scaleX(1);
}


/* --- Out of stock ---------------------------------------------------------
   The state exists in WooCommerce whether or not stock quantities are tracked,
   and it is the only thing standing between a visitor and a purchase they
   cannot make. Left unstyled it announced itself nowhere in the grid: the card
   kept a full mint button reading "Read more", the same visual weight as "Add
   to cart" beside it, so the only way to find out was to click.

   Hung off .outofstock, which WooCommerce writes onto the product's own list
   item, so this works in both grids — the landing and the shop — without
   either template having to know about it.
   -------------------------------------------------------------------------- */

li.outofstock {
	position: relative;
}

li.outofstock::before {
	content: "Out of stock";
	position: absolute;
	top: 1.5rem;
	left: 1.5rem;
	z-index: 2;
	padding: 0.35rem 0.75rem;
	border-radius: 999px;
	background: var(--wp--preset--color--contrast);
	color: var(--wp--preset--color--white);
	font-family: var(--wp--preset--font-family--body);
	font-size: 0.75rem;
	font-weight: 700;
	letter-spacing: 0.06em;
	text-transform: uppercase;
}

/* Enough to read as unavailable at a glance, not so much that the product
   becomes unrecognisable — someone still has to be able to tell what it is. */
li.outofstock img {
	filter: grayscale(0.4);
	opacity: 0.72;
}

/* The button here can only lead to the product page, so it stops competing
   with the cards that can actually be bought from. */
/* The specificity here is measured, not guessed. Two WooCommerce rules stand
   in the way:
   
     :root :where(.wp-element-button, .wp-block-button__link)   border-width: 0
     .wp-block-button.wc-block-components-product-button
       .wc-block-components-product-button__button              border-style: none
   
   The second is (0,3,0), so a selector at (0,2,2) loses it — and losing
   border-style alone is enough to lose the border entirely, because with
   `border-style: none` the used width is 0 whatever the declared width says.
   Naming both classes on the element brings this to (0,3,2). */
li.outofstock a.wp-element-button.wc-block-components-product-button__button,
li.outofstock button.wp-element-button.wc-block-components-product-button__button,
li.outofstock a.wp-element-button,
li.outofstock button.wp-element-button {
	background: transparent;
	border-width: 1px;
	border-style: solid;
	border-color: rgb(15 61 48 / 25%);
	color: rgb(15 61 48 / 78%);
}

li.outofstock a.wp-element-button.wc-block-components-product-button__button:hover,
li.outofstock button.wp-element-button.wc-block-components-product-button__button:hover,
li.outofstock a.wp-element-button:hover,
li.outofstock button.wp-element-button:hover {
	background: rgb(15 61 48 / 6%);
	border-color: rgb(15 61 48 / 30%);
	color: var(--wp--preset--color--contrast);
}

/* On the product page WooCommerce prints the words and nothing else, exactly
   where the buy button used to be — a sentence floating in white space at the
   moment the visitor was about to act. */
.f4l-single__info .wc-block-components-product-stock-indicator--out-of-stock {
	padding: 0.9rem 1.15rem;
	border-radius: 14px;
	background: rgb(15 61 48 / 6%);
	color: var(--wp--preset--color--contrast);
	font-weight: 700;
	font-size: 0.9375rem;
}

.f4l-oos__note {
	margin: 0.75rem 0 1.5rem;
	font-size: 0.9375rem;
	line-height: 1.6;
	color: rgb(15 61 48 / 75%);
}

/* --- Links on the dark footer -------------------------------------------
   The global link colour is tuned for light grounds. On the footer's #0F3D30
   it measures 5.96:1 the wrong way round — it is a dark ink on a dark panel.
   The brand mint reads 6.08:1 there, so the footer gets its own value.
   -------------------------------------------------------------------------- */

.wp-site-blocks > footer a:where(:not(.wp-element-button)) {
	color: var(--wp--preset--color--mint);
	text-decoration-color: rgb(47 169 127 / 45%);
	text-underline-offset: 3px;
	transition: color 0.2s ease, text-decoration-color 0.2s ease;
}

.wp-site-blocks > footer a:where(:not(.wp-element-button)):hover,
.wp-site-blocks > footer a:where(:not(.wp-element-button)):focus-visible {
	color: var(--wp--preset--color--white);
	text-decoration-color: currentColor;
}

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

	.f4l-product:hover {
		transform: none;
	}
}
/* --- Shop filters --------------------------------------------------------- */

.f4l-shop__filters {
	align-self: flex-start;
	position: sticky;
	top: 2rem;
}

.f4l-filter {
	padding: 1.25rem 1.25rem 1.5rem;
	border: 1px solid rgb(15 61 48 / 8%);
	border-radius: 14px;
	background: var(--wp--preset--color--white);
	margin-bottom: 1rem;
}

.f4l-filter__title {
	margin: 0;
	font-family: var(--wp--preset--font-family--body);
	font-size: 0.75rem;
	font-weight: 700;
	letter-spacing: 0.12em;
	text-transform: uppercase;
	opacity: 0.6;
}

.f4l-filter__list {
	list-style: none;
	margin: 0.75rem 0 0;
	padding: 0;
	display: flex;
	flex-direction: column;
	gap: 0.125rem;
}

/* An index list, not a menu of buttons. The reference gives each row a hairline
   under it and nothing else — no fill, no radius, no padding box. The row reads
   as a line in a table of contents, which is what it is: a name and how much of
   the catalogue sits behind it. Colour alone carries hover and selection. */
.f4l-filter__list a {
	display: flex;
	align-items: baseline;
	justify-content: space-between;
	flex-wrap: nowrap;
	gap: 0.625rem;
	padding: 0.625rem 0;
	border-bottom: 1px solid var(--f4-line-10);
	font-size: 0.9375rem;
	line-height: 1.3;
	text-decoration: none;
	color: var(--wp--preset--color--contrast);
	transition: color 0.18s ease;
}

/* The label and the count are explicit elements. Relying on a bare text node
   as the first flex item let the count wrap onto its own line above the name,
   which is what made the sidebar look broken. */
.f4l-filter__label {
	min-width: 0;
}

.f4l-filter__x {
	font-size: 1rem;
	line-height: 1;
	opacity: 0.55;
}

.f4l-filter__list a:hover,
.f4l-filter__list .is-active a {
	color: var(--wp--preset--color--mint);
}

.f4l-filter__list .is-active a {
	font-weight: 600;
}

.f4l-filter__count {
	font-size: 0.75rem;
	color: rgba(15, 61, 48, 0.4);
	font-variant-numeric: tabular-nums;
}

/* --- Dose chips ---------------------------------------------------------- */

.f4l-dose {
	list-style: none;
	margin: 0.75rem 0 0;
	padding: 0;
	display: flex;
	flex-wrap: wrap;
	gap: 0.5rem;
}

.f4l-dose__chip {
	display: block;
	border: 1px solid var(--f4-line-20);
	border-radius: var(--f4-r-sm);
	padding: 0.5625rem 1rem;
	font-size: 0.8125rem;
	font-weight: 600;
	line-height: 1;
	color: var(--wp--preset--color--contrast);
	text-decoration: none;
	transition: border-color 0.18s ease, background-color 0.18s ease;
}

.f4l-dose__chip:hover,
.f4l-dose__chip.is-active {
	border-color: var(--wp--preset--color--mint);
	background: var(--wp--preset--color--mint-light);
}

.f4l-filter__note {
	margin: 0.75rem 0 0;
	font-size: 0.75rem;
	opacity: 0.6;
	line-height: 1.5;
}

/* --- Screen reader text ---------------------------------------------------
   The theme never defined this class, so labels marked as screen-reader-only
   were still laid out: inside the price grid they counted as grid items and
   pushed the inputs onto extra rows. Hiding them properly — clipped, not
   `display:none`, so assistive technology still reads them — fixes the layout
   and the semantics at once.
   -------------------------------------------------------------------------- */

.screen-reader-text {
	position: absolute !important;
	width: 1px;
	height: 1px;
	padding: 0;
	margin: -1px;
	overflow: hidden;
	clip-path: inset(50%);
	white-space: nowrap;
	border: 0;
}

.screen-reader-text:focus {
	position: static !important;
	width: auto;
	height: auto;
	margin: 0;
	clip-path: none;
}

/* --- Search --------------------------------------------------------------- */

/* A filled field, not an outlined pill with a button bolted to the end. The
   reference draws one soft mint rectangle with the magnifier sitting inside it
   on the left, so the control reads as a place to type rather than as a widget
   with two halves. */
.f4l-search {
	display: flex;
	align-items: center;
	gap: 0.625rem;
	padding: 0.8125rem 1rem;
	border: 1px solid transparent;
	border-radius: var(--f4-r-md);
	background: var(--wp--preset--color--mint-light);
	transition: border-color 0.18s ease, box-shadow 0.18s ease;
}

.f4l-search:focus-within {
	border-color: var(--wp--preset--color--mint);
	box-shadow: 0 0 0 3px rgb(47 169 127 / 16%);
}

.f4l-search input {
	flex: 1;
	min-width: 0;
	border: 0;
	background: none;
	padding: 0;
	font-size: 0.875rem;
	color: var(--wp--preset--color--contrast);
}

.f4l-search input::placeholder {
	color: var(--f4-ink-55);
}

.f4l-search input:focus {
	outline: none;
}

/* `order` moves the submit to the left of the field visually while leaving it
   after the field in the DOM. That is the order both should have: you tab into
   the box you type in, then to the control that sends it. Reversing the markup
   to get the same picture would put the submit first in the tab order for no
   reason a keyboard user would recognise. */
.f4l-search button {
	order: -1;
	flex: 0 0 auto;
	display: flex;
	align-items: center;
	justify-content: center;
	width: auto;
	height: auto;
	padding: 0;
	border: 0;
	border-radius: 0;
	background: none;
	color: var(--wp--preset--color--mint);
	cursor: pointer;
	transition: color 0.18s ease;

	/* Collapses the whitespace around the inline SVG. Left in, those text
	   nodes become layout boxes of their own and shove the icon off centre. */
	font-size: 0;
	line-height: 0;
}

.f4l-search button svg {
	display: block;
}

.f4l-search button:hover {
	color: var(--wp--preset--color--mint-deep);
}

/* --- Applied filters ------------------------------------------------------ */

.f4l-filter__head {
	display: flex;
	align-items: baseline;
	justify-content: space-between;
	gap: 0.5rem;
}

.f4l-filter__clear {
	font-size: 0.75rem;
	color: var(--wp--preset--color--mint-dark);
	text-decoration: none;
	border-bottom: 1px solid currentColor;
}

.f4l-chips {
	list-style: none;
	margin: 0.85rem 0 0;
	padding: 0;
	display: flex;
	flex-wrap: wrap;
	gap: 0.4rem;
}

/* Each chip removes only its own filter, so narrowing down is reversible one
   step at a time instead of all-or-nothing. */
.f4l-chips a {
	display: inline-flex;
	align-items: center;
	gap: 0.4rem;
	padding: 0.3rem 0.6rem;
	border-radius: 999px;
	background: var(--wp--preset--color--mint-light);
	color: var(--wp--preset--color--contrast);
	font-size: 0.8125rem;
	text-decoration: none;
	transition: background-color 0.18s ease;
}

.f4l-chips a:hover {
	background: var(--wp--preset--color--mint);
}

.f4l-chips__x {
	font-size: 0.95rem;
	line-height: 1;
	opacity: 0.6;
}

/* --- Live search state ---------------------------------------------------
   A brief dim while results are in flight. Deliberately subtle and without a
   spinner: the request is usually faster than a spinner takes to register,
   and a flashing loader on every keystroke is worse than a quiet fade.
   -------------------------------------------------------------------------- */

.f4l-shop.is-loading .wp-block-woocommerce-product-collection {
	opacity: 0.45;
	transition: opacity 0.15s ease;
	pointer-events: none;
}

@media (prefers-reduced-motion: reduce) {
	.f4l-shop.is-loading .wp-block-woocommerce-product-collection {
		transition: none;
	}
}

/* --- Shop hero ------------------------------------------------------------ */

.f4l-crumbs {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 0.4rem;
	font-size: 0.8125rem;
	opacity: 0.7;
	margin-bottom: 0.85rem;
}

.f4l-crumbs a {
	color: inherit;
	text-decoration: none;
	border-bottom: 1px solid transparent;
	transition: border-color 0.18s ease;
}

.f4l-crumbs a:hover {
	border-bottom-color: currentColor;
}

.f4l-crumbs [aria-current] {
	font-weight: 600;
	opacity: 0.95;
}

.f4l-hero-shop__title {
	margin: 0;
	font-family: var(--wp--preset--font-family--display);
	font-size: clamp(2.5rem, 5vw, 3.75rem);
	font-weight: 500;
	line-height: 1.05;
	letter-spacing: -0.015em;
}

.f4l-hero-shop__intro {
	margin: 1rem 0 0;
	max-width: 48ch;
	opacity: 0.78;
}

/* --- Order confirmation ---------------------------------------------------
   The last screen of the purchase, and the one that was doing the least. The
   default template answers "what did I buy"; on a telehealth store the more
   urgent question is "what happens now", so that is given the space.
   -------------------------------------------------------------------------- */

/* Split: the message left on mint-light, the receipt right on dark green. The
   ratio is the reference's — the copy side is wider because it carries a
   headline, a paragraph and two buttons, while the receipt is five short
   rows. */
.f4l-order-hero {
	display: grid;
	grid-template-columns: 1.15fr 0.85fr;
	align-items: stretch;
}

.f4l-order-hero__copy {
	padding: 4.5rem 2.75rem;
	background: var(--wp--preset--color--mint-light);
}

/* Tick drawn in CSS rather than shipped as an image: one glyph does not
   justify a request, and it inherits the brand colour for free. */
.f4l-confirm__mark {
	position: relative;
	width: 52px;
	height: 52px;
	margin: 0 0 1.5rem;
	border-radius: 999px;
	background: var(--wp--preset--color--mint);
}

/* The ring that pulses. On its own element so the tick underneath stays put —
   scaling the disc itself would drag the checkmark with it. */
.f4l-confirm__mark::before {
	content: "";
	position: absolute;
	inset: 0;
	border-radius: 999px;
	background: var(--wp--preset--color--mint);
	animation: f4l-confirm-pulse 2.6s ease-in-out infinite;
}

.f4l-confirm__mark::after {
	content: "";
	position: absolute;
	left: 50%;
	top: 46%;
	width: 16px;
	height: 8px;
	border-left: 3px solid var(--wp--preset--color--forest);
	border-bottom: 3px solid var(--wp--preset--color--forest);
	border-radius: 1px;
	transform: translate(-50%, -50%) rotate(-45deg);
}

@keyframes f4l-confirm-pulse {
	0%, 100% { opacity: 0.35; transform: scale(1); }
	50%      { opacity: 0.9;  transform: scale(1.06); }
}

/* The status block emits an <h1> and a <p> of its own — "Order received" plus
   the sentence under it — which is the headline-and-lead pair the reference
   draws. So the two are styled separately here rather than the container being
   sized as one lump. */
.f4l-confirm__status {
	margin: 0;
}

.f4l-confirm__status h1 {
	margin: 0;
	font-family: var(--wp--preset--font-family--display);
	font-size: clamp(2.5rem, 5.78vw, 4.625rem);
	font-weight: 700;
	line-height: 0.96;
	letter-spacing: -0.04em;
	color: var(--wp--preset--color--contrast);
	text-wrap: pretty;
}

.f4l-confirm__status p {
	margin: 1.25rem 0 0;
	max-width: 420px;
	font-family: var(--wp--preset--font-family--body);
	font-size: 1.09375rem;
	font-weight: 400;
	line-height: 1.6;
	letter-spacing: normal;
	color: var(--f4-ink-70);
}

.f4l-order-hero__actions {
	margin-top: 2.25rem;
	gap: 0.75rem;
}

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

.f4l-receipt {
	display: flex;
	flex-direction: column;
	justify-content: center;
	padding: 3.5rem 2.75rem;
	background: var(--wp--preset--color--mint-deep);
	color: var(--wp--preset--color--white);
}

.f4l-confirm__summary,
.f4l-receipt .wc-block-order-confirmation-summary {
	margin: 0;
	padding: 0;
	border: 0;
	background: none;
	max-width: none;
}

.f4l-receipt .wc-block-order-confirmation-summary-list {
	display: flex;
	flex-direction: column;
	list-style: none;
	margin: 0;
	padding: 0;
}

.f4l-receipt .wc-block-order-confirmation-summary-list-item {
	display: flex;
	align-items: baseline;
	justify-content: space-between;
	gap: 1.25rem;
	padding: 0.875rem 0;
	border-bottom: 1px solid var(--f4-on-dark-16);
	font-size: 0.9375rem;
}

.f4l-receipt .wc-block-order-confirmation-summary-list-item__key {
	color: var(--f4-on-dark-60);
}

.f4l-receipt .wc-block-order-confirmation-summary-list-item__value {
	text-align: right;
}

/*
   Two rows are re-cast by position. The block always emits Order #, Date and
   Total as its first three items, in that order — those three are unconditional
   — while Email and Payment follow only when the order has them. So counting
   from the top is safe for exactly these two and would not be for the others.

   Row 1 becomes the panel's title, and row 3 (Total) is sent to the bottom with
   `order` and given the display face at 34px: on a receipt the number you paid
   is the one thing that should be findable without reading, and the reference
   ends on it rather than burying it third.
*/
.f4l-receipt .wc-block-order-confirmation-summary-list-item:first-child {
	justify-content: flex-start;
	gap: 0.35rem;
	padding-top: 0;
	padding-bottom: 1.5rem;
	border-bottom: 0;
	font-family: var(--wp--preset--font-family--display);
	font-size: 1.25rem;
	font-weight: 700;
	letter-spacing: -0.02em;
}

.f4l-receipt .wc-block-order-confirmation-summary-list-item:first-child .wc-block-order-confirmation-summary-list-item__key {
	color: inherit;
}

.f4l-receipt .wc-block-order-confirmation-summary-list-item:nth-child(3) {
	order: 1;
	border-bottom: 0;
	padding-top: 1.5rem;
}

.f4l-receipt .wc-block-order-confirmation-summary-list-item:nth-child(3) .wc-block-order-confirmation-summary-list-item__value {
	font-family: var(--wp--preset--font-family--display);
	font-size: 2.125rem;
	font-weight: 700;
	line-height: 1;
	letter-spacing: -0.03em;
	color: var(--wp--preset--color--mint-bright);
}

/* --- What happens next ----------------------------------------------------- */

.f4l-next__title {
	margin: 0 0 2.25rem;
}

.f4l-order__heading {
	font-family: var(--wp--preset--font-family--display);
	font-size: 1.5rem;
	font-weight: 700;
	letter-spacing: -0.02em;
	margin: 0 0 1.25rem;
}

/* Three cards across, not three stacked bars. Same shape as the steps on the
   landing and the product page, because it is the same idea in all three
   places — a short ordered sequence the reader scans rather than reads. */
.f4l-next {
	list-style: none;
	counter-reset: step;
	margin: 0;
	padding: 0;
	display: grid;
	grid-template-columns: repeat(3, 1fr);
	gap: 1.125rem;
}

.f4l-next li {
	counter-increment: step;
	padding: 1.5rem 1.5rem 1.75rem;
	border: 1px solid var(--f4-line-12);
	border-radius: var(--f4-r-xl);
	background: var(--wp--preset--color--white);
}

/* The first badge is filled mint and the other two are dark. Nothing here is
   clickable and no step is "done", so this is not a progress bar — it marks
   where the buyer is standing right now, which is step one: we are waiting on
   their intake form and the other two cannot start until it arrives. */
.f4l-next li::before {
	content: counter(step, decimal-leading-zero);
	display: flex;
	align-items: center;
	justify-content: center;
	width: 44px;
	height: 44px;
	margin-bottom: 1.25rem;
	border-radius: var(--f4-r-sm);
	background: var(--wp--preset--color--mint-deep);
	color: var(--wp--preset--color--mint-bright);
	font-family: var(--wp--preset--font-family--body);
	font-size: 0.8125rem;
	font-weight: 700;
	letter-spacing: 0.06em;
}

.f4l-next li:first-child::before {
	background: var(--wp--preset--color--mint);
	color: var(--wp--preset--color--forest);
}

.f4l-next strong {
	display: block;
	font-family: var(--wp--preset--font-family--display);
	font-size: 1.1875rem;
	font-weight: 600;
	letter-spacing: -0.02em;
	line-height: 1.25;
}

.f4l-next span {
	display: block;
	margin-top: 0.5rem;
	font-size: 0.875rem;
	color: var(--f4-ink-65);
	line-height: 1.55;
}

/* --- Order detail ---------------------------------------------------------- */

.f4l-order table {
	width: 100%;
	border-collapse: collapse;
	border: 1px solid rgb(15 61 48 / 8%);
	border-radius: 14px;
	overflow: hidden;
	background: var(--wp--preset--color--white);
}

.f4l-order th,
.f4l-order td {
	padding: 0.85rem 1.1rem;
	border-bottom: 1px solid rgb(15 61 48 / 6%);
	text-align: left;
}

.f4l-order tfoot td,
.f4l-order tfoot th {
	font-weight: 600;
	border-bottom: 0;
}

.f4l-order address,
.f4l-order .wc-block-order-confirmation-billing-address {
	display: block;
	padding: 1.1rem;
	border: 1px solid rgb(15 61 48 / 8%);
	border-radius: 14px;
	background: var(--wp--preset--color--white);
	font-style: normal;
	line-height: 1.7;
}

/* --- Shop header ---------------------------------------------------------- */

.f4l-shop-head {
	display: flex;
	align-items: baseline;
	justify-content: space-between;
	gap: 1rem;
	flex-wrap: wrap;
	margin-bottom: 1.5rem;
	padding-bottom: 1rem;
	border-bottom: 1px solid rgb(15 61 48 / 8%);
}

.f4l-shop-head__count {
	margin: 0;
	font-size: 0.875rem;
	opacity: 0.65;
	font-variant-numeric: tabular-nums;
}

@media (max-width: 781px) {
	.f4l-shop__filters {
		position: static;
	}
}

/* --- Typography ---------------------------------------------------------- */

/* Serif numerals default to old-style figures, which makes "350+" and "48h"
   read as decorative rather than as data. Force lining figures. */
.wp-block-heading {
	font-variant-numeric: lining-nums;
	font-feature-settings: "lnum" 1;
}

h1.wp-block-heading {
	letter-spacing: -0.015em;
}

/* --- Scroll reveal ------------------------------------------------------- */

/* The class is added by JS only when IntersectionObserver is available, so
   without JS the content is simply visible — never hidden with no way back. */
.f4l-reveal {
	opacity: 0;
	transform: translateY(18px);
	transition: opacity 0.6s ease, transform 0.6s ease;
	will-change: opacity, transform;
}

.f4l-reveal.is-visible {
	opacity: 1;
	transform: none;
}

/* --- Reduced motion ------------------------------------------------------ */

/* Vestibular disorders make parallax and slide-ins genuinely unpleasant, not
   merely unfashionable. Honour the OS setting. */
@media (prefers-reduced-motion: reduce) {
	*,
	*::before,
	*::after {
		animation-duration: 0.01ms !important;
		animation-iteration-count: 1 !important;
		transition-duration: 0.01ms !important;
		scroll-behavior: auto !important;
	}

	.f4l-reveal,
	.f4l-reveal.is-visible {
		opacity: 1;
		transform: none;
	}

	/* The video is NOT hidden here any more, and the reason changed with the
	   redesign.

	   It used to be a background behind the copy, so removing it cost nothing:
	   the poster was also the section's CSS background and the hero still
	   painted. In the split hero the video is a framed object in its own
	   column — hiding it would leave a hole in the green panel.

	   Nothing is lost by keeping it: assets/chrome.js returns early under this
	   setting and never attaches the <source> children, so the element renders
	   its poster and never plays. The float animation is stopped separately,
	   further down this file. */

	.wp-block-column.has-white-background-color:hover,
	.wp-element-button:hover,
	.wp-block-button__link:hover,
	.wp-block-woocommerce-product-template li:hover,
	.f4l-card:hover {
		transform: none;
	}

	/* The underline and the card hairline still appear — they just stop
	   sliding. Removing the affordance entirely would cost information; only
	   the motion is the problem. */
	.wp-block-navigation .wp-block-navigation-item__content::after,
	.f4l-card::after {
		transition: none;
	}
}

/* ==========================================================================
   NARROW SCREENS
   ==========================================================================
   Everything above was written on a desktop and reviewed on one. These rules
   are the audit of what that misses. They live together rather than beside
   each component on purpose: it is the only way to read the small-screen
   layout as one design instead of a dozen afterthoughts.

   ON THE `!important`s BELOW: the section paddings come from inline `style`
   attributes that the block editor writes into the markup, and an inline style
   can only be beaten by `!important`. The alternative is stripping every
   padding out of the templates and rebuilding it here, which trades one
   problem for a worse one — the Site Editor would stop showing what the page
   actually does.
   ========================================================================== */

@media (max-width: 781px) {

	/* --- Hero ------------------------------------------------------------
	   9rem of padding top and bottom is 144px each on a phone, and the
	   headline's clamp bottoms out at 2.5rem — a 40px serif line inside a
	   375px screen breaks "Your longest, healthiest chapter starts here" into
	   a very tall stack. Together they pushed the buttons below the fold on
	   the first screen a visitor sees. */
	.f4l-hero {
		padding-top: 5rem !important;
		padding-bottom: 5rem !important;
	}

	.f4l-hero h1 {
		font-size: clamp(2rem, 8.5vw, 2.75rem) !important;
	}

	/* Side by side, two buttons overflow 375px. Stacked and full width they
	   also become easier to hit. */
	.f4l-hero .wp-block-buttons,
	.f4l-cta .wp-block-buttons,
	.f4l-order .wp-block-buttons {
		flex-direction: column;
		align-items: stretch;
		width: 100%;
	}

	.f4l-hero .wp-block-button,
	.f4l-cta .wp-block-button,
	.f4l-order .wp-block-button {
		width: 100%;
	}

	.f4l-hero .wp-block-button__link,
	.f4l-cta .wp-block-button__link,
	.f4l-order .wp-block-button__link {
		display: block;
		text-align: center;
	}

	/* --- Sections --------------------------------------------------------
	   6rem top and bottom on every section adds up to a lot of scrolling
	   before anything happens. */
	.f4l-section {
		padding-top: 4rem !important;
		padding-bottom: 4rem !important;
	}

	/* Two per row rather than one: at 375px each still clears 150px, and the
	   three figures stay comparable at a glance, which is the whole point of
	   putting them in a row. */
	.f4l-metrics {
		grid-template-columns: repeat(2, 1fr);
	}

	.f4l-metrics > .f4l-metric:last-child:nth-child(odd) {
		grid-column: 1 / -1;
	}

	/* --- Header ----------------------------------------------------------
	   Site title, burger and cart, tighter than the desktop gap. */
	.f4l-header .wp-block-group {
		gap: 0.75rem;
	}

	/* --- Shop ------------------------------------------------------------
	   WordPress stacks columns below 782px, so the filter sidebar lands on
	   top of the grid. At full height it buried the products under a screen
	   and a half of controls — see the `<details>` treatment in
	   inc/shop-filters.php, which collapses each group here. */
	.f4l-shop__filters {
		flex-basis: auto !important;
		width: 100%;
	}

	.f4l-hero-shop__title {
		font-size: clamp(1.75rem, 7vw, 2.25rem);
	}

	/* --- Product grid ----------------------------------------------------
	   Two across. One per row turns ten products into a very long scroll,
	   and these cards read fine at half width. */
	.f4l-shop .wp-block-woocommerce-product-template,
	.f4l-store .wp-block-woocommerce-product-template {
		grid-template-columns: repeat(2, 1fr) !important;
	}

	.f4l-product {
		padding: 0.75rem 0.75rem 1.25rem;
	}

	.f4l-product__title {
		font-size: 0.9375rem;
	}

	.f4l-product__price {
		font-size: 1.125rem;
	}

	/* --- Order confirmation ---------------------------------------------- */
	.f4l-confirm,
	.f4l-order {
		padding-left: 1.25rem !important;
		padding-right: 1.25rem !important;
	}
}

/* Below 400px the two-up product grid stops being readable: the title wraps
   to three lines and the price collides with the button. */
@media (max-width: 400px) {
	.f4l-shop .wp-block-woocommerce-product-template,
	.f4l-store .wp-block-woocommerce-product-template {
		grid-template-columns: 1fr !important;
	}

	.f4l-metrics {
		grid-template-columns: 1fr;
	}
}

/* --- Collapsible filter groups -------------------------------------------
   Category, Dose and Price are `<details open>` in the markup, so with CSS or
   JS unavailable they render exactly as they always did: expanded. On narrow
   screens assets/chrome.js closes them, because WordPress stacks the sidebar
   above the grid and at full height the controls buried the products under a
   screen and a half of scrolling.

   `open` in the markup rather than closed-by-default because the desktop
   layout is the one with room, and progressive enhancement should degrade to
   the more useful state, not the more compact one.
   -------------------------------------------------------------------------- */

.f4l-filter--group > summary {
	cursor: pointer;
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 0.5rem;
	list-style: none;
	user-select: none;
}

/* Safari draws its own triangle through ::-webkit-details-marker, which
   `list-style: none` does not remove. */
.f4l-filter--group > summary::-webkit-details-marker {
	display: none;
}

.f4l-filter--group > summary::after {
	content: "";
	width: 7px;
	height: 7px;
	border-right: 1.5px solid currentColor;
	border-bottom: 1.5px solid currentColor;
	transform: rotate(45deg) translate(-2px, -2px);
	opacity: 0.5;
	transition: transform 0.2s ease;
}

.f4l-filter--group[open] > summary::after {
	transform: rotate(-135deg) translate(-2px, -2px);
}

.f4l-filter--group > summary:focus-visible {
	outline: 2px solid var(--wp--preset--color--mint);
	outline-offset: 3px;
	border-radius: 4px;
}

/* The chevron is the only affordance that the group can close, and it is
   decoration; leave it alone when motion is turned down. */
@media (prefers-reduced-motion: reduce) {
	.f4l-filter--group > summary::after {
		transition: none;
	}
}

/* --- Prescription notice --------------------------------------------------
   Deliberately placed above the buy button. This is the one fact that changes
   what buying here means, and it is the last moment it can still be useful.
   -------------------------------------------------------------------------- */

.f4l-rx {
	display: flex;
	align-items: flex-start;
	gap: 0.85rem;
	margin: 0 0 1.75rem;
	padding: 1.1rem 1.25rem;
	background: var(--wp--preset--color--mint-light);
	border-radius: 14px;
}

.f4l-rx__icon {
	flex: 0 0 auto;
	width: 22px;
	height: 22px;
	margin-top: 1px;
	color: var(--wp--preset--color--mint-deep);
}

.f4l-rx strong {
	display: block;
	margin-bottom: 0.15rem;
	font-size: 0.9375rem;
	font-weight: 700;
	/* 5.44:1 on mint-light. */
	color: #0F3D30;
}

.f4l-rx span {
	display: block;
	font-size: 0.875rem;
	line-height: 1.55;
	/* Solid ink at 85%: 6.9:1 on mint-light. Fading it further would drop the
	   one notice on the page that must not be skimmed past. */
	color: var(--wp--preset--color--contrast);
	opacity: 0.85;
}

/* --- Add to cart ----------------------------------------------------------
   Written for woocommerce/add-to-cart-with-options, which replaced the older
   add-to-cart-form block in templates/single-product.html. That swap changed
   the markup completely: no <form class="cart">, no <table class="variations">,
   no <select>. Variations are chips, the quantity is a stepper, and the whole
   thing submits through the Store API instead of navigating. The rules for the
   old markup were deleted rather than left in place — dead selectors that look
   live are worse than no rules at all.
   -------------------------------------------------------------------------- */

.f4l-single__cart {
	margin-bottom: 1.5rem;
}

.f4l-single__cart .wc-block-components-quantity-selector__input {
	font-weight: 600;
}

/* The attribute name — "Dose" — reads as a field label, matching the labels
   the checkout uses. */
.f4l-single__cart .wp-block-woocommerce-add-to-cart-with-options-variation-selector-attribute-name {
	font-family: var(--wp--preset--font-family--body);
	font-size: 0.8125rem;
	font-weight: 700;
	letter-spacing: 0.08em;
	text-transform: uppercase;
	color: var(--wp--preset--color--contrast);
}

/* One chip per dose. 44px minimum because these are the only tap targets
   between a visitor and the purchase, and they sit close together. */
.f4l-single__cart .wc-block-product-filter-chips__item {
	min-height: 44px;
	padding: 0.55rem 1.15rem;
	border: 1px solid rgb(15 61 48 / 18%);
	border-radius: 999px;
	background: var(--wp--preset--color--white);
	font-family: var(--wp--preset--font-family--body);
	font-size: 0.9375rem;
	color: var(--wp--preset--color--contrast);
}

.f4l-single__cart .wc-block-product-filter-chips__item:hover {
	border-color: var(--wp--preset--color--mint);
}

/* The chosen dose. WooCommerce carries the state in aria-checked rather than
   a class, which is the accessible source of truth anyway, so style from it
   and the two can never disagree. */
.f4l-single__cart .wc-block-product-filter-chips__item[aria-checked="true"] {
	background: var(--wp--preset--color--mint);
	border-color: var(--wp--preset--color--mint);
	font-weight: 600;
}

/* The stepper keeps its natural width and the button takes the rest of the row.
   WooCommerce wraps the button in its own `.wp-block-button` div, so the button
   going full-width was not enough on its own — the wrapper it lives in was
   still sized to its content, which is why the control read as a small pill
   floating beside the stepper instead of the bar the reference draws. */
.f4l-single__cart .wc-block-components-product-button {
	flex: 1;
}

/* Three classes deep, not two: WooCommerce ships
   `.wc-block-components-product-button .wp-block-button__link` for its own
   sizing, which ties with a two-class selector here and then wins on order.
   Matching its depth is enough — no `!important` needed.

   `text-align` is set because the block adds `has-text-align-left` to the
   button element itself, so a label centred by default lands hard left the
   moment the button becomes a full-width bar. */
.f4l-single__cart .wc-block-components-product-button .wp-element-button,
.f4l-single__cart .wc-block-components-product-button .single_add_to_cart_button {
	width: 100%;
	padding: 1.125rem 1.5rem;
	border-radius: var(--f4-r-md);
	font-weight: 700;
	text-align: center;
	background: var(--wp--preset--color--mint);
	color: var(--wp--preset--color--forest);
	border: 0;
}

.f4l-single__cart .wc-block-components-product-button .wp-element-button:hover,
.f4l-single__cart .wc-block-components-product-button .single_add_to_cart_button:hover {
	background: var(--wp--preset--color--mint-deep);
	color: var(--wp--preset--color--white);
}

/*
   The "choose a dose first" state of a variable product.

   The button is live-looking but does nothing until a dose is picked: tapping
   it produces no notice and no change to the cart, which reads as a broken
   store rather than as a step the buyer skipped. WooCommerce marks the form
   .is-invalid while a required attribute is unanswered, so that is the hook —
   it is on the form from the first paint and clears itself the moment a chip
   is chosen, with no JavaScript of ours in between.

   The extra class on the button is load-bearing: the block stylesheet fades
   the disabled button to 50%, and at equal specificity the winner would be
   whichever stylesheet was enqueued last.
*/
.f4l-single__cart.is-invalid button.single_add_to_cart_button.wc-block-components-product-button__button,
.f4l-single__cart.is-invalid button.single_add_to_cart_button.wc-block-components-product-button__button:hover {
	background: rgb(15 61 48 / 7%);
	color: rgb(15 61 48 / 75%);
	cursor: not-allowed;

	/* The 50% fade drags the label to 3.8:1. The colours above carry the state
	   on their own at 5.8:1, so the fade goes. */
	opacity: 1;
}

/* Says out loud what the greyed button implies. The form is a flow layout, so
   the pseudo-element simply lands underneath as its last child. */
.f4l-single__cart.is-invalid::after {
	content: "Choose a dose above to continue.";
	display: block;
	margin-top: 0.75rem;
	font-size: 0.875rem;
	line-height: 1.5;
	color: rgb(15 61 48 / 70%);
}

.f4l-single__meta {
	padding-top: 1.25rem;
	border-top: 1px solid rgb(15 61 48 / 10%);
	font-size: 0.875rem;
	opacity: 0.7;
}

/* --- Description ---------------------------------------------------------- */

.f4l-single__details h2,
.f4l-single__details h3 {
	font-size: 1.375rem;
	margin-bottom: 0.75rem;
}

.f4l-single__details p {
	line-height: 1.7;
	opacity: 0.85;
}

/* WooCommerce prints its tab list even with a single tab and the title
   hidden; an empty nav above the copy reads as a rendering fault. */
.f4l-single__details .wc-tabs,
.f4l-single__details .woocommerce-tabs > ul {
	display: none;
}

@media (max-width: 781px) {
	.f4l-single__top {
		gap: 2rem;
	}

	.f4l-single__media {
		flex-basis: auto !important;
	}

	.f4l-single__price {
		font-size: 1.625rem;
	}
}

/* --- Cart and checkout ----------------------------------------------------
   These two pages are the WooCommerce Cart and Checkout blocks, and their
   inner block tree is not rebuilt here: it is dozens of nested blocks that
   WooCommerce revises between releases, and a copy would break on the first
   update while gaining nothing. The templates only wrap them in the site's own
   chrome; everything below is styling the blocks as they ship.
   -------------------------------------------------------------------------- */

.f4l-cartpage .f4l-section__title,
.f4l-checkoutpage .wc-block-components-title {
	font-size: clamp(1.9rem, 3.4vw, 2.6rem);
	line-height: 1.12;
	letter-spacing: -0.01em;
}

/* Panels: the cart's line items and the order summary, and every checkout
   step, get the same card treatment as the rest of the site. */
.wc-block-cart__sidebar .wc-block-components-sidebar,
.wc-block-checkout__sidebar .wc-block-components-sidebar {
	padding: 1.5rem;
	background: var(--wp--preset--color--white);
	border: 1px solid rgb(15 61 48 / 8%);
	border-radius: 18px;
}

.wc-block-cart-items {
	border-radius: 14px;
	overflow: hidden;
}

.wc-block-cart-items__header {
	font-family: var(--wp--preset--font-family--body);
	font-size: 0.75rem;
	font-weight: 700;
	letter-spacing: 0.12em;
	text-transform: uppercase;
	color: var(--wp--preset--color--contrast);
	opacity: 0.6;
}

.wc-block-components-product-name {
	font-family: var(--wp--preset--font-family--display);
	font-size: 1.125rem;
	color: var(--wp--preset--color--contrast);
	text-decoration: none;
}

.wc-block-components-product-name:hover {
	color: var(--wp--preset--color--mint-deep);
}

.wc-block-cart-item__image img {
	border-radius: 10px;
}

/* Totals in the display face, matching the product cards and the dashboard. */
.wc-block-components-totals-footer-item .wc-block-components-totals-item__value,
.wc-block-components-order-summary__content .wc-block-components-product-price {
	font-family: var(--wp--preset--font-family--display);
	font-variant-numeric: lining-nums tabular-nums;
}

.wc-block-components-totals-footer-item .wc-block-components-totals-item__value {
	font-size: 1.75rem;
	font-weight: 500;
	color: var(--wp--preset--color--mint-deep);
}

/* Primary actions: same pill as everywhere else. */
.wc-block-cart__submit-button,
.wc-block-components-checkout-place-order-button {
	border-radius: 999px !important;
	padding-block: 0.95rem !important;
	font-weight: 600;
	background: var(--wp--preset--color--mint) !important;
	color: var(--wp--preset--color--contrast) !important;
	border: 0 !important;
}

.wc-block-cart__submit-button:hover,
.wc-block-components-checkout-place-order-button:hover {
	background: var(--wp--preset--color--mint-dark) !important;
}

/* Inputs, so the checkout form does not read as a different product. */
.wc-block-components-text-input input,
.wc-block-components-textarea,
.wc-block-components-combobox-control input,
.wc-block-components-select__container {
	border-radius: 10px !important;
}

.wc-block-components-text-input input:focus,
.wc-block-components-textarea:focus {
	outline: 2px solid var(--wp--preset--color--mint);
	outline-offset: 1px;
}

.wc-block-components-checkout-step__title {
	font-family: var(--wp--preset--font-family--display);
	font-size: 1.25rem;
}

/* --- Prescription notice on the checkout ---------------------------------
   Same fact as the product page, at the last moment it can still change a
   decision: nothing ships until a provider approves it.
   -------------------------------------------------------------------------- */

.f4l-checkoutpage .wc-block-checkout__actions::before {
	content: "A licensed provider reviews your intake before anything ships. If it is not approved, you are not charged.";
	display: block;
	margin-bottom: 1rem;
	padding: 0.9rem 1.1rem;
	background: var(--wp--preset--color--mint-light);
	border-radius: 12px;
	font-size: 0.875rem;
	line-height: 1.55;
	color: var(--wp--preset--color--contrast);
}

/* --- Checkout header ------------------------------------------------------ */

.f4l-header--checkout .f4l-secure {
	display: flex;
	align-items: center;
	gap: 0.45rem;
	margin: 0;
	font-size: 0.8125rem;
	font-weight: 600;
	letter-spacing: 0.02em;
	color: var(--wp--preset--color--mint-deep);
}

.f4l-header--checkout .f4l-secure svg {
	width: 17px;
	height: 17px;
}

/* --- Empty cart ----------------------------------------------------------- */

.wp-block-woocommerce-empty-cart-block {
	text-align: center;
	padding-block: 2rem 3rem;
}

.wp-block-woocommerce-empty-cart-block h2 {
	font-size: clamp(1.6rem, 3vw, 2.1rem);
}

@media (max-width: 781px) {
	.wc-block-cart__sidebar .wc-block-components-sidebar,
	.wc-block-checkout__sidebar .wc-block-components-sidebar {
		padding: 1.15rem;
	}
}

/* --- 404 ------------------------------------------------------------------
   A store's 404 is almost always a mistyped or stale product URL, and the
   visitor already knows what they wanted. The search field is the point of the
   page; the buttons are the fallback.
   -------------------------------------------------------------------------- */

.f4l-404 .f4l-lede {
	margin-bottom: 2rem;
}

.f4l-404__search {
	max-width: 420px;
	margin: 0 auto;
}

/* --- Content pages --------------------------------------------------------
   Policies and anything else editorial. Narrow measure and generous leading:
   these are read, not scanned.
   -------------------------------------------------------------------------- */

.f4l-page__body p {
	line-height: 1.75;
	margin-bottom: 1.25rem;
}

.f4l-page__body h2 {
	margin-top: 2.5rem;
	margin-bottom: 0.75rem;
	font-size: 1.5rem;
}

.f4l-page__body h3 {
	margin-top: 1.75rem;
	margin-bottom: 0.5rem;
	font-size: 1.1875rem;
}

.f4l-page__body ul,
.f4l-page__body ol {
	line-height: 1.75;
	margin-bottom: 1.25rem;
	padding-left: 1.25rem;
}

.f4l-page__body li {
	margin-bottom: 0.4rem;
}

/* The placeholder policies open with a bolded warning that they are not legal
   text. Give that first paragraph the weight of a notice so nobody skims past
   it and quotes the page as policy. */
.f4l-page__body > p:first-child:has(strong:first-child) {
	padding: 1.1rem 1.25rem;
	background: var(--wp--preset--color--mint-light);
	border-radius: 12px;
	font-size: 0.9375rem;
	line-height: 1.6;
}


/* ==========================================================================
   REDESIGN 2026 — DESIGN SYSTEM
   ==========================================================================

   Implements the reference sheet supplied by the client (fit4life-redesign.css
   plus the landing / shop / product / order-received reference pages).

   Two things were deliberately NOT copied verbatim from that sheet:

   1. The class prefix. The reference uses `.f4-`; this theme's templates
      already emit `.f4l-`. Renaming every class in every template to gain a
      dropped letter would be churn with no output, so the reference is treated
      as the design spec and the existing names carry it.

   2. The palette as literals. The reference hardcodes hex values; here they
      are mapped onto the theme.json presets, so the Site Editor, the block
      colour pickers and this stylesheet cannot drift apart:

          reference          preset                 value
          --f4-green-950     forest                 #04211A
          --f4-green-900     contrast / mint-deep   #0F3D30
          --f4-mint-500      mint                   #2FA97F
          --f4-mint-300      mint-bright            #7FE3B8
          --f4-mint-50       mint-light             #F1F7F3
          --f4-white         base / white           #FFFFFF

   The ink is now a green (#0F3D30), not the old near-black. Every hardcoded
   rgb() below is that green at an alpha, matching the reference's --f4-ink-*
   ladder.
   -------------------------------------------------------------------------- */

:root {
	--f4-gutter: 44px;
	--f4-gutter-shop: 40px;
	--f4-section-y: 80px;

	--f4-ink-70: rgb(15 61 48 / 70%);
	--f4-ink-65: rgb(15 61 48 / 65%);
	--f4-ink-55: rgb(15 61 48 / 55%);
	--f4-ink-45: rgb(15 61 48 / 45%);
	--f4-line-20: rgb(15 61 48 / 20%);
	--f4-line-14: rgb(15 61 48 / 14%);
	--f4-line-12: rgb(15 61 48 / 12%);
	--f4-line-10: rgb(15 61 48 / 10%);
	--f4-line-08: rgb(15 61 48 / 8%);
	--f4-on-dark-78: rgb(255 255 255 / 78%);
	--f4-on-dark-70: rgb(255 255 255 / 70%);
	--f4-on-dark-60: rgb(255 255 255 / 60%);
	--f4-on-dark-30: rgb(255 255 255 / 30%);
	--f4-on-dark-16: rgb(255 255 255 / 16%);
	--f4-on-dark-07: rgb(255 255 255 / 7%);

	--f4-r-sm: 10px;
	--f4-r-md: 12px;
	--f4-r-lg: 16px;
	--f4-r-xl: 18px;
	--f4-r-2xl: 22px;
	--f4-r-3xl: 26px;

	--f4-shadow-float: 0 12px 30px rgb(0 0 0 / 20%);
	--f4-shadow-card: 0 16px 34px rgb(15 61 48 / 14%);
	--f4-ease: cubic-bezier(0.2, 0.7, 0.2, 1);
}

/* --- Typography -----------------------------------------------------------
   The reference sets sizes in px against a fixed 1280px artboard. They are
   clamped here instead: the same figure at the top end, but the page has to
   survive every width between a phone and a wide monitor, which an artboard
   does not.
   -------------------------------------------------------------------------- */

.f4l-hero__title,
.f4l-hero-shop__title,
.f4l-single__title {
	font-family: var(--wp--preset--font-family--display);
	font-weight: 700;
	line-height: 0.95;
	letter-spacing: -0.04em;
	color: var(--wp--preset--color--contrast);
	margin: 0;
	text-wrap: pretty;
}

/* Each vw factor is set so the clamp reaches its own maximum at exactly 1280px
   — the artboard width AND the theme's wideSize. Below that the type scales
   with the viewport; at and above it the container has stopped growing, so the
   type stops with it. The factors were previously ~8% low, which meant the
   maxima were only reached near 1390px and the 1280px design width rendered
   every headline a size under spec (hero 79px against 86px, shop 69 against
   74, product 54 against 56). */
.f4l-hero__title { font-size: clamp(2.75rem, 6.72vw, 5.375rem); }
.f4l-hero-shop__title { font-size: clamp(2.5rem, 5.78vw, 4.625rem); line-height: 0.96; }
.f4l-single__title { font-size: clamp(2.25rem, 4.38vw, 3.5rem); line-height: 1; }

/* The reference keeps a smaller H2 for headings that open a subordinate block
   rather than a section of the page — "More treatments" under a product,
   "What happens next" under an order. Same face and tracking, one step down,
   so the block reads as attached to what is above it. */
.f4l-section__title--sm { font-size: clamp(1.875rem, 3.44vw, 2.75rem); }

.f4l-section__title,
.f4l-cta__title,
.f4l-panel__title,
.f4l-why__title {
	font-family: var(--wp--preset--font-family--display);
	font-weight: 700;
	font-size: clamp(2.125rem, 4.53vw, 3.625rem);
	line-height: 1;
	letter-spacing: -0.035em;
	margin: 0;
	max-width: none;
	text-wrap: pretty;
}

/* The accent inside a headline. The reference draws two of them and they are
   not the same mark:

     .f4-em     italic, weight 400, mint — the hero's "starts here"
     .f4-accent upright, inherits weight, mint — "around you" in a section H2

   The italic one is the hero's alone. Bricolage Grotesque ships no true italic
   at any weight, so this is the browser's synthetic oblique — which is what the
   prototype rendered too, and what the approved screens show. Dropping to 400
   against the headline's 700 is half of the effect: the slant reads as a change
   of voice rather than a wobble, which is exactly what it does not do when the
   weight stays put. */
.f4l-em {
	font-style: italic;
	font-weight: 400;
	color: var(--wp--preset--color--mint);
}

.f4l-accent {
	font-style: normal;
	color: var(--wp--preset--color--mint);
}

.f4l-lede {
	font-size: 1.09375rem;
	line-height: 1.6;
	color: var(--f4-ink-70);
	margin: 0;
	max-width: 470px;
	opacity: 1;
}

/* --- Header: dark rail ----------------------------------------------------
   The largest single identity change. The bar was white with dark type and
   read as a default WordPress header; it is now the brand's own green, which
   is what makes every page recognisable before a word is read.
   -------------------------------------------------------------------------- */

.f4l-header {
	padding-block: 0.875rem !important;
	background-color: var(--wp--preset--color--mint-deep) !important;
	color: var(--wp--preset--color--white);
	border-bottom: 0 !important;
}

.f4l-header .wp-block-site-title a {
	font-family: var(--wp--preset--font-family--display);
	font-weight: 800;
	font-size: 1.25rem;
	letter-spacing: -0.03em;
	color: var(--wp--preset--color--white);
}

/* The pulse mark recolours for the dark rail: mint-bright measures 9.2:1 on
   the green, where the mid mint would sit near 2.6:1 and disappear. */
.f4l-header .wp-block-site-title a::before {
	background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32'%3E%3Ccircle cx='16' cy='16' r='15' fill='%237FE3B8'/%3E%3Cpath d='M7.5 17h3.6l2.2-5.6L16.6 22l2.3-5h5.6' fill='none' stroke='%230F3D30' stroke-width='2.1' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
}

.f4l-header .wp-block-navigation {
	font-size: 0.84375rem;
	font-weight: 500;
}

.f4l-header .wp-block-navigation a {
	color: var(--wp--preset--color--white);
	white-space: nowrap;
}

.f4l-header .wp-block-navigation a:hover {
	color: var(--wp--preset--color--mint-bright);
}

/* The current page becomes a solid mint-bright pill. This replaces the sliding
   underline defined further up this file: on a dark rail that underline read
   as an artefact of the bar rather than as state. */
.f4l-header .wp-block-navigation .current-menu-item > .wp-block-navigation-item__content {
	background: var(--wp--preset--color--mint-bright);
	color: var(--wp--preset--color--mint-deep);
	font-weight: 700;
	padding: 0.375rem 0.875rem;
	border-radius: 8px;
}

.f4l-header .wp-block-navigation .wp-block-navigation-item__content::after {
	display: none;
}

/* Mini-cart, restyled for the dark rail: an outlined pill rather than the
   tinted circle that was tuned for a white bar. */
.f4l-header .wc-block-mini-cart__button {
	border: 1px solid var(--f4-on-dark-30);
	border-radius: 8px;
	padding: 0.4375rem 0.875rem;
	background-color: transparent;
	color: var(--wp--preset--color--white);
	transition: border-color 0.25s ease, color 0.25s ease;
}

.f4l-header .wc-block-mini-cart__button:hover,
.f4l-header .wc-block-mini-cart__button:focus-visible {
	background-color: transparent;
	border-color: var(--wp--preset--color--mint-bright);
	color: var(--wp--preset--color--mint-bright);
}

.f4l-header .wc-block-mini-cart__badge {
	background-color: var(--wp--preset--color--mint-bright) !important;
	color: var(--wp--preset--color--mint-deep) !important;
}

.f4l-header.is-stuck {
	box-shadow: 0 6px 24px rgb(4 33 26 / 28%);
}

/* --- Buttons --------------------------------------------------------------
   Radius 12px, not a pill: the pill belonged to the old visual language and it
   fights a grotesque display face.
   -------------------------------------------------------------------------- */

.wp-element-button,
.wp-block-button__link {
	border-radius: var(--f4-r-md);
	padding: 1.0625rem 1.75rem;
	font-family: var(--wp--preset--font-family--body);
	font-size: 0.9375rem;
	font-weight: 700;
	line-height: 1.2;
	transition: background 0.25s ease, color 0.25s ease, border-color 0.25s ease;
}

.f4l-hero__actions .wp-block-button:not(.is-style-outline) .wp-block-button__link {
	background: var(--wp--preset--color--mint-deep);
	color: var(--wp--preset--color--white);
	box-shadow: none;
}

.f4l-hero__actions .wp-block-button:not(.is-style-outline) .wp-block-button__link:hover {
	background: var(--wp--preset--color--mint);
	color: var(--wp--preset--color--forest);
	box-shadow: none;
}

.f4l-hero__actions .wp-block-button.is-style-outline .wp-block-button__link {
	background: var(--wp--preset--color--white);
	border: 1px solid var(--f4-line-20);
	color: var(--wp--preset--color--mint-deep);
	font-weight: 600;
	backdrop-filter: none;
}

.f4l-hero__actions .wp-block-button.is-style-outline .wp-block-button__link:hover {
	background: var(--wp--preset--color--white);
	border-color: var(--wp--preset--color--mint-deep);
}

/* --- Hero: split ----------------------------------------------------------
   Copy on a mint-50 field, media on the brand green. The two halves meet on a
   hard vertical edge with no gutter, which is what gives the fold its
   architecture — a centred headline over a full-bleed video is the layout
   every template ships with.
   -------------------------------------------------------------------------- */

.f4l-hero {
	display: grid;
	grid-template-columns: 1.05fr 0.95fr;
	min-height: 620px;
	background-image: none;
	padding: 0 !important;
}

.f4l-hero::before {
	display: none;
}

.f4l-hero__copy {
	background: var(--wp--preset--color--mint-light);
	padding: 5.25rem var(--f4-gutter) 4.5rem;
	display: flex;
	flex-direction: column;
	justify-content: center;
}

.f4l-hero__copy > * {
	max-width: none !important;
	margin-inline: 0 !important;
}

.f4l-hero__actions {
	display: flex;
	gap: 0.75rem;
	margin-top: 2.25rem;
	justify-content: flex-start;
}

.f4l-hero__media {
	position: relative;
	background: var(--wp--preset--color--mint-deep);
	display: flex;
	align-items: center;
	justify-content: center;
	overflow: hidden;
	padding: 3rem 0;
}

.f4l-hero__media::before {
	content: "";
	position: absolute;
	inset: 0;
	background: radial-gradient(70% 70% at 50% 30%, rgb(127 227 184 / 22%), transparent 70%);
}

/* The video keeps its job — it is framed now instead of running behind the
   copy, which is what forced the old scrim to cover 92% of the footage. */
.f4l-hero .f4l-hero__video {
	position: relative;
	inset: auto;
	width: 74%;
	max-width: none;
	height: auto;
	aspect-ratio: 4 / 5;
	border-radius: 20px;
	object-fit: cover;
	z-index: 1;
	animation: f4l-float 6s ease-in-out infinite;
}

@keyframes f4l-float {
	0%, 100% { transform: translateY(0); }
	50% { transform: translateY(-14px); }
}

.f4l-hero__note {
	position: absolute;
	bottom: 2.125rem;
	left: 2.125rem;
	z-index: 2;
	max-width: 250px;
	background: var(--wp--preset--color--white);
	border-radius: 14px;
	padding: 1.125rem 1.25rem;
	box-shadow: var(--f4-shadow-float);
}

.f4l-hero__note strong {
	display: block;
	font-family: var(--wp--preset--font-family--display);
	font-weight: 700;
	font-size: 1.0625rem;
	color: var(--wp--preset--color--contrast);
	margin-bottom: 0.375rem;
}

.f4l-hero__note span {
	display: block;
	font-size: 0.84375rem;
	line-height: 1.45;
	color: var(--f4-ink-70);
}

.f4l-hero__stats {
	display: flex;
	gap: 1.75rem;
	margin-top: 3rem;
	padding-top: 1.625rem;
	border-top: 1px solid var(--f4-line-14);
}

.f4l-hero__stats .f4l-stat__value {
	display: block;
	font-family: var(--wp--preset--font-family--display);
	font-weight: 700;
	font-size: 2.125rem;
	letter-spacing: -0.03em;
	color: var(--wp--preset--color--mint);
	line-height: 1;
}

.f4l-hero__stats .f4l-stat__label {
	display: block;
	font-size: 0.71875rem;
	line-height: 1.4;
	color: var(--f4-ink-65);
	max-width: 120px;
	margin-top: 0.25rem;
}

/* --- Sections -------------------------------------------------------------
   One rhythm shared by every band, and a head that puts the title and its
   supporting line on ONE row — title left, lede right, baselines aligned.
   That single move is what stops six sections reading as one repeated
   template.
   -------------------------------------------------------------------------- */

.f4l-section {
	padding: var(--f4-section-y) var(--f4-gutter) !important;
	background-image: none;
}

/* Two utilities for the wrappers that are not `.f4l-section` — the shop and
   search templates, the product buy panel, the footer. They carry their own
   vertical rhythm in the markup and only need the page's horizontal measure,
   which `.f4l-section` cannot give them without also imposing its vertical
   padding.

   `f4l-bleed` is for a wrapper whose child paints a background edge to edge:
   the gutter belongs to the child, not to the wrapper, or the colour stops
   short of the screen edge. */
.f4l-gutter {
	padding-inline: var(--f4-gutter) !important;
}

.f4l-bleed {
	padding-inline: 0 !important;
}

.f4l-section--tight {
	padding-top: 0 !important;
}

/* No `max-width: none` here.

   Every section is a constrained group carrying its own contentSize — 1280px
   for the bento and the store, 1080px for the tighter ones — and WordPress caps
   and centres each child at that figure. Overriding the cap to `none` let the
   heading run the full padded width while the grid under it stayed at the
   section's measure. Identical at 1280px viewport, where the two figures meet,
   and increasingly wrong above it: at 1920px the heading started at x=44 and
   the bento at x=313, so the title sat 269px to the left of the cards it
   belonged to.

   Leaving the cap alone means the head takes whatever measure its own section
   uses, which is by definition the measure of the grid beside it. */
.f4l-section__head {
	display: flex;
	align-items: flex-end;
	justify-content: space-between;
	gap: 2.5rem;
	margin-bottom: 2.25rem;
}

.f4l-section__head .f4l-lede {
	max-width: 430px;
	font-size: 1rem;
}

.f4l-link-underline {
	flex: none;
	font-size: 0.875rem;
	font-weight: 700;
	color: var(--wp--preset--color--contrast);
	text-decoration: none;
	border-bottom: 2px solid var(--wp--preset--color--mint);
	padding-bottom: 3px;
	white-space: nowrap;
}

.f4l-link-underline:hover {
	color: var(--wp--preset--color--mint);
}

/* --- Bento ----------------------------------------------------------------
   Kept from the previous build — it was already the strongest block on the
   page — but retuned to the new tokens and inverted on hover, so the whole
   tile flips to the brand green instead of only lifting.
   -------------------------------------------------------------------------- */

.f4l-bento {
	display: grid;
	grid-template-columns: repeat(6, 1fr);
	grid-auto-rows: 190px;
	gap: 14px;
}

/* Every tile is a wp:group, so WordPress hands each one but the first a
   `margin-block-start: 1.2rem` for flow spacing. Inside a grid that margin is
   not collapsed or ignored — it is taken out of the tile's own box. The result
   was a 190px row holding a 171px card pushed 19px down, so the first tile in
   each row stood 19px taller than everything beside it and the top edges of the
   whole bento stepped. The grid's `gap` is what spaces these; the flow margin
   has no job here. */
.f4l-bento > * {
	margin-block: 0;
}

/* Arrow pinned top-right, title and copy together at the bottom.

   The three rows are `1fr auto auto`, so the FIRST row swallows all the slack
   in the tile and the two text rows are pushed against the bottom edge as one
   block. The previous `space-between` spread all three evenly instead, which
   parked the title in the middle of the tile with roughly 34px of nothing above
   and below it — the reason the section read as mostly empty even though every
   tile was full. */
.f4l-card {
	grid-column: span 2;
	display: grid;
	grid-template-columns: 1fr auto;
	grid-template-rows: 1fr auto auto;
	padding: 22px;
	background-color: var(--wp--preset--color--mint-light);
	border: 1px solid var(--f4-line-08);
	border-radius: var(--f4-r-xl);
	overflow: hidden;
	transition: background-color 0.35s var(--f4-ease), transform 0.35s var(--f4-ease);
}

.f4l-card--wide { grid-column: span 3; }
.f4l-card--span4 { grid-column: span 4; }
.f4l-card--span6 { grid-column: span 6; }

.f4l-card__title {
	grid-column: 1 / -1;
	grid-row: 2;
	font-family: var(--wp--preset--font-family--display);
	font-weight: 600;
	font-size: 1.4375rem;
	letter-spacing: -0.02em;
	color: var(--wp--preset--color--contrast);
	margin: 0 0 6px;
	transition: color 0.35s var(--f4-ease);
}

.f4l-card__text {
	grid-column: 1 / -1;
	grid-row: 3;
	max-width: 46ch;
	font-size: 0.8125rem;
	line-height: 1.5;
	color: var(--f4-ink-65);
	margin: 0;
	transition: color 0.35s var(--f4-ease);
}

.f4l-card__arrow {
	grid-column: 2;
	grid-row: 1;
	align-self: start;
	width: 30px;
	height: 30px;
	border-radius: 50%;
	background: rgb(47 169 127 / 18%);
	color: var(--wp--preset--color--mint);
	display: flex;
	align-items: center;
	justify-content: center;
	font-size: 13px;
	transition: background-color 0.35s var(--f4-ease), color 0.35s var(--f4-ease);
}

/* --- Bento imagery --------------------------------------------------------
   The eight tile photographs have been in assets/ all along, and the markup has
   carried `f4l-card--image` plus a per-category class on every tile — with no
   rule anywhere to draw them. Hooked up here.

   The photo is not the tile's background; it is the far side of it. A gradient
   in mint-light holds the first ~55% of the width fully opaque and fades out
   across the rest, so the type always sits on flat colour and never on
   photography, whatever the picture happens to be doing behind it. That keeps
   contrast fixed across eight images nobody has art-directed, and it degrades
   to the reference's flat mint-light tile if an image ever fails to load.

   `background-blend-mode` is deliberately NOT used: it would tint the photo
   itself, and these are clinical images where a green cast reads as a bad
   colour profile rather than as a brand.
   -------------------------------------------------------------------------- */

.f4l-card--image {
	background-image:
		linear-gradient(
			100deg,
			var(--wp--preset--color--mint-light) 0%,
			var(--wp--preset--color--mint-light) 56%,
			rgb(241 247 243 / 70%) 72%,
			rgb(241 247 243 / 8%) 100%
		),
		var(--f4l-tile, none);
	background-repeat: no-repeat;
	background-position: center, center right;
	background-size: cover, cover;
}

/* The copy is held inside the opaque part of the gradient rather than being
   allowed to run the full width of the tile. Without this the last words of a
   description finish on top of the photograph, where contrast depends on
   whatever that particular picture happens to be showing — which is exactly the
   thing nobody can check once there are eight of them and the client swaps one.
   Capping the measure means the scrim can be lighter and the photo stronger,
   and the text is on flat colour either way. */
.f4l-card--image .f4l-card__title,
.f4l-card--image .f4l-card__text {
	max-width: 56%;
}

.f4l-card--wide.f4l-card--image .f4l-card__title,
.f4l-card--wide.f4l-card--image .f4l-card__text,
.f4l-card--span4.f4l-card--image .f4l-card__title,
.f4l-card--span4.f4l-card--image .f4l-card__text,
.f4l-card--span6.f4l-card--image .f4l-card__title,
.f4l-card--span6.f4l-card--image .f4l-card__text {
	max-width: 42%;
}

.f4l-card--weight-loss { --f4l-tile: url("assets/tile-weight-loss-consult.webp"); }
.f4l-card--longevity   { --f4l-tile: url("assets/tile-longevity-senior.webp"); }
.f4l-card--peptide     { --f4l-tile: url("assets/tile-peptide-microscope.webp"); }
.f4l-card--hormone     { --f4l-tile: url("assets/tile-hormone-tubes.webp"); }
.f4l-card--iv-therapy  { --f4l-tile: url("assets/tile-iv-therapy-drip.webp"); }
.f4l-card--vitamin     { --f4l-tile: url("assets/tile-vitamin-injection.webp"); }
.f4l-card--strength    { --f4l-tile: url("assets/tile-strength-barbell.webp"); }
.f4l-card--recovery    { --f4l-tile: url("assets/tile-recovery-capsules.webp"); }

/* A narrow tile has no room to show a photograph next to its own text, so the
   span-2 cells keep the gradient tight and let only an edge of the image
   through. The wide ones — span 3, 4 and 6 — are where the picture actually
   gets to be a picture. */
.f4l-card--wide,
.f4l-card--span4,
.f4l-card--span6 {
	background-position: center, center right;
}

.f4l-card--wide.f4l-card--image,
.f4l-card--span4.f4l-card--image,
.f4l-card--span6.f4l-card--image {
	background-image:
		linear-gradient(
			100deg,
			var(--wp--preset--color--mint-light) 0%,
			var(--wp--preset--color--mint-light) 42%,
			rgb(241 247 243 / 55%) 60%,
			rgb(241 247 243 / 0%) 100%
		),
		var(--f4l-tile, none);
}

.f4l-card:hover {
	background-color: var(--wp--preset--color--mint-deep);
	transform: translateY(-4px);
}

/* Hover swaps the mint scrim for a dark one over the same photograph, so the
   picture stays put and only the sheet in front of it changes colour. */
.f4l-card--image:hover,
.f4l-card--wide.f4l-card--image:hover,
.f4l-card--span4.f4l-card--image:hover,
.f4l-card--span6.f4l-card--image:hover {
	background-image:
		linear-gradient(
			100deg,
			var(--wp--preset--color--mint-deep) 0%,
			var(--wp--preset--color--mint-deep) 52%,
			rgb(15 61 48 / 82%) 70%,
			rgb(15 61 48 / 45%) 100%
		),
		var(--f4l-tile, none);
}

.f4l-card:hover .f4l-card__title { color: var(--wp--preset--color--white); }
.f4l-card:hover .f4l-card__text { color: var(--f4-on-dark-70); }

.f4l-card:hover .f4l-card__arrow {
	background: rgb(127 227 184 / 22%);
	color: var(--wp--preset--color--mint-bright);
}

/* --- Dark panel: diagnostics ---------------------------------------------- */

/* `box-sizing` is set explicitly because this is a plain div inside a wp:html
   block, and a block theme ships no global border-box reset — so it inherits the
   browser's content-box. With a max-width coming from the section layout (1080px)
   and 44px of padding on each side, content-box made the panel render 1168px
   wide: wider than the steps and the guarantees grid in the sibling sections
   that share the same measure, by exactly its own padding. */
.f4l-panel {
	box-sizing: border-box;
	display: grid;
	grid-template-columns: 1fr 1fr;
	gap: 2.75rem;
	align-items: center;
	padding: 3.5rem 2.75rem;
	background: var(--wp--preset--color--mint-deep);
	color: var(--wp--preset--color--white);
	border-radius: var(--f4-r-3xl);
}

.f4l-panel__title { color: var(--wp--preset--color--white); }

.f4l-panel .f4l-lede {
	color: var(--f4-on-dark-70);
	font-size: 1.03125rem;
	margin-top: 1.25rem;
	max-width: 400px;
}

.f4l-panel__list {
	display: grid;
	gap: 12px;
}

.f4l-panel__row {
	display: flex;
	align-items: center;
	gap: 1.25rem;
	background: var(--f4-on-dark-07);
	border-radius: 14px;
	padding: 1.125rem 1.375rem;
}

.f4l-panel__row b {
	font-family: var(--wp--preset--font-family--display);
	font-weight: 700;
	font-size: 2.5rem;
	letter-spacing: -0.03em;
	color: var(--wp--preset--color--mint-bright);
	min-width: 104px;
}

.f4l-panel__row span {
	font-size: 0.84375rem;
	line-height: 1.5;
	color: var(--f4-on-dark-78);
}

/* --- Product cards --------------------------------------------------------
   A framed card: photo flush to the top edge, name and price stacked, action
   at the foot.
   -------------------------------------------------------------------------- */

.f4l-store .wc-block-product-template {
	display: grid;
	grid-template-columns: repeat(4, 1fr);
	gap: 16px;
}

.f4l-product {
	display: flex;
	flex-direction: column;
	height: 100%;
	padding: 0;
	background: var(--wp--preset--color--white);
	border: 1px solid var(--f4-line-12);
	border-radius: var(--f4-r-xl);
	overflow: hidden;
	transition: box-shadow 0.35s var(--f4-ease), transform 0.35s var(--f4-ease);
}

.f4l-product:hover {
	transform: translateY(-6px);
	box-shadow: var(--f4-shadow-card);
	border-color: var(--f4-line-12);
}

.f4l-product__media {
	margin: 0;
	border-radius: 0;
	overflow: hidden;
	background: var(--wp--preset--color--mint-light);
}

.f4l-product__media img {
	width: 100%;
	height: 200px;
	aspect-ratio: auto;
	object-fit: cover;
	transition: transform 0.6s var(--f4-ease);
}

.f4l-product:hover .f4l-product__media img { transform: scale(1.04); }

.f4l-product__title {
	margin: 0;
	padding: 18px 18px 0;
	font-family: var(--wp--preset--font-family--display);
	font-weight: 600;
	font-size: 1.125rem;
	letter-spacing: -0.02em;
	line-height: 1.25;
	text-align: left;
}

.f4l-product__title a {
	color: var(--wp--preset--color--contrast);
	text-decoration: none;
}

.f4l-product__title a:hover { color: var(--wp--preset--color--mint); }

/* The category sits between the name and the price — it is what tells a
   visitor that "Sermorelin" and "NAD+ Nasal Spray" are the same kind of thing
   as each other and a different kind from "GLP-1 Monthly Program". Without it
   the four cards on the landing read as an unsorted pile. */
.f4l-product__cat {
	margin: 4px 18px 0;
	font-size: 0.78125rem;
	line-height: 1.4;
	color: var(--f4-ink-55);
}

.f4l-product__cat a {
	color: inherit;
	text-decoration: none;
}

.f4l-product__cat a:hover { color: var(--wp--preset--color--mint); }

/* Price and button share one row, pushed apart. `margin-top: auto` is on the
   foot rather than the price so cards of unequal title length still line their
   buttons up along the bottom edge of the grid. */
.f4l-product__foot {
	margin-top: auto;
	padding: 14px 18px 18px;
	gap: 10px;
}

.f4l-product__price {
	margin: 0;
	font-family: var(--wp--preset--font-family--display);
	font-weight: 700;
	font-size: 1.1875rem;
	letter-spacing: -0.02em;
	color: var(--wp--preset--color--contrast);
	text-align: left;
}

.f4l-product__button {
	margin: 0;
	padding: 0;
}

.f4l-product__button .wp-element-button,
.f4l-product__button .wc-block-components-product-button__button {
	background: var(--wp--preset--color--mint);
	border: 0;
	color: var(--wp--preset--color--forest);
	font-weight: 700;
	font-size: 0.8125rem;
	border-radius: var(--f4-r-sm);
	padding: 0.6875rem 1rem;
	white-space: nowrap;
}

.f4l-product__button .wp-element-button:hover,
.f4l-product__button .wc-block-components-product-button__button:hover {
	background: var(--wp--preset--color--mint-deep);
	color: var(--wp--preset--color--white);
}

/* The related grid on a product page shows a shorter image than the landing:
   it is a footnote to the product above it, not the section the page is about. */
.f4l-product__media--sm img { height: 170px; }

/* The soft variant. On the landing the mint button is the loudest thing in the
   section and should be. In "Other treatments" it would out-shout the actual
   buy button a few hundred pixels above it, so it waits in mint-light until
   the pointer arrives. */
.f4l-product__button--soft .wp-element-button,
.f4l-product__button--soft .wc-block-components-product-button__button {
	background: var(--wp--preset--color--mint-light);
	color: var(--wp--preset--color--contrast);
}

.f4l-product__button--soft .wp-element-button:hover,
.f4l-product__button--soft .wc-block-components-product-button__button:hover {
	background: var(--wp--preset--color--mint);
	color: var(--wp--preset--color--forest);
}

/* --- Product page: buy column --------------------------------------------- */

.f4l-single__cat {
	margin: 0 0 0.625rem;
	font-size: 0.8125rem;
	font-weight: 600;
	line-height: 1.4;
	color: var(--wp--preset--color--mint);
}

.f4l-single__cat a {
	color: inherit;
	text-decoration: none;
}

.f4l-single__cat a:hover { text-decoration: underline; }

.f4l-single__pricerow {
	margin-top: 1.125rem;
	gap: 0.75rem;
}

.f4l-single__stock {
	margin: 0;
	font-size: 0.875rem;
	color: var(--f4-ink-55);
	white-space: nowrap;
}

/* The same figure the block above renders. Hidden, not removed: the block is
   what supplies it, and the out-of-stock note in functions.php hangs off the
   copy that stays visible in the price row. */
.f4l-single__cart > .wc-block-components-product-stock-indicator {
	display: none;
}

/* --- Shop grid: the frameless tile ----------------------------------------
   The shop grid is NOT the landing's `.f4l-product` card and the reference is
   deliberate about the difference. On the landing, four products are a guest
   appearance inside a page about the clinic, so each one is boxed to mark it
   as a different kind of object from the sections around it. The shop is
   nothing but products: forty borders there would draw a cage and add no
   information. So the tile has no frame — the image carries the shape, and
   whitespace does the separating.
   -------------------------------------------------------------------------- */

.f4l-shop .wc-block-product-template {
	display: grid;
	grid-template-columns: repeat(3, 1fr);
	gap: 34px 24px;
}

.f4l-tile {
	display: flex;
	flex-direction: column;
}

.f4l-tile__media {
	position: relative;
	margin: 0 0 14px;
	aspect-ratio: 1;
	border-radius: var(--f4-r-lg);
	overflow: hidden;
	background: var(--wp--preset--color--mint-light);
	transition: transform 0.4s var(--f4-ease);
}

.f4l-tile__media img {
	width: 100%;
	height: 100%;
	object-fit: cover;
}

/* The reference scales the whole media block, not the image inside it. With
   `overflow: hidden` on the same element the two look identical at rest, but
   scaling the wrapper keeps the rounded corner growing with the image instead
   of holding still while the picture slides under it. */
.f4l-tile:hover .f4l-tile__media { transform: scale(1.02); }

/* --------------------------------------------------------------------------
   The Rx badge is drawn, not stored. Every product in the catalogue today is
   a prescription treatment, which is what the shop intro and the product page
   notice both already say, so a badge on every tile states nothing new.

   It is a pseudo-element for exactly that reason: it is a repetition of a
   claim the page makes in prose, so it should not be read out forty times,
   and it must not look like per-product data when no product carries such a
   field.

   THE DAY THE CATALOGUE HOLDS ONE NON-PRESCRIPTION ITEM THIS BECOMES A LIE.
   At that point it stops being a style rule and has to become a real product
   attribute driving a real element. Until then the storefront is 100% Rx and
   this is honest.
   -------------------------------------------------------------------------- */
.f4l-tile__media::after {
	content: "Rx";
	position: absolute;
	top: 14px;
	left: 14px;
	padding: 5px 10px;
	border-radius: var(--f4-r-badge);
	background: var(--wp--preset--color--mint-deep);
	color: var(--wp--preset--color--mint-bright);
	font-family: var(--wp--preset--font-family--body);
	font-size: 0.625rem;
	font-weight: 700;
	letter-spacing: 0.1em;
	text-transform: uppercase;
	line-height: 1;
}

.f4l-tile__title {
	margin: 0 0 4px;
	font-family: var(--wp--preset--font-family--display);
	font-weight: 600;
	font-size: 1.3125rem;
	line-height: 1.2;
	letter-spacing: -0.025em;
	text-align: left;
}

.f4l-tile__title a {
	color: var(--wp--preset--color--contrast);
	text-decoration: none;
}

.f4l-tile__title a:hover { color: var(--wp--preset--color--mint); }

.f4l-tile__cat {
	margin: 0 0 6px;
	font-size: 0.8125rem;
	line-height: 1.4;
	color: var(--f4-ink-55);
}

.f4l-tile__cat a {
	color: inherit;
	text-decoration: none;
}

.f4l-tile__cat a:hover { color: var(--wp--preset--color--mint); }

.f4l-tile__price {
	margin: 0 0 14px;
	font-family: var(--wp--preset--font-family--display);
	font-weight: 700;
	font-size: 1.25rem;
	letter-spacing: -0.03em;
	color: var(--wp--preset--color--contrast);
	text-align: left;
}

/* `margin-top: auto` pins the button to the bottom of the tile so a two-line
   product name does not push its button below the buttons beside it. */
.f4l-tile__button {
	margin: auto 0 0;
	padding: 0;
}

.f4l-tile__button .wp-element-button,
.f4l-tile__button .wc-block-components-product-button__button {
	display: block;
	width: 100%;
	background: var(--wp--preset--color--mint);
	border: 0;
	color: var(--wp--preset--color--forest);
	font-family: var(--wp--preset--font-family--body);
	font-weight: 700;
	font-size: 0.875rem;
	border-radius: var(--f4-r-md);
	padding: 0.875rem 1rem;
	text-align: center;
}

.f4l-tile__button .wp-element-button:hover,
.f4l-tile__button .wc-block-components-product-button__button:hover {
	background: var(--wp--preset--color--mint-deep);
	color: var(--wp--preset--color--white);
}

/* --- Why: dark panel + guarantees ----------------------------------------- */

.f4l-why {
	display: grid;
	grid-template-columns: 1.25fr 1fr;
	gap: 16px;
}

.f4l-why__panel {
	display: flex;
	align-items: flex-end;
	min-height: 340px;
	padding: 3rem;
	background: var(--wp--preset--color--mint-deep);
	color: var(--wp--preset--color--white);
	border-radius: var(--f4-r-2xl);
}

.f4l-why__title { color: var(--wp--preset--color--white); }

.f4l-why__panel .f4l-lede {
	color: var(--f4-on-dark-70);
	font-size: 1rem;
	margin-top: 0.875rem;
}

.f4l-trust {
	display: grid;
	grid-template-columns: 1fr;
	gap: 16px;
	margin-top: 0;
}

.f4l-trust__item {
	flex-direction: row;
	align-items: flex-start;
	gap: 1rem;
	padding: 1.375rem 1.5rem;
	background: var(--wp--preset--color--mint-light);
	border: 1px solid var(--f4-line-08);
	border-radius: var(--f4-r-lg);
	text-align: left;
	box-shadow: none;
	transition: none;
}

.f4l-trust__item::before { display: none; }
.f4l-trust__item:hover { transform: none; box-shadow: none; }

.f4l-trust__icon {
	flex: none;
	width: 38px;
	height: 38px;
	padding: 8px;
	margin: 0;
	border-radius: var(--f4-r-sm);
	background: var(--wp--preset--color--white);
	color: var(--wp--preset--color--mint);
}

.f4l-trust__title {
	margin: 0 0 5px;
	font-family: var(--wp--preset--font-family--display);
	font-weight: 600;
	font-size: 1.125rem;
	color: var(--wp--preset--color--contrast);
}

.f4l-trust__text {
	margin: 0;
	max-width: none;
	font-size: 0.84375rem;
	line-height: 1.5;
	color: var(--f4-ink-65);
	opacity: 1;
}

/* --- Steps ---------------------------------------------------------------- */

.f4l-steps {
	display: grid;
	grid-template-columns: repeat(3, 1fr);
	gap: 16px;
	margin: 0;
	padding: 0;
	list-style: none;
}

.f4l-steps::before { display: none; }

.f4l-step {
	display: block;
	padding: 30px;
	background: var(--wp--preset--color--white);
	border: 1px solid var(--f4-line-14);
	border-radius: var(--f4-r-xl);
	text-align: left;
}

.f4l-step__num {
	display: flex;
	align-items: center;
	justify-content: center;
	width: 44px;
	height: 44px;
	margin-bottom: 20px;
	padding: 0;
	border: 0;
	border-radius: var(--f4-r-md);
	background: var(--wp--preset--color--mint-deep);
	color: var(--wp--preset--color--mint-bright);
	font-family: var(--wp--preset--font-family--display);
	font-weight: 700;
	font-size: 1.125rem;
	letter-spacing: 0;
	opacity: 1;
}

.f4l-step__title {
	margin: 0 0 8px;
	font-family: var(--wp--preset--font-family--display);
	font-weight: 600;
	font-size: 1.4375rem;
	color: var(--wp--preset--color--contrast);
}

.f4l-step__text {
	margin: 0;
	max-width: none;
	font-size: 0.875rem;
	line-height: 1.6;
	color: var(--f4-ink-65);
	opacity: 1;
}

/* --- CTA ------------------------------------------------------------------
   A mint block with real corners, inset from the page edge, rather than a
   full-bleed band. The inset is the point: it reads as an object placed at the
   end of the page instead of one more stripe.
   -------------------------------------------------------------------------- */

.f4l-cta {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 2.5rem;
	margin: 0 var(--f4-gutter) var(--f4-gutter) !important;
	padding: 4.25rem 3rem !important;
	background: var(--wp--preset--color--mint) !important;
	background-image: none !important;
	border-radius: var(--f4-r-3xl);
	width: auto !important;
	max-width: none;
}

.f4l-cta > * {
	max-width: none !important;
	margin-inline: 0 !important;
}

.f4l-cta__title {
	color: var(--wp--preset--color--forest);
	max-width: 640px;
	text-align: left;
}

.f4l-cta__button { flex: none; }

.f4l-cta__button .wp-block-button__link {
	background: var(--wp--preset--color--forest);
	color: var(--wp--preset--color--white);
	padding: 1.1875rem 2.125rem;
	box-shadow: none;
}

.f4l-cta__button .wp-block-button__link:hover {
	background: var(--wp--preset--color--mint-deep);
	color: var(--wp--preset--color--white);
	box-shadow: none;
}

/* --- Shop ----------------------------------------------------------------- */

.f4l-hero-shop {
	display: grid;
	grid-template-columns: 1.1fr 0.9fr;
	gap: 2.75rem;
	align-items: end;
	/* The page gutter, not the shop-specific one. The reference set the shop at
	   40px against 44px elsewhere, a distinction drawn on a 1280px artboard
	   where nothing else shared an edge with it. Full-width, this band's H1 sits
	   directly under the header logo, and a 4px disagreement between them is
	   visible as a wobble in a vertical line that runs the height of the page. */
	padding: 3.5rem var(--f4-gutter) 2.75rem;
	background: var(--wp--preset--color--mint-light);
	background-image: none;
}

/* The header comes out of a shortcode, and the block that runs it hands the
   result through wpautop, which leaves an empty <p> behind. Sitting in a grid
   that costs a third row plus a 44px gap — about 72px of blank mint-light under
   the intro, which is invisible in two columns and obvious once the band
   stacks on a phone. */
.f4l-hero-shop > :empty {
	display: none;
}

.f4l-hero-shop__intro {
	font-size: 1.0625rem;
	line-height: 1.6;
	color: var(--f4-ink-70);
	margin: 0;
	max-width: none;
	opacity: 1;
}

.f4l-shop__filters .f4l-filter {
	background: none;
	border: 0;
	border-radius: 0;
	box-shadow: none;
	padding: 0;
	margin-bottom: 2rem;
}

.f4l-filter__title {
	font-size: 0.75rem;
	font-weight: 700;
	letter-spacing: 0.1em;
	text-transform: uppercase;
	color: var(--f4-ink-45);
	margin-bottom: 0.75rem;
	opacity: 1;
}

/* Borderless tiles: the shop grid drops the card frame the landing keeps, so
   the two grids are related without being the same object. */
.f4l-shop .wp-block-woocommerce-product-template {
	display: grid;
	grid-template-columns: repeat(3, 1fr);
	gap: 34px 24px;
}

.f4l-shop .wp-block-woocommerce-product-template li {
	display: flex;
	flex-direction: column;
	gap: 14px;
	padding: 0;
	background: none;
	border: 0;
	border-radius: 0;
	box-shadow: none;
	transition: none;
}

.f4l-shop .wp-block-woocommerce-product-template li:hover {
	transform: none;
	box-shadow: none;
	border-color: transparent;
}

.f4l-shop .wp-block-woocommerce-product-image,
.f4l-shop .wc-block-components-product-image {
	display: block;
	overflow: hidden;
	border-radius: var(--f4-r-lg);
	margin: 0;
	background: var(--wp--preset--color--mint-light);
}

.f4l-shop .wp-block-woocommerce-product-template img {
	border-radius: var(--f4-r-lg);
	aspect-ratio: 1;
	object-fit: cover;
	transition: transform 0.4s var(--f4-ease);
}

.f4l-shop .wp-block-woocommerce-product-template li:hover img {
	transform: scale(1.02);
}

.f4l-shop .wp-block-woocommerce-product-template .wp-block-post-title {
	margin: 0;
	padding: 0;
	font-family: var(--wp--preset--font-family--display);
	font-weight: 600;
	font-size: 1.3125rem;
	letter-spacing: -0.025em;
	line-height: 1.2;
	text-align: left;
}

.f4l-shop .wp-block-woocommerce-product-template .wp-block-woocommerce-product-price {
	margin: 0;
	padding: 0;
	font-family: var(--wp--preset--font-family--display);
	font-weight: 700;
	font-size: 1.25rem;
	letter-spacing: -0.03em;
	color: var(--wp--preset--color--contrast);
	text-align: left;
}

.f4l-shop .wp-block-woocommerce-product-button {
	margin: 0;
	margin-top: auto;
}

.f4l-shop .wp-block-woocommerce-product-button .wp-block-button__link {
	width: 100%;
	background: var(--wp--preset--color--mint);
	border: 0;
	color: var(--wp--preset--color--forest);
	border-radius: var(--f4-r-md);
	padding: 0.875rem;
	font-size: 0.84375rem;
	font-weight: 700;
}

.f4l-shop .wp-block-woocommerce-product-button .wp-block-button__link:hover {
	background: var(--wp--preset--color--mint-deep);
	color: var(--wp--preset--color--white);
}

/* --- Single product ------------------------------------------------------- */

.f4l-single__media {
	position: relative;
}

.f4l-single__media img {
	aspect-ratio: 1;
	object-fit: contain;
	padding: 2.5rem;
	background: var(--wp--preset--color--mint-light);
	border: 0;
	border-radius: var(--f4-r-2xl);
	box-shadow: none;
}

/* Same badge as the shop tile, same reasoning — see the note on
   `.f4l-tile__media::after`. Inset 18px here rather than 14px because it sits
   on a much larger square and the reference opens the margin with it. */
.f4l-single__media::after {
	content: "Rx";
	position: absolute;
	top: 18px;
	left: 18px;
	padding: 6px 11px;
	border-radius: var(--f4-r-badge);
	background: var(--wp--preset--color--mint-deep);
	color: var(--wp--preset--color--mint-bright);
	font-family: var(--wp--preset--font-family--body);
	font-size: 0.625rem;
	font-weight: 700;
	letter-spacing: 0.1em;
	text-transform: uppercase;
	line-height: 1;
}

.f4l-single__price {
	font-family: var(--wp--preset--font-family--display);
	font-weight: 700;
	font-size: 2.5rem;
	letter-spacing: -0.03em;
	line-height: 1;
	color: var(--wp--preset--color--contrast);
	margin: 1.125rem 0 0;
}

.f4l-single__excerpt {
	font-size: 1.0625rem;
	line-height: 1.6;
	color: var(--f4-ink-70);
	opacity: 1;
	margin: 1.125rem 0 0;
	max-width: 460px;
}

/* The prescription notice inverts: it was a soft mint tint and is now the
   brand green, because it is the one block on this page that must not be
   skimmed past. */
.f4l-rx {
	display: block;
	margin: 1.625rem 0 0;
	padding: 1.5rem 1.625rem;
	background: var(--wp--preset--color--mint-deep);
	border-radius: var(--f4-r-lg);
}

.f4l-rx__icon { display: none; }

.f4l-rx strong {
	display: block;
	margin-bottom: 0.5rem;
	font-family: var(--wp--preset--font-family--display);
	font-weight: 700;
	font-size: 1.25rem;
	letter-spacing: -0.02em;
	color: var(--wp--preset--color--white);
}

.f4l-rx span {
	display: block;
	font-size: 0.90625rem;
	line-height: 1.6;
	color: var(--f4-on-dark-78);
	opacity: 1;
}

.f4l-single__cart {
	position: static;
	padding: 0;
	margin-top: 1.75rem;
	background: none;
	border: 0;
	border-radius: 0;
	box-shadow: none;
}

/* --- Motion --------------------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
	.f4l-hero .f4l-hero__video { animation: none; }

	.f4l-card:hover,
	.f4l-product:hover {
		transform: none;
	}
}

/* --- Responsive -----------------------------------------------------------
   The reference's two breakpoints, kept as they were written: 1199px folds the
   split layouts into one column, 899px is the phone.
   -------------------------------------------------------------------------- */

@media (max-width: 1199px) {
	:root {
		--f4-gutter: 32px;
		--f4-gutter-shop: 28px;
		--f4-section-y: 64px;
	}

	.f4l-hero,
	.f4l-panel,
	.f4l-why,
	.f4l-hero-shop {
		grid-template-columns: 1fr;
	}

	.f4l-hero__media { min-height: 420px; }

	.f4l-bento { grid-template-columns: repeat(4, 1fr); }

	.f4l-card--span4,
	.f4l-card--span6 { grid-column: span 4; }

	.f4l-card--wide { grid-column: span 2; }

	.f4l-store .wc-block-product-template,
	.f4l-shop .wp-block-woocommerce-product-template {
		grid-template-columns: repeat(2, 1fr);
	}

	/* Below 1200px the bento drops to four columns and then to one, so a tile
	   is between roughly 280px and a phone's width. There is no room there for
	   a photograph beside the text: holding the copy inside a 56% measure would
	   squeeze a two-line description into six lines, and letting it run full
	   width would put it back on top of the picture.

	   So the imagery is a wide-screen affordance only. Below this breakpoint the
	   tiles revert to the flat mint-light the reference specifies — which is not
	   a fallback, it is the approved design; the photographs are the addition. */
	/* Matched at two classes, not one: the wide-tile rules above are compound
	   selectors, so a bare `.f4l-card--image` here loses to them on specificity
	   and the photograph survives the breakpoint. */
	.f4l-card--image,
	.f4l-card--wide.f4l-card--image,
	.f4l-card--span4.f4l-card--image,
	.f4l-card--span6.f4l-card--image {
		background-image: none;
	}

	.f4l-card--image .f4l-card__title,
	.f4l-card--image .f4l-card__text,
	.f4l-card--wide.f4l-card--image .f4l-card__title,
	.f4l-card--wide.f4l-card--image .f4l-card__text,
	.f4l-card--span4.f4l-card--image .f4l-card__title,
	.f4l-card--span4.f4l-card--image .f4l-card__text,
	.f4l-card--span6.f4l-card--image .f4l-card__title,
	.f4l-card--span6.f4l-card--image .f4l-card__text {
		max-width: none;
	}

	.f4l-card--image:hover,
	.f4l-card--wide.f4l-card--image:hover,
	.f4l-card--span4.f4l-card--image:hover,
	.f4l-card--span6.f4l-card--image:hover {
		background-image: none;
	}
}

@media (max-width: 899px) {
	:root {
		--f4-gutter: 22px;
		--f4-gutter-shop: 20px;
		--f4-section-y: 48px;
	}

	.f4l-section__head {
		flex-direction: column;
		align-items: flex-start;
		gap: 1.25rem;
	}

	.f4l-bento { grid-template-columns: 1fr; grid-auto-rows: auto; }

	.f4l-card,
	.f4l-card--wide,
	.f4l-card--span4,
	.f4l-card--span6 {
		grid-column: span 1;
		min-height: 160px;
	}

	.f4l-store .wc-block-product-template,
	.f4l-shop .wp-block-woocommerce-product-template,
	.f4l-steps {
		grid-template-columns: 1fr;
	}

	.f4l-cta {
		flex-direction: column;
		align-items: flex-start;
		padding: 2.5rem 1.75rem !important;
	}

	.f4l-hero__stats { flex-wrap: wrap; gap: 1.25rem; }
	.f4l-panel { padding: 2.5rem 1.75rem; }
	.f4l-why__panel { padding: 2rem; min-height: 0; }

	/* --- Bento imagery comes back, as a band across the top -----------------
	   The photographs are off between 900px and 1200px because the bento is
	   four columns there and a ~280px tile in a fixed 190px row has room for
	   neither a picture beside the text nor one above it.

	   Below 900px neither of those is true any more: the bento is a single
	   column, so every tile is the full width of the page, and the rows are
	   `auto` rather than a fixed 190px, so a tile can grow. That is a card, and
	   a card puts its picture on top.

	   The image is still a background rather than an <img>, because the markup
	   is a wp:group with no image element in it — and the alternative, adding
	   eight <img> tags, would make them content. They are decoration: every one
	   repeats what the heading beside it already says.
	   ---------------------------------------------------------------------- */
	.f4l-card--image,
	.f4l-card--wide.f4l-card--image,
	.f4l-card--span4.f4l-card--image,
	.f4l-card--span6.f4l-card--image {
		padding-top: 8.5rem;
		background-image:
			linear-gradient(
				180deg,
				rgb(241 247 243 / 0%) 0,
				rgb(241 247 243 / 0%) 6.5rem,
				var(--wp--preset--color--mint-light) 7.75rem,
				var(--wp--preset--color--mint-light) 100%
			),
			var(--f4l-tile, none);
		background-size: 100% 100%, cover;
		background-position: top left, center top;
		background-repeat: no-repeat, no-repeat;
	}

	.f4l-card--image:hover,
	.f4l-card--wide.f4l-card--image:hover,
	.f4l-card--span4.f4l-card--image:hover,
	.f4l-card--span6.f4l-card--image:hover {
		background-image:
			linear-gradient(
				180deg,
				rgb(15 61 48 / 0%) 0,
				rgb(15 61 48 / 0%) 6.5rem,
				var(--wp--preset--color--mint-deep) 7.75rem,
				var(--wp--preset--color--mint-deep) 100%
			),
			var(--f4l-tile, none);
	}

	/* The arrow would otherwise float in the middle of the photograph. */
	.f4l-card--image .f4l-card__arrow {
		align-self: end;
	}

	/* Order confirmation. The receipt stops being a side panel and becomes the
	   band under the message — still dark, so it still reads as a separate
	   object rather than more page. */
	.f4l-order-hero { grid-template-columns: 1fr; }
	.f4l-order-hero__copy { padding: 3rem 1.375rem; }
	.f4l-receipt { padding: 2.5rem 1.375rem; }

	.f4l-next { grid-template-columns: 1fr; }

	/* The landing card's price/button row: a long product name plus a "Select
	   options" button does not fit side by side at one column, so the button
	   drops under the price and takes the full width rather than being squeezed
	   to three words per line. */
	.f4l-product__foot { flex-wrap: wrap; }
	.f4l-product__foot .f4l-product__button { width: 100%; }

	.f4l-product__foot .f4l-product__button .wp-element-button,
	.f4l-product__foot .f4l-product__button .wc-block-components-product-button__button {
		display: block;
		width: 100%;
	}
}

/* --- Product page: the buy bar on a phone ---------------------------------
   Between 900px and 1200px the two product columns are already stacked by the
   rule above, which leaves the buy button somewhere in the middle of a long
   scroll. The reference pins it to the bottom of the viewport at that point so
   the one action on the page is always within thumb reach.

   `position: sticky` rather than `fixed`: sticky stops at the end of its own
   container, so the bar rides the screen while the buy column is in view and
   then stays behind with the rest of the page instead of hovering over the
   related products and the footer forever.
   -------------------------------------------------------------------------- */

@media (max-width: 899px) {
	.f4l-single__cart {
		position: sticky;
		bottom: 0;
		z-index: 20;
		margin-inline: -1.375rem;
		padding: 0.75rem 1.375rem;
		background: var(--wp--preset--color--white);
		border-top: 1px solid var(--f4-line-12);
	}
}

/* --- Single product: facts row -------------------------------------------- */

.f4l-facts {
	display: grid;
	grid-template-columns: repeat(3, 1fr);
	margin-top: 1.625rem;
	border-top: 1px solid var(--f4-line-14);
}

.f4l-facts div { padding: 1.125rem 1rem 0; }
.f4l-facts div + div { border-left: 1px solid var(--f4-line-14); }

.f4l-facts b {
	display: block;
	font-family: var(--wp--preset--font-family--display);
	font-weight: 700;
	font-size: 1.5rem;
	color: var(--wp--preset--color--mint);
}

.f4l-facts span {
	display: block;
	margin-top: 0.25rem;
	font-size: 0.78125rem;
	line-height: 1.45;
	color: var(--f4-ink-65);
}

@media (max-width: 899px) {
	.f4l-facts { grid-template-columns: 1fr; }
	.f4l-facts div + div { border-left: 0; border-top: 1px solid var(--f4-line-14); }
}

/* The tile used to carry a `.f4l-card__index` (01..08) that the reference does
   not have. It was never a design element — it had no rule anywhere in this
   file and rendered as a stray unstyled paragraph above each heading — and the
   client's standing rule against section micro-labels rules it out on purpose,
   not by omission. Removed from the markup, and the rule that placed it went
   with it. The tile's own layout lives with `.f4l-card` further up. */
