/*
Theme Name: CesarFeed
Theme URI: https://www.cesarfeed.com/
Description: CesarFeed storefront theme. A Storefront child theme with the CesarFeed brand, a header search overlay backed by a theme REST route, catalogue metadata drawn from product categories, and page-sourced product tabs. Plain PHP and CSS, no encoded code, no build step, no external font requests.
Author: On Initiative LLC
Author URI: https://www.oninitiative.com/
Template: storefront
Version: 1.188.0
Requires at least: 6.5
Tested up to: 6.9
Requires PHP: 8.2
License: GNU General Public License v2 or later
License URI: http://www.gnu.org/licenses/gpl-2.0.html
Text Domain: cesarfeed
Tags: e-commerce, two-columns, custom-colors, custom-menu, custom-logo, featured-images, full-width-template, accessibility-ready
*/

/* This stylesheet is enqueued by Storefront itself as storefront-child-style,
   after the parent stylesheet and after the parent WooCommerce stylesheet.
   That ordering is why almost nothing here needs !important. */

/* --- Tokens ------------------------------------------------------------ */

:root {
	--cf-indigo: #2f2fa2;
	--cf-indigo-deep: #14105c;
	--cf-ink: #0f1029;
	--cf-lilac: #a096ff;
	--cf-tint: #f6f6f7;
	--cf-line: #e6e5e9;
	--cf-line-strong: #d2d1d8;
	--cf-body: #3c3f55;

	/* Link colours are their own tokens rather than reaching for the brand
	   fill. A link is a state machine, and the two states have to be named
	   somewhere one edit can reach both. --cf-link is the same value as
	   --cf-indigo today; that they agree is a design decision, not a fact the
	   stylesheet should depend on. */
	--cf-link: #2f2fa2;
	--cf-link-hover: #000080;

	/* max() so the line survives a low density screen and does not thin out
	   when the reader zooms. */
	--cf-underline: max(1px, .0625rem);
	--cf-underline-offset: .16em;

	/* The keyboard focus ring. One token so the colour is decided by the
	   surface a control sits on rather than by the control, and so a new dark
	   band is one line rather than one rule per element inside it. */
	--cf-focus: #2f2fa2;

	/* Font size for every form control. It is a token, not a per-rule value,
	   because iOS Safari zooms the page whenever a focused control computes
	   below 16px, and before 1.96.0 every field on this site was between 14.40
	   and 15.36px. One number decides it everywhere, and the narrow-screen
	   override at the end of this file raises it to the threshold. */
	--cf-field-size: .95rem;
	--cf-muted: #6b6f8a;
	--cf-mapped: #12805c;

	--cf-crumb-gap: 1.25rem;
	--cf-crumb-below: 1.25rem;
	--cf-head-pad-top: 1.2rem;
	--cf-radius: 12px;
	--cf-radius-sm: 7px;
	--cf-shadow: 0 1px 2px rgba(15,16,41,.04), 0 10px 28px rgba(15,16,41,.06);
	--cf-shadow-lift: 0 2px 6px rgba(15,16,41,.06), 0 18px 44px rgba(15,16,41,.13);

	--cf-display: "Poppins", "Segoe UI", system-ui, -apple-system, sans-serif;
	--cf-mono: "IBM Plex Mono", ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
	--cf-text: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
}

body { font-family: var(--cf-text); color: var(--cf-body); font-size: 1rem; }

h1, h2, h3, h4 {
	font-family: var(--cf-display);
	color: var(--cf-ink);
	letter-spacing: -.02em;
	margin: 0 0 .55em;
	font-weight: 700;
}

h1 { font-size: 2.7rem; line-height: 1.1; }
h2 { font-size: 1.85rem; line-height: 1.18; }
h3 { font-size: 1.22rem; line-height: 1.28; font-weight: 600; letter-spacing: -.012em; }
h4 { font-size: 1rem; font-weight: 600; }

/* =========================================================================
   Parent layout register
   =========================================================================

   Storefront lays the whole site out with floats. Its scaffolding for that is
   a clearfix on the container, which compiles to a ::before and an ::after
   carrying `content: ""`, plus float geometry on the children.

   The moment this stylesheet turns one of those containers into a grid or a
   flex container, both pseudo-elements stop being invisible table cells and
   become REAL ITEMS. A grid gives each one a cell. A flex row gives each one
   a share of the gap. Neither is visible on its own, so the symptom always
   shows up somewhere else: a column of cards starting a track late, a header
   row one gap adrift at each end, a product list wrapping a row early.

   This has been diagnosed five separate times in this theme. It is one fault,
   so it gets one register. Every Storefront container this stylesheet converts
   is listed below, and the list is the whole treatment for the clearfix half
   of the problem.

   THE RULE, for anyone converting another Storefront container later:
   if you write `display: grid` or `display: flex` on a selector that Storefront
   also styles, add that selector here in the same edit. If you do not, the two
   pseudo-elements become items and the layout goes wrong somewhere you are not
   looking.

   Sizing is not handled here. A percentage width on a grid item resolves
   against its own track rather than the row, and a float gutter margin is added
   on top of the gap, but the fix for that is specific to each container and
   lives with the container's own rules. Those are, today:
     .site-header > .col-full ....... .site-branding float and width reset
     .site-footer .footer-widgets ... .block float widths reset
     ul.products .................... li.product width and margin reset

   Containers deliberately NOT listed: .col-full outside the two rows named
   below, .main-navigation, and ul.cart_list. Storefront clearfixes all three,
   but this stylesheet converts a descendant of each rather than the container
   itself, so their pseudo-elements are still inside a block box and still
   harmless. Convert one of those containers directly and it joins the list.
   ====================================================================== */

.site-header > .col-full::before,
.site-header > .col-full::after,
.cf-search-overlay > .col-full::before,
.cf-search-overlay > .col-full::after,
.site-footer .footer-widgets::before,
.site-footer .footer-widgets::after,
ul.products::before,
ul.products::after { content: none; }

p { margin: 0 0 1.15em; }

a { color: var(--cf-link); text-decoration: none; }
a:hover { color: var(--cf-link-hover); text-decoration: underline; }

:focus-visible { outline: 2px solid var(--cf-focus); outline-offset: 3px; }

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

.screen-reader-text:focus {
	clip-path: none;
	height: auto;
	width: auto;
	padding: .6em 1em;
	background: #fff;
	color: var(--cf-indigo);
	z-index: 100;
}

.lede { font-size: 1.12rem; color: var(--cf-body); max-width: 34em; }
.muted { color: var(--cf-muted); }

/* --- The metadata voice ------------------------------------------------
   Mono is reserved for things that are literally data: platform, source
   store, destination marketplace, SKU, dates, counts. It never carries
   marketing copy. That rule is what keeps it from being decoration.
   ---------------------------------------------------------------------- */

.cf-eyebrow {
	display: flex;
	align-items: center;
	gap: .6rem;
	font-family: var(--cf-mono);
	font-size: .72rem;
	font-weight: 500;
	letter-spacing: .16em;
	text-transform: uppercase;
	color: var(--cf-indigo);
	margin: 0 0 .9rem;
}

.cf-eyebrow::before {
	content: "";
	width: 22px;
	height: 2px;
	background: var(--cf-indigo);
	flex: 0 0 22px;
}

.cf-meta {
	font-family: var(--cf-mono);
	font-size: .705rem;
	letter-spacing: .04em;
	color: var(--cf-muted);
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: .35rem;
	margin: 0 0 .5rem;
	text-transform: lowercase;
}

.cf-meta .sep { color: var(--cf-line-strong); }
.cf-meta .to { color: var(--cf-indigo); font-weight: 500; }

/* The single product caption follows the title instead of preceding it, so it
   needs a little air above where it previously needed none. The title carries
   its own bottom margin, so this is a nudge rather than a full gap. */
.cf-meta--caption { margin: .25rem 0 .9rem; }

/* --- Header ------------------------------------------------------------ */

.site-header {
	background: #fff;
	border-bottom: 1px solid var(--cf-line);
	position: relative;
}

.site-header__top {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 1rem;
	padding: 1.15rem 0;
}

.site-logo { display: inline-flex; align-items: center; }
.site-logo:hover { text-decoration: none; }

/* The logo is capped by height only and the width follows. Upload a file at
   three times this height and the browser draws it at full density on a
   retina screen. In the theme this cap becomes a Customizer control. */
.site-logo__img {
	height: 40px;
	width: auto;
	max-width: 100%;
	display: block;
}

.site-header__utility {
	display: flex;
	align-items: center;
	gap: 1.3rem;
	font-family: var(--cf-display);
	font-weight: 500;
	font-size: .92rem;
}

.site-header__utility a { color: var(--cf-ink); }

.cart-contents { display: inline-flex; align-items: center; gap: .45rem; }


/* Expands over the whole header rather than pushing the page down, so
   opening search never shifts what the visitor was already reading. */

/* The overlay is anchored to the header, not to the logo row.
 *
 * Whether that happens depends on which ancestor is positioned. If
 * Storefront gives .col-full a position of its own, the overlay silently
 * anchors to the logo row instead and its contents centre against the wrong
 * box. Forcing .col-full back to static removes that dependency, so the
 * anchor is decided here rather than by whichever stylesheet loads last. */

.site-header > .col-full { position: static; }

.cf-search-overlay {
	position: absolute;
	top: 0;
	left: 0;
	right: 0;
	bottom: 0;
	z-index: 20;
	background: rgba(15, 16, 41, .95);

	/* Block, and the choice matters more than it looks.
	 *
	 * As a grid container this had to hand its column a definite width, because
	 * a grid item with auto side margins is not stretched: the margins absorb
	 * the free space and the item shrinks to its contents. Storefront gives
	 * .col-full auto margins above its container width, so above that point the
	 * panel shrank and the margins centred what was left. Supplying the width
	 * meant restating Storefront's container width and column padding here, and
	 * a restated constant goes wrong quietly.
	 *
	 * In block flow none of that arises. Width auto fills the space, max-width
	 * caps it, auto margins centre the remainder, and every one of those values
	 * comes from Storefront's own .col-full rules. Change the container width
	 * anywhere and this panel follows it without being told. */
	display: block;
}

.cf-search-overlay[hidden] { display: none; }

/* No width, no max-width, no margin, and no breakpoint of its own. That is the
   whole point of this rule.
 *
   This is a .col-full and it has to measure exactly like the .col-full holding
   the logo, or the search text will not start where the logo starts. Every
   value needed to do that already lives in Storefront's own .col-full rules,
   including the breakpoint where it swaps auto side margins for fixed ones.
   Restating any of it here would mean this panel keeps the old geometry on the
   day the container width changes, and nothing would report the drift.
 *
   Measured against a container widened from 66.4989em to 80em: this rule
   followed to zero drift at 1300px, 1440px and 1920px. The version that
   restated the constants landed the search text 108px off the page content.
 *
   The two declarations below carry the vertical centring the grid used to do,
   which is the only thing block flow gives up. */
.cf-search-overlay > .col-full {
	height: 100%;
	display: flex;
	align-items: center;
}

/* This row's inherited clearfix is suppressed in the parent layout register
   near the top of this file. */

.cf-search-overlay__form {
	display: flex;
	align-items: center;
	gap: 1rem;
	width: 100%;
	max-width: 100%;
	/* Now a flex item of .col-full. Grows into the row, and may shrink below
	   the field's intrinsic width rather than forcing the column wider than
	   the space it has. */
	flex: 1 1 auto;
	min-width: 0;
	/* Storefront sets form{margin-bottom:1.618em}. Inside the panel that
	   26px sat below the field and nowhere above it, which is what pushed
	   the question off centre by exactly half of it. */
	margin: 0;
}

.cf-search-overlay__form input {
	flex: 1;
	min-width: 0;
	border: 0;
	background: transparent;
	color: #fff;
	font-family: var(--cf-display);
	font-weight: 400;
	font-size: 1.85rem;
	line-height: 1.2;
	padding: .3em 0;
}

.cf-search-overlay__form input::placeholder { color: rgba(255, 255, 255, .62); }
.cf-search-overlay__form input:focus { outline: 0; }
.cf-search-overlay__form input:focus-visible { outline: 0; }

.cf-search-close {
	flex: 0 0 auto;
	display: grid;
	place-items: center;
	width: 42px;
	height: 42px;
	padding: 0;
	border: 0;
	border-radius: 50%;
	background: transparent;
	color: #fff;
	cursor: pointer;
}

.cf-search-close:hover { background: rgba(255, 255, 255, .12); color: #fff; box-shadow: none; transform: none; }
.cf-search-close svg { width: 22px; height: 22px; stroke: currentColor; fill: none; stroke-width: 2; }

.cart-contents .count {
	background: var(--cf-indigo);
	color: #fff;
	border-radius: 999px;
	font-family: var(--cf-mono);
	font-size: .68rem;
	padding: .12em .5em;
}

.main-navigation { border-top: 1px solid var(--cf-line); }

.main-navigation ul {
	list-style: none; margin: 0; padding: 0;
	display: flex; flex-wrap: wrap; gap: 1.7rem;
}

.main-navigation a {
	display: block;
	font-family: var(--cf-display);
	font-weight: 500;
	font-size: .96rem;
	color: var(--cf-ink);
	padding: .85em 0;
	border-bottom: 2px solid transparent;
}

.main-navigation a:hover,
.main-navigation .current a {
	color: var(--cf-indigo);
	border-bottom-color: var(--cf-indigo);
	text-decoration: none;
}

.main-navigation .has-children > a::after {
	content: "";
	display: inline-block;
	margin-left: .4em;
	border: 4px solid transparent;
	border-top-color: currentColor;
	transform: translateY(2px);
}

/* --- Buttons ----------------------------------------------------------- */

.button {
	display: inline-block;
	font-family: var(--cf-display);
	font-weight: 600;
	font-size: .98rem;
	border: 0;
	border-radius: var(--cf-radius-sm);
	padding: .8em 1.5em;
	background: var(--cf-indigo);
	color: #fff;
	cursor: pointer;
	transition: background-color .14s ease, box-shadow .14s ease, transform .14s ease;
}

.button:hover {
	background: var(--cf-indigo-deep);
	color: #fff;
	text-decoration: none;
	transform: translateY(-1px);
	box-shadow: 0 6px 18px rgba(47,47,162,.2);
}

.button--outline {
	background: transparent;
	color: var(--cf-indigo);
	box-shadow: inset 0 0 0 1.5px var(--cf-line-strong);
}

.button--outline:hover {
	background: transparent;
	color: var(--cf-indigo-deep);
	box-shadow: inset 0 0 0 1.5px var(--cf-indigo);
}

.button--onDark {
	background: #fff;
	color: var(--cf-indigo-deep);
}

.button--onDark:hover { background: #fff; color: var(--cf-indigo-deep); }

.button--ghostOnDark {
	background: transparent;
	color: #fff;
	box-shadow: inset 0 0 0 1.5px rgba(255,255,255,.45);
}

.button--ghostOnDark:hover { background: transparent; color: #fff; box-shadow: inset 0 0 0 1.5px #fff; }

.button-row { display: flex; flex-wrap: wrap; gap: .7rem; }

/* --- Hero, with the mapping panel as the signature --------------------- */

/* The hero follows the store listing artwork: dark indigo field, headline
   with one accent line, platform pills, and the two app screens overlapping
   on the right, cropped by the bottom edge of the band. */

.cf-hero {
	background: linear-gradient(135deg, #14105c 0%, #241f8f 52%, #2f2fa2 100%);
	color: #fff;
	padding: 3.4rem 0 0;
	overflow: hidden;
}

.cf-hero__grid {
	display: grid;
	grid-template-columns: minmax(0, 1.04fr) minmax(0, .96fr);
	gap: 2.6rem;
	align-items: end;
}

.cf-hero__copy { padding-bottom: 3.8rem; }

.cf-hero h1 {
	color: #fff;
	font-size: 3.15rem;
	line-height: 1.04;
	margin-bottom: .34em;
}

.cf-hero h1 .accent { color: var(--cf-lilac); }

.cf-hero .cf-eyebrow { color: var(--cf-lilac); }
.cf-hero .cf-eyebrow::before { background: var(--cf-lilac); }

.cf-hero__rule {
	width: 86px;
	height: 3px;
	background: var(--cf-lilac);
	border: 0;
	margin: 0 0 1.3rem;
}

.cf-tagline {
	font-family: var(--cf-display);
	font-weight: 500;
	font-size: 1.42rem;
	line-height: 1.3;
	color: rgba(255, 255, 255, .9);
	margin: 0 0 1.4rem;
}

.cf-pills { display: flex; flex-wrap: wrap; gap: .55rem; margin: 0 0 1.7rem; }

.cf-pill {
	background: rgba(255, 255, 255, .13);
	color: #fff;
	border-radius: 999px;
	padding: .5em 1.15em;
	font-family: var(--cf-display);
	font-weight: 600;
	font-size: .95rem;
	white-space: nowrap;
}

.cf-hero__shots { position: relative; min-height: 452px; }

.cf-hero__shot {
	position: absolute;
	bottom: -54px;
	border-radius: 11px;
	border: 1px solid rgba(255, 255, 255, .18);
	box-shadow: 0 28px 70px rgba(0, 0, 0, .42);
	display: block;
	height: auto;
}

.cf-hero__shot--back { left: -4%; width: 62%; z-index: 1; }
.cf-hero__shot--front { right: -3%; width: 71%; z-index: 2; }

/* Light strip, used for the mapping explainer */

/* The tinted strip is a box, not a full bleed band: it sits inside .col-full
 * and its tint stops at the column edges. Two things followed from that and
 * both were wrong.
 *
 * It carried no horizontal padding, so its eyebrow, heading, paragraph and the
 * mapping panel all sat hard against the tint. Measured at 390: every one of
 * them inset 0px from the strip's own left and right edges.
 *
 * And it carried no top margin, so the space above it was borrowed from
 * whatever came before. That works when the preceding section is a
 * .cf-section and supplies 3.4rem of its own, and gives nothing at all when it
 * is a bare heading and a product list, which is what the home page actually
 * uses. The strip now states its own space. Sibling margins collapse, so a
 * .cf-section before it still yields one 3.4rem gap rather than two. */

.cf-strip {
	background: var(--cf-tint);
	border-top: 1px solid var(--cf-line);
	border-bottom: 1px solid var(--cf-line);
	padding: 3.2rem 2rem;
	margin: 3.4rem 0;
}

.cf-strip__grid {
	display: grid;
	grid-template-columns: minmax(0, 1fr) minmax(0, 1.05fr);
	gap: 2.8rem;
	align-items: center;
}

/* The mapping panel. This is the one element the page is built around:
   your category on the left, the marketplace category on the right, the
   arrow between them. It is the app's actual job, drawn literally. */

.cf-map {
	background: #fff;
	border: 1px solid var(--cf-line);
	border-radius: var(--cf-radius);
	box-shadow: var(--cf-shadow-lift);
	overflow: hidden;
}

.cf-map__head {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 1rem;
	padding: .8rem 1.1rem;
	border-bottom: 1px solid var(--cf-line);
	background: #fafafb;
}

.cf-map__title {
	font-family: var(--cf-display);
	font-weight: 600;
	font-size: .92rem;
	color: var(--cf-ink);
}

.cf-map__badge {
	font-family: var(--cf-mono);
	font-size: .68rem;
	letter-spacing: .08em;
	text-transform: uppercase;
	color: var(--cf-mapped);
	display: inline-flex;
	align-items: center;
	gap: .35rem;
}

.cf-map__badge::before {
	content: "";
	width: 7px; height: 7px;
	border-radius: 50%;
	background: var(--cf-mapped);
}

.cf-map__row {
	display: grid;
	grid-template-columns: minmax(0,1fr) 28px minmax(0,1.15fr);
	align-items: center;
	gap: .5rem;
	padding: .78rem 1.1rem;
	border-bottom: 1px solid var(--cf-line);
	font-size: .86rem;
}

.cf-map__row:last-child { border-bottom: 0; }

.cf-map__src { color: var(--cf-ink); font-weight: 500; }

.cf-map__dst {
	font-family: var(--cf-mono);
	font-size: .765rem;
	color: var(--cf-muted);
	line-height: 1.4;
	word-break: break-word;
}

.cf-map__arrow { display: grid; place-items: center; }

.cf-map__arrow svg { width: 18px; height: 18px; stroke: var(--cf-indigo); fill: none; stroke-width: 2; }

.cf-map__foot {
	padding: .7rem 1.1rem;
	background: #fafafb;
	border-top: 1px solid var(--cf-line);
	font-family: var(--cf-mono);
	font-size: .7rem;
	color: var(--cf-muted);
	letter-spacing: .04em;
	display: flex;
	justify-content: space-between;
	gap: 1rem;
	flex-wrap: wrap;
}

/* --- Sections ---------------------------------------------------------- */

.site-main { padding: 3rem 0; }

.cf-section { margin-bottom: 3.4rem; }
.cf-section:last-child { margin-bottom: 0; }

.cf-section__head {
	display: flex;
	align-items: flex-end;
	justify-content: space-between;
	gap: 1rem;
	flex-wrap: wrap;
	margin-bottom: 1.5rem;
}

.cf-section__head h2 { margin-bottom: 0; }

.cf-section__link { font-family: var(--cf-display); font-weight: 600; font-size: .92rem; }

/* On a phone the head stacks, always.

   Left to flex-wrap, where the link lands depends on how long the heading
   happens to be. "New licenses this month" is wide enough to push it onto its
   own line, while "What stores are buying" leaves just enough room for it to
   stay clinging to the right edge, so two instances of the same component read
   as two different layouts. Declaring the direction takes copy length, font
   metrics and translated strings out of the decision.

   align-items is restated because the base rule's flex-end means bottom in a
   row but right in a column, which would pin the link to the right edge again.
   ------------------------------------------------------------------------ */

@media (max-width: 767px) {
	.cf-section__head {
		flex-direction: column;
		align-items: flex-start;
	}
}

/* The one full-bleed indigo band on the page. Brand presence lives here so
   the hero does not have to be a gradient slab. */

.cf-band {
	background: var(--cf-indigo-deep);
	background-image: linear-gradient(135deg, #14105c 0%, #2f2fa2 100%);
	color: #fff;
	padding: 3.2rem 0;
	margin: 3.4rem 0 0;
}

.cf-band h2, .cf-band h3 { color: #fff; }
.cf-band p { color: rgba(255,255,255,.82); }
.cf-band .cf-eyebrow { color: var(--cf-lilac); }
.cf-band .cf-eyebrow::before { background: var(--cf-lilac); }

.cf-grid { display: grid; gap: 1.4rem; }
.cf-grid--2 { grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); }
.cf-grid--3 { grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); }
.cf-grid--4 { grid-template-columns: repeat(auto-fit, minmax(215px, 1fr)); }

.cf-card {
	background: #fff;
	border: 1px solid var(--cf-line);
	border-radius: var(--cf-radius);
	padding: 1.4rem;
	box-shadow: var(--cf-shadow);
}

.cf-card h3 { margin-top: 0; }
.cf-card p:last-child { margin-bottom: 0; }

.cf-band .cf-card {
	background: rgba(255,255,255,.07);
	border-color: rgba(255,255,255,.16);
	box-shadow: none;
}

/* Numbered steps. Numbers are used because install, buy, connect, export is
   a real sequence, not because numbers look tidy. */

.cf-steps { counter-reset: cfstep; }

.cf-steps .cf-card { position: relative; padding-top: 2.7rem; }

.cf-steps .cf-card::before {
	counter-increment: cfstep;
	content: counter(cfstep, decimal-leading-zero);
	position: absolute;
	top: 1.15rem; left: 1.4rem;
	font-family: var(--cf-mono);
	font-size: .78rem;
	font-weight: 500;
	letter-spacing: .1em;
	color: var(--cf-lilac);
}

/* --- Page wrapper ------------------------------------------------------- */

/* Storefront gives the page wrapper and the body overflow-x: hidden to stop
 * stray horizontal overflow from ever producing a sideways scrollbar. That is
 * the right intent with the wrong value. Any overflow other than visible or
 * clip turns an element into a scroll container, and the scroll-driven
 * animations further down resolve their view timelines against the nearest
 * scroll container: the wrapper, which never scrolls. Chrome then left every
 * card static and Safari held every card at its first keyframe, invisible and
 * to all appearances unclickable.
 *
 * clip does exactly the clipping hidden does without becoming a scroll
 * container, so the viewport is the scroll container again. hidden stays as
 * the fallback for anything old enough not to know clip. */
body,
.site {
	overflow-x: hidden;
	overflow-x: clip;
}

/* --- Page container ----------------------------------------------------- */

/* The design's container is 1180px wide including its own 1.4rem gutters, which
 * leaves 1135px for content. Storefront's is 1064px of content inside a
 * content-box, so every section on the page sat 36px further in on each side.
 *
 * Both halves have to be stated. Setting the width alone would land in the
 * wrong place while the box is still content-box, because the padding would be
 * added outside the max-width instead of taken out of it, giving a 1225px
 * container rather than the 1180px the design asks for.
 *
 * This is the one container the header, the content and the footer all share,
 * so changing it here keeps them in line with each other rather than pulling
 * one of them out. The narrower phone and tablet gutters set further down still
 * apply, since they come later in this file. */

.col-full {
	box-sizing: border-box;
	max-width: 1180px;
	margin-left: auto;
	margin-right: auto;
	padding: 0 1.4rem;
}

/* --- Product grid ------------------------------------------------------ */

ul.products {
	list-style: none;
	padding: 0;
	display: grid;
	/* min() keeps the track from insisting on 228px in a container narrower
	   than that, which would push the cards out past their column instead of
	   letting them shrink. Identical at every width where 228px fits. */
	grid-template-columns: repeat(auto-fill, minmax(min(228px, 100%), 1fr));
	gap: 1.4rem;
	/* The gap spaces the cards from each other. This margin is what separates
	   the list from whatever follows it, and the list has to state it because
	   nothing else will: the sections on the home page carry a bottom margin
	   but no top one, so each relies on its predecessor. Until 1.31.0 the space
	   came from the parent theme's per-card bottom margin, which was part of
	   its float row layout and was cleared with the rest of that geometry.
	   Clearing it was right; leaving nothing in its place was not.
	   Collapses against a .cf-section's own bottom margin when the list is
	   inside one, so it yields one gap rather than two. */
	margin: 0 0 3.4rem;
}

/* Storefront lays this same list out as floated blocks, and does it with four
 * things that all survive into a grid and damage it:
 *
 *   a clearfix on the list, whose two pseudo elements become real grid items
 *   and take a whole cell each;
 *   a percentage width on the card, picked by the columns-N class, which on a
 *   grid item resolves against that card's own track rather than the row, so
 *   the card shrinks to a fraction of the cell it was given;
 *   a percentage right margin serving as the float gutter;
 *   and a large bottom margin serving as the row gap.
 *
 * Measured at 1440 before this block existed: four tracks of 249px, cards
 * 55px wide, the first card pushed a full track to the right by ::before, the
 * fourth card wrapped to a second row by ::after, and the product title
 * breaking one letter per line.
 *
 * The width and the right margin come from selectors carrying five classes,
 * which nothing writable in a child stylesheet outranks. Matching them would
 * mean naming every wrapper the parent puts on the page and leaning on load
 * order to break the tie, and it would fail silently the first time the parent
 * adds another one. They are declared important instead, which states what is
 * actually true here: this list is a grid, and a grid sizes its own items. The
 * clearfix is a single class rule and is simply overridden. */

/* The clearfix half of this is suppressed in the parent layout register near
   the top of this file, with every other container this stylesheet converts.
   The sizing half stays here, because it is specific to this list. */

ul.products li.product {
	width: auto !important;
	margin: 0 !important;
}

/* Related and upsell lists are a fixed four across rather than however many
 * fit. The catalogue grid elsewhere is asked for a card width and left to
 * decide the count, which is right for a page of products and wrong for a
 * short row under one, where four cards on one line is the shape being asked
 * for. Two across on a phone, so the row stays a block of four rather than a
 * column of four. */

.related.products ul.products,
.up-sells ul.products {
	grid-template-columns: repeat(4, minmax(0, 1fr));
}

ul.products li.product {
	background: #fff;
	/* Storefront centres everything in the card. The design ranges the meta
	   line, the title and the price to the left; the add to cart button sets
	   its own centring further down and is unaffected. */
	text-align: left;
	border: 1px solid var(--cf-line);
	border-radius: var(--cf-radius);
	padding: .9rem .9rem 1.1rem;
	box-shadow: var(--cf-shadow);
	display: flex;
	flex-direction: column;
	transition: box-shadow .16s ease, translate .16s ease, border-color .16s ease;
}

/* The lift is written as translate rather than transform. The scroll-driven
   rise near the end of this file animates transform on these same cards, and
   an animation owns whatever it animates, outranking every normal rule
   including :hover. translate is a separate property that composes with
   transform, so the rise and the lift no longer compete for one slot. */
ul.products li.product:hover,
ul.products li.product:focus-within {
	box-shadow: var(--cf-shadow-lift);
	border-color: var(--cf-line-strong);
	translate: 0 -2px;
}

/* The card link inherits the card's text colour, but the rule must be scoped
   to the link class. A bare "li.product > a" also matches the add-to-cart
   button and quietly turns its white label dark. */
ul.products li.product a.woocommerce-LoopProduct-link {
	display: flex;
	flex-direction: column;
	flex: 1;
	color: inherit;
}

ul.products li.product a.woocommerce-LoopProduct-link:hover { text-decoration: none; }

.cf-thumb {
	border-radius: var(--cf-radius-sm);
	background: var(--cf-tint);
	border: 1px solid var(--cf-line);
	margin-bottom: .8rem;
	aspect-ratio: 1 / 1;
	display: grid;
	place-items: center;
	overflow: hidden;
}

.cf-thumb img,
.cf-thumb svg {
	width: 100%;
	height: 100%;
	object-fit: cover;
	display: block;
}

.cf-thumb--wide { aspect-ratio: 4 / 3; }

/* Storefront states font-weight: 400 and its own bottom margin for this title
 * from a selector carrying three classes and two elements, which a bare class
 * cannot reach. The second selector below matches its weight exactly and wins
 * on load order. */
.woocommerce-loop-product__title,
ul.products li.product .woocommerce-loop-product__title {
	/* Product names here carry long unbreakable runs like
	   (iOS/macOS/visionOS), which have no break opportunity in them and hang
	   out of a narrow card. anywhere breaks such a run only when it will not
	   otherwise fit, so ordinary titles still wrap between words. */
	overflow-wrap: anywhere;
	font-family: var(--cf-display);
	font-size: 1rem;
	font-weight: 600;
	line-height: 1.32;
	color: var(--cf-ink);
	letter-spacing: -.01em;
	margin: 0 0 .45rem;
}

.star-rating {
	font-size: .8rem;
	letter-spacing: .08em;
	color: var(--cf-indigo);
	margin: 0 0 .55rem;
}

.star-rating .off { color: var(--cf-line-strong); }
.star-rating .count { font-family: var(--cf-mono); font-size: .68rem; color: var(--cf-muted); margin-left: .35rem; letter-spacing: .04em; }

ul.products li.product .cf-price-row {
	display: flex;
	align-items: center;
	justify-content: space-between;
	/* The term chip cannot be broken and the price will not shrink, so in a
	   narrow card the two together are wider than the row. Letting the row wrap
	   drops the chip under the price instead of pushing it past the card edge. */
	flex-wrap: wrap;
	gap: .6rem;
	margin-top: auto;
	padding-top: .5rem;
}

ul.products li.product .price {
	display: block;
	font-family: var(--cf-display);
	font-size: 1.14rem;
	font-weight: 700;
	color: var(--cf-ink);
}

/* The billing period inside a price, from either source: .term is the theme's
   own, .wps_sfw_interval is the one Subscriptions For WooCommerce appends. Both
   inherit the price outright so "$19.99 / Month" reads as one figure, which is
   how www has always shown it. The earlier treatment here set mono at .74rem
   and --cf-muted, which made the period look like a footnote on the price
   rather than part of it. */
.price .term,
.price .wps_sfw_interval,
.woocommerce div.product p.price .wps_sfw_interval {
	font: inherit;
	color: inherit;
	letter-spacing: inherit;
	white-space: nowrap;
}

ul.products li.product a.button {
	margin-top: .8rem;
	width: 100%;
	text-align: center;
	color: #fff;
}

ul.products li.product a.button:hover { color: #fff; }

.cf-chip {
	display: inline-flex;
	align-items: center;
	font-family: var(--cf-mono);
	font-size: .66rem;
	font-weight: 500;
	letter-spacing: .1em;
	text-transform: uppercase;
	padding: .26em .62em;
	border-radius: 4px;
	background: var(--cf-tint);
	color: var(--cf-indigo);
	border: 1px solid var(--cf-line);
	white-space: nowrap;
}

.cf-chip--lifetime { background: var(--cf-indigo); color: #fff; border-color: var(--cf-indigo); }

.cf-chip-row { display: flex; gap: .35rem; flex-wrap: wrap; margin: 0 0 .5rem; }

/* --- Shop toolbar, breadcrumbs, pagination ----------------------------- */

.cf-breadcrumb {
	font-family: var(--cf-mono);
	font-size: .72rem;
	letter-spacing: .04em;
	color: var(--cf-muted);
	padding: 1.1rem 0 0;
}


/* The block every page heading is printed into, whether the page was hand
   built or not. The rule underneath is what makes an ordinary page read
   like the ones that were designed. */
.cf-page-head { padding: var(--cf-head-pad-top) 0 1.6rem; border-bottom: 1px solid var(--cf-line); margin-bottom: 2rem; }

/* The same padding again, at a weight that survives Cart, Checkout and Account.

   The theme's head carries entry-header as well as cf-page-head, which invites
   Storefront's rules for that class. One of them is

     .storefront-full-width-content.woocommerce-cart .entry-header,
     .storefront-full-width-content.woocommerce-checkout .entry-header,
     .storefront-full-width-content.woocommerce-account .entry-header
       { padding: 0 0 5.9968353111em; }

   Three classes against the one above, so on those three pages the top padding
   went to zero and the eyebrow sat 19px higher than everywhere else, with about
   96px of dead space hung underneath it.

   .hentry is what makes this three classes as well. The head is always printed
   inside the article, so it is a fact about the markup rather than a selector
   picked for its weight, and it does not name the three pages, which means a
   fourth one added by Storefront is covered too. */
.hentry .cf-page-head.entry-header {
	padding: var(--cf-head-pad-top) 0 1.6rem;
}


.cf-page-head .cf-eyebrow { margin-bottom: .75rem; }
.cf-page-head h1 { margin-bottom: .25em; }
.cf-page-head p { margin-bottom: 0; max-width: 46em; }
/* --- Product archive head and sorting row ------------------------------- */

/* Storefront centres the products header and hangs 74px of padding under it.
 * The heading is left aligned everywhere else on this site, and that padding
 * is the gap between the title and the sorting row.
 *
 * It states this from .storefront-full-width-content .woocommerce-products-header,
 * inside a desktop media query. This theme removes the sidebar, so that class
 * is on every page and a bare selector here loses on specificity: the first
 * attempt at this changed nothing at all. Both forms are written out, the same
 * way the product tabs had to be. */
.woocommerce-products-header,
.storefront-full-width-content .woocommerce-products-header {
	text-align: left;
	padding-bottom: 0;
}

/* No rule under a product archive heading. The line belongs to a page head
   that introduces a body of text; here the next thing is a grid of cards,
   which has its own edges. */
.woocommerce-products-header .cf-page-head,
.storefront-full-width-content .woocommerce-products-header .cf-page-head {
	border-bottom: 0;
	padding-bottom: 0;
	margin-bottom: 1.4rem;
}

/* The heading block inside the header carries the same reset, since the
   parent's rule reaches h1 through the header it centres. */

/* The count and the select were both floated with matching padding, which
   lines up their boxes and not what is inside them: a 12px mono line and a
   38px control sit at different heights whatever the padding says. A flex row
   aligns them on their centres, which is what the eye reads. */
/* One rule for every width. There was a phone override here that pushed the
   row left and gave each item its own line; it was wrong on both counts, and
   removing it leaves the pair sitting together at the right edge whatever the
   viewport, wrapping only when there is genuinely no room.

   Qualified with .woocommerce because Storefront re-declares this row inside a
   min-width media query with a clearfix and a float on the count, and an
   unqualified single class was losing to it at some widths. */
.woocommerce .storefront-sorting,
.woocommerce-page .storefront-sorting,
.storefront-sorting {
	display: flex;
	align-items: center;
	justify-content: flex-end;
	gap: 1rem;
	flex-wrap: wrap;
	text-align: right;
}

.storefront-sorting::before,
.storefront-sorting::after { content: none; }

.woocommerce .storefront-sorting .woocommerce-result-count,
.woocommerce .storefront-sorting .woocommerce-ordering,
.storefront-sorting .woocommerce-result-count,
.storefront-sorting .woocommerce-ordering {
	float: none;
	margin: 0;
	padding: 0;
	width: auto;
}

/* Storefront also drops pagination into this row on some archives. With the
   row now aligned right, the auto margin that used to push it there would
   instead push it away from the other two, so it simply joins them. */
.storefront-sorting .woocommerce-pagination {
	float: none;
	margin: 0;
}

.cf-termbar { display: flex; flex-wrap: wrap; gap: .5rem; margin: 0 0 1.6rem; }

.cf-termbar a {
	font-family: var(--cf-display);
	font-weight: 500;
	font-size: .9rem;
	padding: .45em 1em;
	border-radius: 999px;
	border: 1px solid var(--cf-line);
	color: var(--cf-body);
	background: #fff;
}

.cf-termbar a:hover { border-color: var(--cf-indigo); color: var(--cf-indigo); text-decoration: none; }
.cf-termbar a.is-active { background: var(--cf-indigo); border-color: var(--cf-indigo); color: #fff; }

.cf-toolbar {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 1rem;
	flex-wrap: wrap;
	padding: 0 0 1.2rem;
	margin-bottom: 1.6rem;
	border-bottom: 1px solid var(--cf-line);
}

.woocommerce-result-count { font-family: var(--cf-mono); font-size: .74rem; color: var(--cf-muted); letter-spacing: .04em; margin: 0; }

.woocommerce-ordering select {
	font-family: var(--cf-text);
	font-size: .9rem;
	color: var(--cf-ink);
	padding: .5em 2em .5em .8em;
	border: 1px solid var(--cf-line);
	border-radius: var(--cf-radius-sm);
	background: #fff;
	appearance: none;
	background-image: linear-gradient(45deg, transparent 50%, var(--cf-muted) 50%), linear-gradient(135deg, var(--cf-muted) 50%, transparent 50%);
	background-position: calc(100% - 15px) center, calc(100% - 10px) center;
	background-size: 5px 5px, 5px 5px;
	background-repeat: no-repeat;
}

.cf-pagination { display: flex; gap: .4rem; justify-content: center; margin-top: 2.4rem; }

.cf-pagination a, .cf-pagination span {
	font-family: var(--cf-mono);
	font-size: .82rem;
	min-width: 38px;
	height: 38px;
	display: grid;
	place-items: center;
	border-radius: var(--cf-radius-sm);
	border: 1px solid var(--cf-line);
	color: var(--cf-body);
	padding: 0 .6rem;
}

.cf-pagination .current { background: var(--cf-indigo); border-color: var(--cf-indigo); color: #fff; }
.cf-pagination a:hover { border-color: var(--cf-indigo); color: var(--cf-indigo); text-decoration: none; }

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

.cf-product { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 3rem; align-items: start; }

.cf-gallery .cf-thumb { aspect-ratio: 1 / 1; margin-bottom: .8rem; }

.cf-gallery__strip { display: grid; grid-template-columns: repeat(4, 1fr); gap: .6rem; }
.cf-gallery__strip .cf-thumb { aspect-ratio: 1 / 1; margin: 0; }

.summary h1 { font-size: 2.15rem; margin-bottom: .3em; }

.summary .price {
	font-family: var(--cf-display);
	font-size: 2rem;
	font-weight: 700;
	color: var(--cf-ink);
	display: block;
	margin: .5rem 0 1rem;
}

.cf-stock {
	font-family: var(--cf-mono);
	font-size: .74rem;
	letter-spacing: .06em;
	text-transform: uppercase;
	color: var(--cf-mapped);
	display: inline-flex;
	align-items: center;
	gap: .4rem;
	margin-bottom: 1rem;
}

.cf-stock::before { content: ""; width: 7px; height: 7px; border-radius: 50%; background: var(--cf-mapped); }

.cf-cart-row { display: flex; gap: .7rem; align-items: stretch; margin: 1.2rem 0; }

.cf-qty {
	width: 84px;
	border: 1px solid var(--cf-line);
	border-radius: var(--cf-radius-sm);
	padding: .7em .8em;
	font-family: var(--cf-mono);
	font-size: .95rem;
	color: var(--cf-ink);
}

.cf-cart-row .button { flex: 1; font-size: 1.02rem; }

.cf-assurance {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(185px, 1fr));
	gap: .8rem;
	margin: 1.5rem 0;
	padding: 1.1rem;
	background: var(--cf-tint);
	border: 1px solid var(--cf-line);
	border-radius: var(--cf-radius);
}

.cf-assurance__item { display: flex; gap: .6rem; align-items: flex-start; font-size: .86rem; line-height: 1.4; }

.cf-assurance__item svg { flex: 0 0 20px; width: 20px; height: 20px; stroke: var(--cf-indigo); fill: none; stroke-width: 1.8; margin-top: .15em; }

.cf-assurance__item strong { display: block; font-family: var(--cf-display); font-weight: 600; color: var(--cf-ink); font-size: .9rem; }
.cf-assurance__item span { color: var(--cf-muted); }

/* Inside the narrow product summary the assurance block reads better as a
   stacked list than as a ragged two-column grid. */
.summary .cf-assurance { grid-template-columns: 1fr; }

.cf-spec {
	border-top: 1px solid var(--cf-line);
	margin-top: 1.4rem;
	padding-top: 1rem;
}

.cf-spec dl { display: grid; grid-template-columns: 130px minmax(0,1fr); gap: .45rem 1rem; margin: 0; font-size: .87rem; }
.cf-spec dt { font-family: var(--cf-mono); font-size: .72rem; letter-spacing: .08em; text-transform: uppercase; color: var(--cf-muted); padding-top: .18em; }
.cf-spec dd { margin: 0; color: var(--cf-ink); }

/* Tabs */

/* Storefront lays this section out as a left rail: the tab list floated into
 * span(3 of 9) and the panel floated beside it into span(last 6 of 9), which
 * resolve to 29.4118% and 64.7059% against its 12 column, gutters-of-1 grid.
 * That is a deliberate parent design and it is not this one. The list here is
 * a row across the full width with the panel below it.
 *
 * Measured before this block, at 1440: the list came out 313px wide and wrapped
 * five tabs onto three lines, the panel sat beside it starting at 376px, and
 * 93px of empty space opened above the row, being this file's 3.2rem margin
 * plus the parent's own ms(5) padding stacked on top of each other.
 *
 * None of it needs important. Every parent rule involved carries at most two
 * classes and two elements, the same as the selectors below, and this
 * stylesheet is enqueued after the parent's, so the ties fall this way. */

.woocommerce-tabs {
	margin-top: 3.2rem;
	/* The space above the row is this margin and nothing else. */
	padding-top: 0;
	padding-bottom: 0;
}

.woocommerce-tabs ul.tabs,
.storefront-full-width-content .woocommerce-tabs ul.tabs {
	list-style: none;
	margin: 0 0 1.8rem;
	padding: 0;
	display: flex;
	gap: 1.6rem;
	flex-wrap: wrap;
	/* Taken back from the parent's float rail. */
	width: 100%;
	float: none;
	margin-right: 0;
	/* The parent rules the list off at the top, which reads as a divider above
	   a vertical rail and as a stray line above a row. The underline below the
	   row is the one that carries meaning here. */
	border-top: 0;
	border-bottom: 1px solid var(--cf-line);
}

.woocommerce-tabs .panel,
.storefront-full-width-content .woocommerce-tabs .panel {
	width: 100%;
	float: none;
	margin-right: 0;
}

/* The second selector in each pair above is not decoration. The parent states
 * this layout twice: once bare, and once behind .storefront-full-width-content,
 * which it puts on the body of any page with no sidebar. This theme removes the
 * sidebar, so that class is present on every product page and the heavier of
 * the two rules was the one winning. The bare selector alone tied with the
 * wrong one. */

.woocommerce-tabs ul.tabs a {
	display: block;
	font-family: var(--cf-display);
	font-weight: 600;
	font-size: .96rem;
	color: var(--cf-muted);
	padding: .7em 0;
	border-bottom: 3px solid transparent;
}

.woocommerce-tabs ul.tabs li.active a,
.woocommerce-tabs ul.tabs a:hover { color: var(--cf-indigo); border-bottom-color: var(--cf-indigo); text-decoration: none; }

.cf-tab-panel { max-width: 52em; }
.cf-tab-panel h3 { margin-top: 1.6em; }
.cf-tab-panel h3:first-child { margin-top: 0; }
.cf-tab-source { font-family: var(--cf-mono); font-size: .74rem; letter-spacing: .03em; }

/* --- Pricing ----------------------------------------------------------- */

/* Term switch. Two named choices, so both labels are clickable targets and
   the control reports its state rather than relying on the knob position
   alone. Without JavaScript both price groups render stacked under their
   own headings, which is why the groups are visible by default and the
   script hides one rather than revealing one. */

.cf-termswitch {
	display: flex;
	align-items: center;
	justify-content: center;
	gap: 1rem;
	margin: 0 0 2.6rem;
}

.cf-termswitch[hidden] { display: none; }

.cf-termswitch__label {
	font-family: var(--cf-display);
	font-weight: 600;
	font-size: 1.05rem;
	color: var(--cf-muted);
	background: none;
	border: 0;
	padding: .3em .2em;
	cursor: pointer;
}

.cf-termswitch__label:hover { color: var(--cf-indigo); background: none; box-shadow: none; transform: none; }
.cf-termswitch__label.is-on { color: var(--cf-ink); }

.cf-switch {
	position: relative;
	flex: 0 0 auto;
	width: 66px;
	height: 34px;
	border-radius: 999px;
	border: 1px solid var(--cf-line-strong);
	background: #fff;
	padding: 0;
	cursor: pointer;
	transition: background-color .16s ease, border-color .16s ease;
}

.cf-switch:hover { box-shadow: none; transform: none; background: #fff; }
.cf-switch[aria-checked="true"] { background: var(--cf-indigo); border-color: var(--cf-indigo); }
.cf-switch[aria-checked="true"]:hover { background: var(--cf-indigo); }

.cf-switch__knob {
	position: absolute;
	top: 3px;
	left: 3px;
	width: 26px;
	height: 26px;
	border-radius: 50%;
	background: var(--cf-indigo);
	box-shadow: 0 1px 3px rgba(15, 16, 41, .3);
	transition: transform .16s ease, background-color .16s ease;
}

.cf-switch[aria-checked="true"] .cf-switch__knob { transform: translateX(32px); background: #fff; }

.cf-plans[hidden] { display: none; }
.cf-plans__heading { text-align: center; }
.is-enhanced .cf-plans__heading { display: none; }

.cf-plan {
	background: #fff;
	border: 1px solid var(--cf-line);
	border-radius: var(--cf-radius);
	padding: 2rem 1.7rem;
	display: flex;
	flex-direction: column;
	box-shadow: var(--cf-shadow);
}

.cf-plan--featured { border-color: var(--cf-indigo); box-shadow: var(--cf-shadow-lift); }

.cf-plan h3 {
	margin: 0 0 .1em;
	font-size: 2rem;
	font-weight: 700;
	letter-spacing: -.03em;
}

.cf-plan__sub { color: var(--cf-muted); font-size: .96rem; margin: 0; min-height: 2.9em; }

.cf-plan__price { font-family: var(--cf-display); font-size: 3.1rem; font-weight: 700; color: var(--cf-ink); line-height: 1.02; margin: 1rem 0 .1rem; letter-spacing: -.035em; }

.cf-plan__term { font-family: var(--cf-mono); font-size: .8rem; letter-spacing: .04em; color: var(--cf-muted); margin: 0 0 1.4rem; }

.cf-plan ul { list-style: none; margin: 0 0 1.4rem; padding: 0; }

.cf-plan li { position: relative; padding: .52em 0 .52em 1.6rem; border-bottom: 1px solid var(--cf-line); font-size: .98rem; }
.cf-plan li:last-child { border-bottom: 0; }

.cf-plan li::before {
	content: "";
	position: absolute;
	left: 0; top: .8em;
	width: 9px; height: 5px;
	border-left: 2px solid var(--cf-indigo);
	border-bottom: 2px solid var(--cf-indigo);
	transform: rotate(-45deg);
}

.cf-plan .button { margin-top: auto; text-align: center; width: 100%; padding: .95em 1.5em; font-size: 1.02rem; }

/* --- Blog -------------------------------------------------------------- */

.cf-layout { display: grid; grid-template-columns: minmax(0, 1fr) 280px; gap: 3rem; align-items: start; }

/* The post card is for blog listings and single posts only.
 *
 * WordPress puts the .hentry class on pages as well as posts, so an unscoped
 * rule wrapped every page in a card. That is what put a white panel around
 * Services and Pricing, and its 24px padding is what pushed the page content
 * out of line with the breadcrumb sitting outside it. */

.blog .hentry,
.archive .hentry,
.search .hentry,
.single-post .hentry {
	background: #fff;
	border: 1px solid var(--cf-line);
	border-radius: var(--cf-radius);
	padding: 1.5rem;
	margin-bottom: 1.4rem;
	box-shadow: var(--cf-shadow);
}

/* Pages carry no card, so their content lines up with the breadcrumb. */
.page .hentry,
.page article.hentry {
	background: none;
	border: 0;
	border-radius: 0;
	padding: 0;
	box-shadow: none;
	margin-bottom: 0;
}

.hentry--media {
	display: grid;
	grid-template-columns: 240px minmax(0, 1fr);
	gap: 1.4rem;
	align-items: center;
	padding: 1.1rem;
}

.hentry__media {
	display: block;
	border-radius: var(--cf-radius-sm);
	overflow: hidden;
	border: 1px solid var(--cf-line);
	background: var(--cf-tint);
}

.hentry__media img { width: 100%; height: auto; display: block; }

.hentry__body p:last-child { margin-bottom: 0; }

.cf-post-media {
	border-radius: var(--cf-radius-sm);
	overflow: hidden;
	border: 1px solid var(--cf-line);
	margin: 1.2rem 0 1.8rem;
}

.cf-post-media img { width: 100%; height: auto; display: block; }

.hentry h2 { font-size: 1.4rem; margin-bottom: .35em; }
.hentry h2 a { color: var(--cf-ink); }
.hentry h2 a:hover { color: var(--cf-indigo); text-decoration: none; }

.entry-meta {
	font-family: var(--cf-mono);
	font-size: .715rem;
	letter-spacing: .05em;
	color: var(--cf-muted);
	margin: 0 0 .7rem;
	text-transform: lowercase;
}

.entry-meta .sep { color: var(--cf-line-strong); margin: 0 .35rem; }

.entry-content { font-size: 1.04rem; line-height: 1.72; }
.entry-content h2 { font-size: 1.5rem; margin-top: 1.8em; }
.entry-content h3 { margin-top: 1.6em; }
/* The indent exists so bullet markers have somewhere to sit. Lists this
 * stylesheet takes over as components set list-style: none, have no markers,
 * and state their own padding, but they state it in a selector of the same
 * weight as this one and earlier in the file, so this rule was quietly winning
 * and pushing them off centre. It cost the product grid 19.2px on its left and
 * nothing on its right, which is the uneven margin visible on every section
 * that lists products, and it did the same to the plan feature lists.
 *
 * The negation is wrapped in :where() so it carries no weight of its own. That
 * matters: :not(.products) alone would lift this selector above .cf-plan ul and
 * break that list in the act of fixing this one.
 *
 * Add a component list here when you add one. WPForms builds its checkbox
 * and radio groups as lists, which is why the contact form checkbox sat
 * indented from its own label. */
.entry-content ul:not(:where(.products, .cf-plan ul, .wpforms-container ul)),
.entry-content ol {
	/* Storefront sets "ul, ol { margin: 0 0 ms(2) 3em }", so on top of the
	   padding below there was a 3em margin as well, putting the words of a
	   bullet 82px right of the paragraph above on a desktop and 70px on a
	   phone. A list belongs to the sentence around it. The whole indent is the
	   padding now, which is also where the marker sits. */
	margin-left: 0;
	padding-left: 1.2rem;
}
.entry-content li { margin-bottom: .4em; }

.entry-content blockquote {
	margin: 1.8em 0;
	padding: .2em 0 .2em 1.4rem;
	border-left: 3px solid var(--cf-indigo);
	color: var(--cf-ink);
	font-size: 1.1rem;
}

.entry-content code {
	font-family: var(--cf-mono);
	font-size: .86em;
	background: var(--cf-tint);
	border: 1px solid var(--cf-line);
	border-radius: 4px;
	padding: .1em .38em;
}

.widget { margin-bottom: 2rem; }

.widget-title {
	font-family: var(--cf-mono);
	font-size: .72rem;
	font-weight: 500;
	letter-spacing: .16em;
	text-transform: uppercase;
	color: var(--cf-muted);
	margin: 0 0 .9rem;
	padding-bottom: .6rem;
	border-bottom: 1px solid var(--cf-line);
}

.widget ul { list-style: none; margin: 0; padding: 0; }
.widget li { padding: .38em 0; border-bottom: 1px solid var(--cf-line); font-size: .93rem; }
.widget li:last-child { border-bottom: 0; }

.search-field {
	width: 100%;
	border: 1px solid var(--cf-line);
	border-radius: var(--cf-radius-sm);
	padding: .7em .9em;
	font-family: var(--cf-text);
	font-size: .95rem;
}

/* --- Services ---------------------------------------------------------- */

.cf-service {
	display: grid;
	grid-template-columns: 260px minmax(0, 1fr);
	gap: 2rem;
	align-items: center;
	padding: 1.8rem 0;
	border-bottom: 1px solid var(--cf-line);
}

.cf-service:last-child { border-bottom: 0; }
.cf-service h2 { font-size: 1.5rem; }
.cf-service .cf-thumb { aspect-ratio: 4 / 3; margin: 0; }

/* --- App store badges -------------------------------------------------- */

.cf-badges { margin: 0; }
.cf-badges--center { text-align: center; }
.cf-badges--left { text-align: left; }

.cf-badges__heading {
	font-family: var(--cf-display);
	font-weight: 600;
	font-size: 1.05rem;
	color: var(--cf-ink);
	margin: 0 0 .7rem;
}

.cf-badges__heading:not(:first-child) { margin-top: 1.5rem; }

.cf-badges__row {
	display: flex;
	flex-wrap: wrap;
	gap: .75rem;
	align-items: center;
}

.cf-badges--center .cf-badges__row { justify-content: center; }

.cf-badge { display: inline-block; line-height: 0; }
.cf-badge:hover { opacity: .85; text-decoration: none; }

/* The official artwork carries its own colour and clear space, so it is
   never recoloured or given a border. The height is set and the width
   follows; without an explicit height, width:auto falls back to each
   badge's intrinsic size and the three stop matching. */
.cf-badge img {
	display: block;
	height: 44px;
	width: auto;
}

/* On the dark band the black Apple and Microsoft badges need a light plate,
   the same trick the footer logo uses. */
.cf-band .cf-badges__heading { color: #fff; }
.cf-band .cf-badge {
	background: #fff;
	border-radius: 8px;
	padding: .35rem .5rem;
}

/* --- Footer ------------------------------------------------------------ */

.site-footer { background: var(--cf-ink); color: #b9bcd4; padding: 3rem 0 1.5rem; }

.footer-widgets { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 2rem; }

.site-footer .widget-title { color: #fff; border-bottom-color: rgba(255,255,255,.14); }
.site-footer li { border-bottom-color: rgba(255,255,255,.08); }
.site-footer a { color: #fff; }
.site-footer a:hover { color: #fff; }

.site-info {
	border-top: 1px solid rgba(255,255,255,.12);
	margin-top: 2.2rem;
	padding-top: 1.3rem;
	font-family: var(--cf-mono);
	font-size: .74rem;
	letter-spacing: .04em;
	display: flex;
	justify-content: space-between;
	gap: 1rem;
	flex-wrap: wrap;
}

/* --- Responsive -------------------------------------------------------- */

@media (max-width: 980px) {
	.cf-hero__grid { grid-template-columns: 1fr; gap: 1.6rem; }
	.cf-hero__copy { padding-bottom: 0; }
	.cf-hero h1 { font-size: 2.5rem; }
	/* Absolute positioning leaves a dead band of colour once the column is
	   full width, so the screen flows normally and keeps only its crop. */
	.cf-hero__shots { min-height: 0; display: flex; justify-content: center; }
	.cf-hero__shot { position: static; transform: none; width: 78%; max-width: 330px; margin-bottom: -44px; }
	.cf-hero__shot--back { display: none; }
	.cf-strip__grid { grid-template-columns: 1fr; gap: 1.8rem; }
	.cf-plan h3 { font-size: 1.7rem; }
	.cf-plan__price { font-size: 2.6rem; }
	.cf-product { grid-template-columns: 1fr; gap: 2rem; }
	.cf-layout { grid-template-columns: 1fr; gap: 2.4rem; }
	.cf-service { grid-template-columns: 1fr; gap: 1.2rem; }
	.hentry--media { grid-template-columns: 1fr; gap: 1rem; }
	.cf-service .cf-thumb { max-width: 320px; }
}

@media (max-width: 640px) {
	h1 { font-size: 2.05rem; }
	h2 { font-size: 1.5rem; }
	.cf-hero { padding: 2.4rem 0 0; }
	.cf-hero h1 { font-size: 2.1rem; }
	.cf-tagline { font-size: 1.15rem; }
	.cf-search-overlay__form input { font-size: 1.3rem; }
	.cf-search-overlay__form { gap: .5rem; }
	.site-main { padding: 2rem 0; }
	.main-navigation ul { gap: 1.1rem; }
	.main-navigation a { font-size: .9rem; }
	.site-header__utility { gap: .9rem; font-size: .85rem; }
	.cf-map__row { grid-template-columns: minmax(0,1fr) 22px minmax(0,1fr); font-size: .8rem; }
	.cf-spec dl { grid-template-columns: 1fr; gap: .1rem .5rem; }
	.cf-spec dd { margin-bottom: .6rem; }
}

@media (prefers-reduced-motion: reduce) {
	*, *::before, *::after { transition-duration: .001ms !important; animation-duration: .001ms !important; }

	/* Zeroing the duration alone is not enough for a staggered list: the
	   delays would survive and the last item would still arrive a third of a
	   second late, with no animation to explain the wait. */
	*, *::before, *::after { animation-delay: 0s !important; transition-delay: 0s !important; }

	.main-navigation.toggled .handheld-navigation::before { display: none; }
	.button:hover,
	ul.products li.product:hover,
	ul.products li.product:focus-within,
	.cf-post-card:hover,
	.cf-post-card:focus-within,
	.cf-keep__card:hover,
	.cf-keep__card:focus-within { transform: none; translate: none; }
}


/* =========================================================================
   Storefront integration
   Selectors that exist only because of the parent theme's markup.
   ====================================================================== */

/* Storefront lays the header out with floats across two containers. The cart
   is re-hooked into the upper container in inc/setup.php so the logo row
   carries logo, search, account and cart, and the lower row carries the menu.
   These rules make that upper row behave. */

.site-header {
	position: relative;
	padding-top: 0;
	padding-bottom: 0;
	border-bottom: 1px solid var(--cf-line);
}

/* Storefront's header rhythm is replaced wholesale rather than adjusted, so
   the override is marked important deliberately. Two previous attempts to win
   this on specificity alone did not hold, and a band of dead white under the
   menu is worse than one flagged declaration. */
.site-header,
.woocommerce-active .site-header,
body .site-header {
	margin-bottom: 0 !important;
	padding-bottom: 0 !important;
}

.storefront-primary-navigation { margin-bottom: 0 !important; }

/* Nothing between the header and the hero may add its own top margin. */
.site-header + .cf-hero,
.site-header + * { margin-top: 0 !important; }

/* Vertical rhythm above the content.
 *
 * Storefront fires storefront_before_content outside #content, and hangs the
 * header widget region and the WooCommerce breadcrumb off it, each carrying
 * roughly 4.2em of its own margin. Stacked with the header's bottom margin
 * that is three separate gaps between the menu and the first real content.
 * All three are neutralised here and the spacing is set once, deliberately. */

.header-widget-region { margin: 0; padding: 0; }
.header-widget-region:empty { display: none; }

/* The breadcrumb now sits inside #content .col-full, the same container as
   the page content, so its left edge matches without any calculation. */

/* One breadcrumb, one rule set.

   The theme drew its own .cf-crumbs trail on posts and archives at .72rem with
   indigo links, while this one was .74rem with muted links. Same element, two
   treatments, and which you saw depended on the page. The hand drawn trails
   are gone, so this takes over what they had. */
.woocommerce-breadcrumb,
nav.woocommerce-breadcrumb,
.site-content .woocommerce-breadcrumb {
	margin: var(--cf-crumb-gap) 0 var(--cf-crumb-below);
	padding: 0;
	font-family: var(--cf-mono);
	font-size: .72rem;
	letter-spacing: .06em;
	color: var(--cf-muted);
	text-align: left;
	text-indent: 0;
}

/* The separator is drawn in the same colour as the crumbs either side of it.

   It was --cf-line-strong, #d2d1d8, 1.52:1 on white: the right value for a
   hairline and the wrong one for a character someone has to read. Inheriting
   the nav colour fixed the contrast but not the mismatch, because the crumbs
   are links and the nav is not.

   What is actually on screen here is not the slash this theme emits. Storefront
   pushes .breadcrumb-separator off with text-indent: -9999px and draws a Font
   Awesome chevron in an ::after, which takes its colour from this rule. */
nav.woocommerce-breadcrumb .breadcrumb-separator,
nav.woocommerce-breadcrumb .breadcrumb-separator::after {
	color: var(--cf-link);
}

.storefront-breadcrumb {
	padding-bottom: 0;
	text-align: left;
}

/* WooCommerce prints an empty notice wrapper at the top of the content on
   every page. Empty, it should occupy nothing. */
#content .woocommerce:empty {
	display: none;
	margin: 0;
	padding: 0;
}

/* The same tap target treatment the theme's own crumbs get. These links have
 * identical 11px mono text and the identical problem, and giving it to only one
 * of the two also made the two rows different heights, which is what pushed the
 * blog eyebrow lower than the product one even after the margins matched. */
/* nav. rather than a bare class, and the reason is not decoration.

   Storefront's Customizer prints its own colours in an inline <style> in the
   head, after this stylesheet, including
   .woocommerce-breadcrumb a { color: #41445a }. That is the same specificity
   as a bare .woocommerce-breadcrumb a here and later in the document, so it
   won, and the trail rendered in Storefront's text colour while the separator
   used ours. Adding the element name takes the comparison rather than relying
   on order against markup printed by the parent. */
nav.woocommerce-breadcrumb a {
	display: inline-block;
	padding: .45rem .15rem;
	margin: -.45rem -.15rem;
	color: var(--cf-link);
	text-decoration: none;
}

/* Colour alone should not be the only thing marking these as links.
   Breadcrumbs are excluded from the site link rule by decision, so the
   affordance is declared here instead. */
nav.woocommerce-breadcrumb a:hover,
nav.woocommerce-breadcrumb a:focus-visible {
	color: var(--cf-link-hover);
	text-decoration: underline;
}

.woocommerce-breadcrumb a:focus-visible {
	outline: 2px solid var(--cf-focus);
	outline-offset: 1px;
	border-radius: 2px;
}

.woocommerce-breadcrumb a:hover,
.woocommerce-breadcrumb a:focus-visible {
	color: var(--cf-indigo);
	text-decoration: underline;
}

.woocommerce-breadcrumb a:focus-visible {
	outline: 2px solid var(--cf-indigo);
	outline-offset: 1px;
	border-radius: 2px;
}

/* Everything between the breadcrumb and the first block of content has its
   own top margin in Storefront: the content area, the main element and the
   entry wrapper. Each is small on its own and they add up to a band of white.
   The spacing is set once, here, and the rest are zeroed. */

#content.site-content,
.site-content { padding-top: .5rem; }

#content.site-content > .col-full { padding-top: 0; }

.content-area,
#primary.content-area,
.site-main,
#main.site-main {
	margin-top: 0;
	padding-top: 0;
}

.site-main > .hentry:first-child,
.content-area .hentry:first-child { margin-top: 0; }

.entry-header { margin-top: 0; }

/* Storefront styles headings inside .entry-content with a large top margin,
   which pushed our section headings away from their own eyebrow. Only the
   theme's own components are reset; ordinary prose keeps its rhythm. */

.entry-content .cf-page-head h1,
.entry-content .cf-section__head h2,
.entry-content .cf-section > h2,
.entry-content .cf-strip h2,
.entry-content .cf-card h3,
.entry-content .cf-plan h3,
.entry-content .cf-service h2,
.cf-section__head h2,
.cf-section > h2,
.cf-strip h2 { margin-top: 0; }

.entry-content .cf-eyebrow,
.entry-content .cf-page-head,
.entry-content .cf-section:first-child { margin-top: 0; }

/* The hero is full width and sits directly under the menu, so the content
   wrapper below it adds nothing of its own. */
.cf-hero { margin-bottom: 0; }
.cf-hero + #content.site-content,
.cf-hero + .site-content { padding-top: 3rem; }
.home #content.site-content > .col-full { padding-top: 0; }

.site-header > .col-full {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 1rem;
	padding-top: 1.15rem;
	padding-bottom: 1.15rem;
}

/* Storefront puts a clearfix ::before and ::after on every .col-full. The rule
   above turns this one into a flex container, and a flex container treats both
   pseudo-elements as real items, so the row's gap was being spent on two empty
   boxes: one before the logo and one after the cart icon.
 *
 * Measured before this rule: the logo started at 444px where the search text
 * and the page content below both started at 428px, and the cart icon finished
 * at 1476px where the close button finished at 1492px. One gap adrift at each
 * end, at every width.
 *
 * Floats do not apply inside a flex container, so the clearfix has nothing to
 * clear here and is removed rather than compensated for. Only this row is
 * touched; .col-full everywhere else keeps its clearfix. The suppression
 * itself lives in the parent layout register near the top of this file. */

.site-header .site-branding { margin: 0; float: none; width: auto; }
.site-header .site-branding .site-title,
.site-header .site-branding .site-description { margin: 0; }

.site-header .cf-header-tools {
	display: flex;
	align-items: center;
	gap: 1.1rem;
	margin-left: auto;
}

.site-header .site-header-cart {
	float: none;
	margin: 0;
	padding: 0;
	list-style: none;
	display: flex;
	align-items: center;
	width: auto;
}

.site-header .site-header-cart li { list-style: none; margin: 0; }
.site-header .site-header-cart .cart-contents {
	font-family: var(--cf-display);
	font-weight: 500;
	font-size: .93rem;
	color: var(--cf-ink);
	padding: 0;
}

.site-header .site-header-cart .cart-contents .count,
.site-header .site-header-cart .cart-contents .amount {
	font-family: var(--cf-mono);
	font-size: .72rem;
	letter-spacing: .04em;
	color: var(--cf-muted);
}

/* The parent's own search form is removed in PHP; this hides any copy that a
   plugin re-inserts, so two search fields can never appear at once. */
.site-header .site-search { display: none; }

.storefront-primary-navigation {
	background: transparent;
	border-top: 1px solid var(--cf-line);
}

.storefront-primary-navigation .col-full { padding-top: 0; padding-bottom: 0; }

.main-navigation ul.menu,
.main-navigation ul.nav-menu {
	display: flex;
	flex-wrap: wrap;
	gap: 1.7rem;
}

.main-navigation ul.menu > li,
.main-navigation ul.nav-menu > li { margin: 0; }

/* --- Navigation sub menus ----------------------------------------------- */

/* The primary navigation is a flex row, and that rule reaches every list inside
 * it, sub menus included, which would lay a dropdown out as a horizontal strip
 * across the header. A sub menu is a stacked panel, so it states its own axis
 * rather than inheriting the row's, and clears the row's gap with it.
 *
 * The panel is anchored to its item, so the item is the positioning context.
 * It is shown on hover and on focus-within, the second being what lets it open
 * for anyone arriving by keyboard, since nothing here runs on script. */

.main-navigation ul.menu > li,
.main-navigation ul.nav-menu > li { position: relative; }

.main-navigation .sub-menu {
	display: block;
	position: absolute;
	top: 100%;
	left: -.9rem;
	z-index: 60;
	min-width: 13rem;
	margin: 0;
	padding: .35rem 0;
	gap: 0;
	list-style: none;
	background: #fff;
	border: 1px solid var(--cf-line);
	border-radius: var(--cf-radius-sm);
	box-shadow: var(--cf-shadow-lift);
	opacity: 0;
	visibility: hidden;
	transition: opacity .14s ease, visibility .14s ease;
}

.main-navigation li:hover > .sub-menu,
.main-navigation li:focus-within > .sub-menu {
	opacity: 1;
	visibility: visible;
}

.main-navigation .sub-menu li { width: 100%; margin: 0; }

.main-navigation .sub-menu a {
	display: block;
	padding: .45rem .9rem;
	font-family: var(--cf-display);
	font-weight: 500;
	font-size: .92rem;
	line-height: 1.4;
	color: var(--cf-body);
	white-space: nowrap;
	border-bottom: 0;
}

.main-navigation .sub-menu a:hover,
.main-navigation .sub-menu a:focus {
	background: var(--cf-tint);
	color: var(--cf-indigo);
	text-decoration: none;
}

.main-navigation .sub-menu .current-menu-item > a,
.main-navigation .sub-menu .current-menu-ancestor > a { color: var(--cf-indigo); }

/* A third level opens beside its parent rather than under it, since there is
   no room below inside a panel only as tall as its own items. */
.main-navigation .sub-menu .sub-menu { top: -.35rem; left: 100%; }

/* Inside a panel the caret points the way the next panel opens, which is
   sideways, so it is turned rather than reused as it stands. */
.main-navigation .sub-menu li.menu-item-has-children > a::after {
	content: "";
	display: inline-block;
	width: .34em;
	height: .34em;
	margin-left: .5em;
	border-right: 2px solid currentColor;
	border-bottom: 2px solid currentColor;
	transform: translateY(-.1em) rotate(-45deg);
	opacity: .55;
	float: right;
}

/* A caret so an item that opens a panel says so before it is hovered. */
.main-navigation ul.menu > li.menu-item-has-children > a::after,
.main-navigation ul.nav-menu > li.menu-item-has-children > a::after {
	content: "";
	display: inline-block;
	width: .34em;
	height: .34em;
	margin-left: .5em;
	border-right: 2px solid currentColor;
	border-bottom: 2px solid currentColor;
	transform: translateY(-.15em) rotate(45deg);
	opacity: .55;
}

.main-navigation ul.menu > li > a,
.main-navigation ul.nav-menu > li > a {
	font-family: var(--cf-display);
	font-weight: 500;
	font-size: .96rem;
	color: var(--cf-ink);
	padding: .85em 0;
	border-bottom: 2px solid transparent;
}

.main-navigation ul.menu > li > a:hover,
.main-navigation ul.nav-menu > li > a:hover,
.main-navigation ul.menu > li.current-menu-item > a,
.main-navigation ul.nav-menu > li.current-menu-item > a {
	color: var(--cf-indigo);
	border-bottom-color: var(--cf-indigo);
}

/* Full width WooCommerce pages, applied by the body class added in PHP. */
.cf-full-width .content-area { width: 100%; float: none; margin-right: 0; }
.cf-full-width .widget-area { display: none; }

/* Storefront's sale flash and star rating use its own markup. */
.woocommerce span.onsale {
	background-color: var(--cf-mapped);
	border-radius: 999px;
	font-family: var(--cf-mono);
	font-size: .7rem;
	letter-spacing: .06em;
	font-weight: 500;
	padding: .3em .85em;
	min-height: auto;
	min-width: auto;
	line-height: 1.6;
}

.woocommerce ul.products li.product .star-rating,
.woocommerce .star-rating { color: var(--cf-indigo); font-size: .82em; }

/* Storefront prints its own tab styling with higher specificity. */
.woocommerce div.product .woocommerce-tabs ul.tabs::before,
.woocommerce div.product .woocommerce-tabs ul.tabs li::before,
.woocommerce div.product .woocommerce-tabs ul.tabs li::after { display: none; }

.woocommerce div.product .woocommerce-tabs ul.tabs li {
	background: transparent;
	border: 0;
	border-radius: 0;
	/* The list is a flex row and its gap already spaces these. A right margin
	   here as well was adding to that gap rather than replacing it, so the tabs
	   sat 3.2rem apart where 1.6rem was intended. */
	margin: 0;
	padding: 0;
	box-shadow: none;
}

.woocommerce div.product .woocommerce-tabs ul.tabs li a { padding: .7em 0; }

/* Footer. Storefront wraps each widget area in .block and gives it a
   percentage width plus a float, sized by the col-N class on the parent.
   Laying a grid over that leaves every block at roughly 22% of an already
   narrow track, which is what collapses the columns into a single column of
   character-by-character wrapping. The float widths have to be cleared, and
   the attribute selector is there to outrank .footer-widgets.col-4 .block. */

.site-footer { background: var(--cf-ink); color: #b9bcd4; padding-top: 3rem; }

.site-footer .footer-widgets,
.site-footer .footer-widgets[class*="col-"] {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
	gap: 2rem;
	border: 0;
	padding-bottom: 1rem;
	float: none;
	width: auto;
}

.site-footer .footer-widgets .block,
.site-footer .footer-widgets[class*="col-"] .block,
.site-footer .footer-widgets[class*="col-"] .block.footer-widget-1,
.site-footer .footer-widgets[class*="col-"] .block.footer-widget-2,
.site-footer .footer-widgets[class*="col-"] .block.footer-widget-3,
.site-footer .footer-widgets[class*="col-"] .block.footer-widget-4 {
	width: 100%;
	max-width: 100%;
	float: none;
	margin: 0;
	padding: 0;
	clear: none;
}

/* This grid's inherited clearfix is suppressed in the parent layout register
   near the top of this file. */

.site-footer .widget { margin: 0 0 1.4rem; }
.site-footer .widget:last-child { margin-bottom: 0; }

/* Long single words in a narrow column should wrap on the word, never mid
   letter, which is what a collapsed column produced. */
.site-footer .widget-title,
.site-footer .widget li,
.site-footer .widget a {
	overflow-wrap: break-word;
	word-break: normal;
	hyphens: none;
}
.site-footer a { color: #fff; }
.site-footer a:hover { color: #fff; }
/* Footer widget headings.
 *
 * The base .widget-title rule is a single class, and Storefront's footer
 * version carries two, so only the colour was getting through and the size
 * stayed at Storefront's heading scale. The typography is restated here at
 * matching specificity rather than nudged. */

.site-footer .widget-title,
.site-footer .widget .widget-title,
.footer-widgets .widget-title,
.footer-widgets .widget .widget-title {
	font-family: var(--cf-mono);
	font-size: .72rem;
	font-weight: 500;
	line-height: 1.4;
	letter-spacing: .16em;
	text-transform: uppercase;
	color: #fff;
	margin: 0 0 .9rem;
	padding-bottom: .6rem;
	border-bottom: 1px solid rgba(255, 255, 255, .14);
}

/* The height of one footer row is stated here rather than inherited, and every
 * property that contributes to it is named: the line box, the padding around
 * it, and the margins on both the item and the link inside it.
 *
 * Naming all of them is the point. This stylesheet on its own already produces
 * the 36px row the design asks for, measured against the design file, so
 * anything growing it is arriving from somewhere else on the page. Which of the
 * four it lands on does not matter once all four are stated.
 *
 * 14.88px of type on a 1.618 line box with .38em above and below, plus the 1px
 * rule, is the 36px row. */
.site-footer .widget li,
.footer-widgets .widget li {
	border-bottom-color: rgba(255, 255, 255, .08);
	font-size: .93rem;
	line-height: 1.618;
	padding: .38em 0;
	margin: 0;
}

/* The link contributes nothing of its own to the row. The social rows set their
   own display and gap from a heavier selector and are not affected. */
.site-footer .widget li a,
.footer-widgets .widget li a {
	padding: 0;
	margin: 0;
	line-height: inherit;
}

/* Storefront's icon stylesheet puts a glyph before every list item in a
   navigation menu widget. The design has no icons, and the glyph also
   reserves indent that pushes the labels out of line with the Contact
   column, which is why the footer stopped matching once columns 2 to 4
   became menus. Both the mark and its indent are removed. */

.site-footer .widget ul li::before,
.site-footer .widget ul li a::before,
.site-footer .widget_nav_menu ul li::before,
.site-footer .widget_nav_menu ul li a::before,
.site-footer .widget_nav_menu .menu li::before,
.footer-widgets .widget ul li::before,
.footer-widgets .widget ul li a::before,
.footer-widgets .widget_nav_menu ul li a::before {
	content: none;
	display: none;
}

.site-footer .widget ul li,
.site-footer .widget_nav_menu ul li,
.footer-widgets .widget ul li {
	padding-left: 0;
	text-indent: 0;
	list-style: none;
}

.site-footer .widget ul li a,
.site-footer .widget_nav_menu ul li a,
.footer-widgets .widget ul li a {
	padding-left: 0;
	text-indent: 0;
}

/* --- Follow us ------------------------------------------------------------ */

/* This column is a navigation menu widget like columns 2 and 3, and at column
   widths it is meant to read as one: a stacked list of named links carrying
   the same divider, the same vertical padding and the same row height as
   Company info beside it, with a mark set before each name. Nothing below
   overrides .widget li, so the two columns stay in step by inheriting the
   same rule rather than by holding a matching pair of numbers.

   Anything the host map did not recognise arrives without .cf-social and is
   not touched at all, which is what keeps an unrecognised link readable
   instead of collapsing into a blank gap. */

.site-footer .widget_nav_menu ul li.cf-social a,
.footer-widgets .widget_nav_menu ul li.cf-social a {
	display: flex;
	align-items: center;
	gap: .6rem;
}

.cf-social__icon {
	display: block;
	/* Sized to sit inside the row's text line box rather than to grow it, so
	   the divider under a named mark lands at the same height as the divider
	   in the column to its left. The line box measures 19px at this column's
	   font size, and a 22px mark grew every row by 4px, which walked the two
	   columns 24px out of step by the last divider. */
	width: 18px;
	height: 18px;
	flex: 0 0 auto;
	/* Both stated rather than inherited. Several icon rules in this file set
	   stroke on currentColor and fill to none, and a brand mark needs the
	   opposite of that. */
	fill: currentColor;
	stroke: none;
}

/* Below the footer's column layout the names are dropped and the marks run as
   a single row under the same heading. The name stays in the document and only
   its box is taken away, so the link keeps its accessible name either way. */

@media (max-width: 767px) {

	/* Storefront's column gutters are sized for a page that has a sidebar to
	   give room to. This one does not, and on a phone the gutter was spending
	   45px of a 390px screen on empty margin. Both of Storefront's small-screen
	   steps are narrowed here, the tablet one proportionally more than the
	   phone one because it started at nearly twice the width.
	   Set on .col-full rather than on the product grid alone, so the cards stay
	   in line with the heading above them and with the logo in the header. */
	.col-full {
		margin-left: 1.6rem;
		margin-right: 1.6rem;
		padding-left: 0;
		padding-right: 0;
	}

	.cf-strip { padding: 2.6rem 1.4rem; }

	/* Above this width the footer is a set of columns and auto-fit picks how
	   many from the space available, which at phone and small tablet widths
	   leaves two or three narrow columns sitting beside each other in a block.
	   Below it there are no columns at all: every heading and its list take the
	   full width and follow one under the next. Both selectors from the rule
	   that established the grid are repeated here, because the one carrying the
	   attribute test outranks a single class and would otherwise keep winning. */
	/* Stacked, the last column is the row of social marks, and the marks sit in
	 * a band between two rules: the one under the heading and the one along the
	 * top of the bottom bar. Left alone they hung under the heading, with 14px
	 * above and 51px below, because the space above came from the heading's
	 * margin while the space below was the grid's padding and the bar's margin
	 * added together.
	 *
	 * One value now sets both sides of that band. Above the marks it is the
	 * list's own top margin, which collapses against the heading's margin
	 * rather than adding to it, so the larger of the two is what shows and the
	 * value can simply be stated. Below them the grid contributes nothing and
	 * the bar's margin is the whole of it. */
	.related.products ul.products,
	.up-sells ul.products {
		grid-template-columns: repeat(2, minmax(0, 1fr));
	}

	.site-footer { --cf-social-band: 1.9rem; }

	.site-footer .footer-widgets,
	.site-footer .footer-widgets[class*="col-"] {
		grid-template-columns: 1fr;
		padding-bottom: 0;
	}

	.site-footer .widget_nav_menu ul.menu:has(li.cf-social),
	.footer-widgets .widget_nav_menu ul.menu:has(li.cf-social) {
		margin-top: var(--cf-social-band);
	}

	.site-footer .widget_nav_menu ul li.cf-social,
	.footer-widgets .widget_nav_menu ul li.cf-social {
		display: inline-block;
		margin: 0 .7rem .5rem 0;
		/* .widget li gives every item a divider and vertical padding, which is
		   right for a stacked list of names and wrong the moment the items sit
		   in a row: each divider becomes a short rule under its own mark. Both
		   belong to the stacked layout, so both go with it. */
		border-bottom: 0;
		padding: 0;
	}

	.site-footer .widget_nav_menu ul li.cf-social a,
	.footer-widgets .widget_nav_menu ul li.cf-social a {
		display: block;
		/* The link box is the mark and nothing else. */
		line-height: 0;
	}

	/* With no name beside it the mark is the whole target, so it is set back
	   to the size it reads at on its own. Nothing here is measured against a
	   neighbouring column, because at this width there is no column beside
	   it to match. */
	.cf-social__icon {
		width: 22px;
		height: 22px;
	}

	/* The gap between inline-block items is set by the list's own font size
	   and cannot be stated from here, and that unstated width is what decided
	   how many marks fit on a line in 1.26.0. Laying the row out as flex
	   replaces it with a number this file controls. A menu holding no marks is
	   left alone, and an unrecognised item inside one is given a full line so
	   it still reads as the stacked text link it was. */
	.site-footer .widget_nav_menu ul.menu:has(li.cf-social),
	.footer-widgets .widget_nav_menu ul.menu:has(li.cf-social) {
		display: flex;
		flex-wrap: wrap;
		align-items: center;
		/* The marks are spread over the column rather than packed against its
		   left edge, so the first one starts under the start of the heading
		   and the last one ends at the column's right edge. The gap is the
		   floor the row falls back to once the column is too narrow for any
		   free space to hand out, which keeps the marks apart instead of
		   letting them touch. */
		justify-content: space-between;
		gap: .7rem;
	}

	.site-footer .widget_nav_menu ul.menu:has(li.cf-social) li.cf-social,
	.footer-widgets .widget_nav_menu ul.menu:has(li.cf-social) li.cf-social {
		margin: 0;
	}

	.site-footer .widget_nav_menu ul.menu:has(li.cf-social) li:not(.cf-social),
	.footer-widgets .widget_nav_menu ul.menu:has(li.cf-social) li:not(.cf-social) {
		flex: 0 0 100%;
	}

	.cf-social__label {
		position: absolute;
		width: 1px;
		height: 1px;
		overflow: hidden;
		clip: rect(1px, 1px, 1px, 1px);
		clip-path: inset(50%);
		white-space: nowrap;
	}

	.site-footer .widget_nav_menu ul li.cf-social a:hover .cf-social__icon,
	.site-footer .widget_nav_menu ul li.cf-social a:focus .cf-social__icon {
		opacity: .68;
		transition: opacity .15s ease;
	}
}

/* The title has been a span, an h4 and now an h2. Whichever it is, the
   underline needs an explicit block to run the width of the column, so this
   asks for the class and never for the element. */
.site-footer .widget-title,
.site-footer .gamma.widget-title {
	display: block;
	width: 100%;
}

/* Storefront underlines footer links. The design does not. */
.site-footer a,
.site-footer .widget a,
.site-footer .widget li a,
.footer-widgets .widget a {
	text-decoration: none;
	box-shadow: none;
}

/* The footer sits on the deep indigo band, so the light-background link
   colours do not apply here. Hover keeps the rest colour and lets the
   underline carry the state on its own: shifting white towards lilac was a
   colour-only signal, and a weak one at 1.3:1 between the two. */
.site-footer a:hover,
.site-footer .widget a:hover,
.footer-widgets .widget a:hover {
	text-decoration: underline;
	color: #fff;
}

.site-info {
	border-top: 1px solid rgba(255,255,255,.12);
	margin-top: 2rem;
	padding-top: 1.3rem;
	font-family: var(--cf-mono);
	font-size: .74rem;
	letter-spacing: .04em;
}

/* Footer bottom bar.
 *
 * Where this block sits is chosen in the customizer, and each choice is one
 * modifier on this element, so a single class decides the whole arrangement
 * rather than alignment being spread over the base rule and the parts below
 * it. The base rule holds only what every choice shares. */

.cf-footer-bottom {
	display: flex;
	gap: 1.6rem;
	flex-wrap: wrap;
	border-top: 1px solid rgba(255, 255, 255, .12);
	margin-top: 2.2rem;
	padding-top: 1.6rem;
}

/* Brand on one side, payment marks on the other, which is what the bar did
   before the setting existed. */
.cf-footer-bottom--split {
	align-items: flex-end;
	justify-content: space-between;
}

/* The other three stack the brand and the marks and move both to the same
   edge. The stack is a direction change rather than a text-align, because the
   marks are a flex row of their own and text-align would leave them where
   they were. */
.cf-footer-bottom--left,
.cf-footer-bottom--center,
.cf-footer-bottom--right {
	flex-direction: column;
}

.cf-footer-bottom--left   { align-items: flex-start; text-align: left; }
.cf-footer-bottom--center { align-items: center;     text-align: center; }
.cf-footer-bottom--right  { align-items: flex-end;   text-align: right; }

.cf-footer-bottom__brand { max-width: 42em; }

/* The other side of the band described in the mobile block above. It is set
   here because the base value for this margin is stated below that block and
   would otherwise win on source order. */
@media (max-width: 767px) {
	.cf-footer-bottom { margin-top: var(--cf-social-band); }
}

/* The tagline caps its own measure below the brand block's, so on a centred or
   right aligned bar it would sit at the left of that block with its text
   centred inside itself. The box is moved as well as the text in it. */
.cf-footer-bottom--center .cf-footer-tagline { margin-inline: auto; }
.cf-footer-bottom--right .cf-footer-tagline { margin-left: auto; margin-right: 0; }

.cf-footer-logo { display: inline-block; margin: 0 0 .9rem; }

/* A white plate lets the ordinary dark logo sit on the dark footer without
   needing a second light artwork file. */
.cf-footer-logo--plate {
	background: #fff;
	border-radius: 10px;
	padding: .5rem .9rem;
}

.cf-footer-logo--plate:hover { background: #fff; }

.cf-footer-logo img {
	height: 34px;
	width: auto;
	display: block;
}

.cf-footer-tagline {
	color: #c7c9de;
	font-size: .95rem;
	line-height: 1.5;
	margin: 0 0 .6rem;
	max-width: 34em;
}

.cf-footer-copy {
	font-family: var(--cf-mono);
	font-size: .74rem;
	letter-spacing: .04em;
	color: #9a9db8;
	margin: 0;
}

.cf-footer-bottom__pay {
	display: flex;
	align-items: center;
	gap: .8rem;
	flex-wrap: wrap;
}

.cf-pay-label {
	font-family: var(--cf-mono);
	font-size: .7rem;
	letter-spacing: .14em;
	text-transform: uppercase;
	color: #9a9db8;
}

.cf-pay-icons {
	height: 30px;
	width: auto;
	display: block;
}

@media (max-width: 568px) {
	.col-full {
		margin-left: 1rem;
		margin-right: 1rem;
	}
}

@media (max-width: 640px) {
	/* Only the split arrangement needs this. It bottom aligns two items side by
	   side, and once they wrap onto separate lines that reads as an indent. The
	   three stacked arrangements set align-items themselves to place the block,
	   so an unscoped rule here would overrule the chosen alignment on phones,
	   which is the one width where it is most visible. */
	.cf-footer-bottom--split { align-items: flex-start; }
	.cf-footer-bottom { gap: 1.4rem; }
	.cf-pay-icons { height: 26px; }
}

/* The hero renders on storefront_before_content, outside #content, so it is
   already full width and needs no negative-margin trickery. */
.cf-hero + #content .col-full { padding-top: 0; }

/* Live search results panel, which only exists on the live site. */
.cf-search-results {
	position: absolute;
	left: 0;
	right: 0;
	top: 100%;
	background: #fff;
	border: 1px solid var(--cf-line);
	border-top: 0;
	border-radius: 0 0 var(--cf-radius) var(--cf-radius);
	box-shadow: var(--cf-shadow-lift);
	max-height: 60vh;
	overflow-y: auto;
	z-index: 30;
	padding: .4rem 0;
}

.cf-search-results[hidden] { display: none; }

.cf-search-result {
	display: flex;
	align-items: center;
	gap: .85rem;
	padding: .7rem 1.1rem;
	color: var(--cf-ink);
	border: 0;
	background: none;
	width: 100%;
	text-align: left;
}

.cf-search-result:hover,
.cf-search-result[aria-selected="true"] {
	background: var(--cf-tint);
	text-decoration: none;
	color: var(--cf-ink);
}

.cf-search-result img {
	flex: 0 0 46px;
	width: 46px;
	height: 46px;
	border-radius: var(--cf-radius-sm);
	border: 1px solid var(--cf-line);
	object-fit: cover;
	background: var(--cf-tint);
}

.cf-search-result__body { min-width: 0; flex: 1; }

.cf-search-result__title {
	font-family: var(--cf-display);
	font-weight: 600;
	font-size: .95rem;
	line-height: 1.3;
	display: block;
}

.cf-search-result__meta {
	font-family: var(--cf-mono);
	font-size: .68rem;
	letter-spacing: .04em;
	color: var(--cf-muted);
	display: block;
	margin-top: .15rem;
}

.cf-search-result__price {
	flex: 0 0 auto;
	font-family: var(--cf-display);
	font-weight: 700;
	font-size: .95rem;
	color: var(--cf-ink);
	white-space: nowrap;
}

.cf-search-result__price .woocommerce-Price-amount { color: var(--cf-ink); }

.cf-search-status {
	padding: .9rem 1.1rem;
	font-size: .9rem;
	color: var(--cf-muted);
}

.cf-search-all {
	display: block;
	padding: .75rem 1.1rem;
	border-top: 1px solid var(--cf-line);
	font-family: var(--cf-display);
	font-weight: 600;
	font-size: .9rem;
}

/* Product page trust panel: promise line, three checks, safe checkout. */

.cf-trust {
	border: 1px solid var(--cf-line);
	border-radius: var(--cf-radius);
	padding: 1.25rem 1.35rem;
	margin: 1.6rem 0;
	background: #fff;
}

.cf-trust__head {
	font-family: var(--cf-display);
	font-weight: 600;
	font-size: 1.02rem;
	color: var(--cf-ink);
	margin: 0 0 .9rem;
	letter-spacing: -.01em;
}

.cf-trust__list {
	list-style: none;
	margin: 0;
	padding: 0;
}

.cf-trust__list li {
	display: flex;
	align-items: flex-start;
	gap: .6rem;
	padding: .3em 0;
	font-size: .96rem;
	color: var(--cf-body);
	border: 0;
}

.cf-trust__list svg {
	flex: 0 0 20px;
	width: 20px;
	height: 20px;
	margin-top: .12em;
	fill: var(--cf-mapped);
	stroke: #fff;
	stroke-width: 2;
}

.cf-trust__checkout {
	margin-top: 1.1rem;
	padding: .95rem 1rem;
	background: var(--cf-tint);
	border: 1px solid var(--cf-line);
	border-radius: var(--cf-radius-sm);
	text-align: center;
}

.cf-trust__legend {
	display: block;
	font-family: var(--cf-mono);
	font-size: .7rem;
	letter-spacing: .14em;
	text-transform: uppercase;
	color: var(--cf-muted);
	margin: 0 0 .7rem;
}

.cf-trust__checkout .cf-pay-icons {
	height: 32px;
	width: auto;
	max-width: 100%;
	margin: 0 auto;
	display: block;
}

@media (max-width: 640px) {
	.cf-trust { padding: 1.1rem; }
	.cf-trust__checkout .cf-pay-icons { height: 26px; }
}

/* Header icon links: search, account, cart. */

.cf-icon-link,
.cf-search-toggle {
	display: inline-grid;
	place-items: center;
	position: relative;
	width: 40px;
	height: 40px;
	padding: 0;
	border: 0;
	border-radius: 50%;
	background: transparent;
	color: var(--cf-ink);
	cursor: pointer;
}

.cf-icon-link:hover,
.cf-search-toggle:hover {
	background: var(--cf-tint);
	color: var(--cf-indigo);
	box-shadow: none;
	transform: none;
	text-decoration: none;
}

.cf-icon-link svg,
.cf-search-toggle svg {
	width: 22px;
	height: 22px;
	stroke: currentColor;
	fill: none;
	stroke-width: 1.7;
}

/* The count sits on the basket rather than beside it, so the row keeps a
   steady width whether the cart holds 0 items or 12. */
.cf-cart__count {
	position: absolute;
	top: 0;
	right: -4px;
	min-width: 14px;
	height: 14px;
	padding: 0 3px;
	border-radius: 999px;
	background: var(--cf-indigo);
	color: #fff;
	font-family: var(--cf-mono);
	font-size: .58rem;
	font-weight: 500;
	line-height: 14px;
	text-align: center;
	border: 2px solid #fff;
	box-sizing: content-box;
}

.cf-cart__count.is-empty {
	background: var(--cf-line-strong);
	color: var(--cf-ink);
}

.site-header .cf-header-tools { gap: .5rem; overflow: visible; }

@media (max-width: 640px) {
	.cf-icon-link,
	.cf-search-toggle { width: 36px; height: 36px; }
	.cf-icon-link svg,
	.cf-search-toggle svg { width: 19px; height: 19px; }
	.site-header .cf-header-tools { gap: .15rem; }
}

/* Search overlay field, hardened.
   Storefront styles bare inputs with a grey fill, an inset shadow, a radius
   and padding. Those rules match on the same specificity as a single class,
   so the outcome depended on source order. These selectors carry a class and
   an attribute so the result is not a coin toss, and every property
   Storefront sets is reset rather than only the background. */

.cf-search-overlay .cf-search-overlay__form input.cf-search-field,
.cf-search-overlay .cf-search-overlay__form input[type="search"] {
	-webkit-appearance: none;
	appearance: none;
	flex: 1;
	min-width: 0;
	width: 100%;
	margin: 0;
	padding: .3em 0;
	border: 0;
	border-radius: 0;
	background: none;
	background-color: transparent;
	box-shadow: none;
	color: #fff;
	font-family: var(--cf-display);
	font-weight: 400;
	font-size: 1.85rem;
	line-height: 1.2;
	height: auto;
	/* If a placeholder ever outgrows the field again it ends in an ellipsis
	   rather than being sliced through the middle of a glyph, which reads as a
	   rendering fault rather than as truncation. The rules under 640px already
	   did this; it belongs at every width. */
	text-overflow: ellipsis;
}

.cf-search-overlay .cf-search-overlay__form input.cf-search-field:focus,
.cf-search-overlay .cf-search-overlay__form input[type="search"]:focus {
	background-color: transparent;
	box-shadow: none;
	outline: 0;
	color: #fff;
}

.cf-search-overlay .cf-search-overlay__form input::placeholder {
	color: rgba(255, 255, 255, .62);
	opacity: 1;
}

/* Chrome and Safari draw their own clear button inside a search field. */
.cf-search-overlay input[type="search"]::-webkit-search-decoration,
.cf-search-overlay input[type="search"]::-webkit-search-cancel-button,
.cf-search-overlay input[type="search"]::-webkit-search-results-button {
	-webkit-appearance: none;
	appearance: none;
}

.cf-search-overlay .cf-search-close,
.cf-search-overlay button.cf-search-close {
	background: transparent;
	border: 0;
	color: #fff;
	box-shadow: none;
}

.cf-search-overlay .cf-search-close:hover {
	background: rgba(255, 255, 255, .12);
	color: #fff;
}

.cf-search-overlay .cf-search-close svg { stroke: currentColor; }

@media (max-width: 640px) {
	.cf-search-overlay .cf-search-overlay__form input.cf-search-field,
	.cf-search-overlay .cf-search-overlay__form input[type="search"] {
		font-size: 1.3rem;
	}
}

/* --- Mobile header ------------------------------------------------------ */

@media (max-width: 767px) {

	/* The toggle is moved into the logo row by cesarfeed.js. Storefront's
	   default is a wide bordered button labelled "Menu" on a row of its own,
	   which costs a whole band of height on a phone. */

	.site-header > .col-full {
		display: flex;
		align-items: center;
		gap: .5rem;
		padding-top: .6rem;
		padding-bottom: .6rem;
	}

	.site-header .site-branding {
		flex: 1 1 auto;
		min-width: 0;
		margin: 0;
	}

	.site-header .site-branding img,
	.site-header .custom-logo {
		max-height: 34px;
		width: auto;
	}

	.site-header .cf-header-tools {
		flex: 0 0 auto;
		margin-left: auto;
	}

	button.menu-toggle,
	.main-navigation button.menu-toggle,
	.cf-menu-toggle:hover,
	.cf-menu-toggle:focus-visible {
		background: var(--cf-tint);
		border-color: var(--cf-line-strong);
		color: var(--cf-ink);
	}

	.cf-menu-toggle {
		order: -1;
		flex: 0 0 auto;
		display: inline-flex;
		align-items: center;
		justify-content: center;
		width: 42px;
		height: 42px;
		margin: 0;
		padding: 0;
		border: 1px solid var(--cf-line);
		border-radius: 10px;
		background: transparent;
		box-shadow: none;
	}

	button.menu-toggle:hover,
	.cf-menu-toggle:hover {
		background: var(--cf-tint);
		border-color: var(--cf-line-strong);
	}

	/* Storefront draws the bars with pseudo elements and puts the word
	   "Menu" inside the span. The bars stay, the word goes. */
	button.menu-toggle span {
		font-size: 0;
		line-height: 0;
		text-indent: -9999px;
		width: 18px;
	}

	button.menu-toggle::before,
	button.menu-toggle::after,
	button.menu-toggle span::before {
		width: 18px;
		height: 2px;
		border-radius: 2px;
		left: 50%;
		margin-left: -9px;
	}

	/* With the button hidden, the navigation row carries nothing until it is
	   opened, so it should take no space and draw no border. */
	.storefront-primary-navigation {
		padding: 0;
		border: 0;
	}

	.storefront-primary-navigation .col-full { padding: 0; }

	/* The desktop menu never appears on a phone, opened or not. Only the
	   handheld copy does, and it stacks. */
	.main-navigation .primary-navigation { display: none; }
	.main-navigation:not(.toggled) .handheld-navigation { display: none; }

	/* --- opening the menu ---------------------------------------------
	 *
	 * The panel wipes down, a line sweeps through it once, and the items
	 * arrive one after another rather than all at once. The whole thing is
	 * finished in under a third of a second, which is the point: it should
	 * read as the panel assembling itself, not as something to wait for.
	 *
	 * Everything keys off aria-expanded rather than a class. That attribute
	 * is already correct because the script sets it for screen readers, so
	 * the animation and the accessibility state cannot drift apart.
	 *
	 * display cannot be transitioned, but an animation on the shown state
	 * restarts every time the element appears, which is exactly the
	 * behaviour wanted here and needs no change to the script. */

	.main-navigation.toggled .handheld-navigation {
		display: block;
		position: relative;
		overflow: hidden;
		border-top: 1px solid var(--cf-line);
		padding: .2rem 1.4rem .8rem;
		animation: cf-menu-open .26s cubic-bezier(.2, .7, .3, 1) both;
	}

	@keyframes cf-menu-open {
		from { clip-path: inset(0 0 100% 0); opacity: .4; }
		to   { clip-path: inset(0 0 0 0);    opacity: 1; }
	}

	/* The sweep. One pass, top to bottom, then gone. It is decoration, so it
	   is hidden from assistive technology and ignores pointer events. */
	.main-navigation.toggled .handheld-navigation::before {
		content: "";
		position: absolute;
		inset: 0 0 auto 0;
		height: 1px;
		background: linear-gradient(90deg, transparent, var(--cf-indigo), var(--cf-lilac), transparent);
		opacity: .9;
		pointer-events: none;
		animation: cf-menu-sweep .42s ease-out both;
	}

	@keyframes cf-menu-sweep {
		from { transform: translateY(0); opacity: 0; }
		18%  { opacity: .9; }
		to   { transform: translateY(var(--cf-sweep-to, 340px)); opacity: 0; }
	}

	.main-navigation.toggled .handheld-navigation ul.menu > li {
		animation: cf-menu-item .22s ease-out both;
	}

	@keyframes cf-menu-item {
		from { opacity: 0; transform: translateX(-10px); }
		to   { opacity: 1; transform: none; }
	}

	/* The stagger. Eight is the depth worth writing out: past that the delay
	   would be longer than the animation and the last item would feel late,
	   so anything further in simply arrives with the eighth. */
	.main-navigation.toggled .handheld-navigation ul.menu > li:nth-child(1) { animation-delay: .04s; }
	.main-navigation.toggled .handheld-navigation ul.menu > li:nth-child(2) { animation-delay: .08s; }
	.main-navigation.toggled .handheld-navigation ul.menu > li:nth-child(3) { animation-delay: .12s; }
	.main-navigation.toggled .handheld-navigation ul.menu > li:nth-child(4) { animation-delay: .16s; }
	.main-navigation.toggled .handheld-navigation ul.menu > li:nth-child(5) { animation-delay: .20s; }
	.main-navigation.toggled .handheld-navigation ul.menu > li:nth-child(6) { animation-delay: .24s; }
	.main-navigation.toggled .handheld-navigation ul.menu > li:nth-child(7) { animation-delay: .28s; }
	.main-navigation.toggled .handheld-navigation ul.menu > li:nth-child(n+8) { animation-delay: .32s; }

	/* The bars become a cross. Storefront writes this rule already, but only
	   for a button sitting inside .toggled, and this theme's button lives in
	   the header instead, so it never matched. */
	.cf-menu-toggle::before,
	.cf-menu-toggle::after,
	.cf-menu-toggle span::before {
		transition: transform .22s cubic-bezier(.2, .7, .3, 1), opacity .16s ease;
	}

	.cf-menu-toggle[aria-expanded="true"]::before { transform: rotate(45deg); }
	.cf-menu-toggle[aria-expanded="true"]::after { transform: rotate(-45deg); }
	.cf-menu-toggle[aria-expanded="true"] span::before { opacity: 0; transform: scaleX(.2); }

	.main-navigation.toggled .handheld-navigation ul.menu,
	.main-navigation.toggled .handheld-navigation ul {
		display: block;
		margin: 0;
		padding: 0;
		list-style: none;
	}

	.main-navigation.toggled .handheld-navigation ul.menu li,
	.main-navigation.toggled .handheld-navigation ul li {
		display: block;
		width: 100%;
		float: none;
		margin: 0;
		border-bottom: 1px solid var(--cf-line);
	}

	.main-navigation.toggled .handheld-navigation ul.menu li:last-child { border-bottom: 0; }

	/* Stacked, a sub menu is just an indented run of items under its parent.
	 * Storefront hides sub menus here until its own script adds a toggle button
	 * beside each parent; this theme draws its menu without that script, so the
	 * categories are simply shown, and any toggle button that does turn up is
	 * taken out rather than left as a control that does nothing. */
	.main-navigation.toggled .handheld-navigation .sub-menu {
		position: static;
		visibility: visible;
		opacity: 1;
		max-height: none;
		min-width: 0;
		margin: 0;
		padding: 0 0 0 1.1rem;
		background: none;
		border: 0;
		border-radius: 0;
		box-shadow: none;
	}

	.main-navigation.toggled .handheld-navigation .sub-menu a {
		font-size: .95rem;
		font-weight: 400;
		white-space: normal;
		padding: .7em 0;
	}

	.main-navigation.toggled .handheld-navigation .dropdown-toggle { display: none; }

	/* The caret belongs to the hover panel, which does not exist at this width. */
	.main-navigation.toggled .handheld-navigation li.menu-item-has-children > a::after { content: none; }

	.main-navigation.toggled .handheld-navigation ul.menu li a {
		display: block;
		padding: .85em 0;
		font-family: var(--cf-display);
		font-weight: 500;
		font-size: 1rem;
		border-bottom: 0;
	}
}

/* --- Cart drawer -------------------------------------------------------- */

.cf-drawer-backdrop {
	position: fixed;
	inset: 0;
	z-index: 998;
	background: rgba(15, 16, 41, .45);
	opacity: 0;
	transition: opacity .28s ease;
}

.cf-drawer-backdrop.is-open { opacity: 1; }

/* The hidden attribute is what the script uses to take this panel out of the
 * page, and the browser implements it as display: none from its own stylesheet,
 * which any author display declaration outranks. The rule below therefore has
 * to exist for the one under it to be switchable at all: without it the panel
 * keeps display: flex with hidden set, stays laid out at full viewport height,
 * and keeps both of its buttons in the tab order, held out of sight only by a
 * transform. Every other element this theme toggles by the attribute already
 * carries the matching rule; this one was the gap.
 *
 * The rule for anyone adding another: an element the script toggles by the
 * hidden attribute must never carry a bare display declaration without this
 * alongside it. */

.cf-drawer[hidden] { display: none; }

.cf-drawer {
	position: fixed;
	top: 0;
	right: 0;
	z-index: 999;
	display: flex;
	flex-direction: column;
	width: min(420px, 100%);
	height: 100%;
	background: #fff;
	box-shadow: -16px 0 40px rgba(15, 16, 41, .18);
	transform: translateX(100%);
	transition: transform .28s ease;
}

.cf-drawer.is-open { transform: translateX(0); }

@media (prefers-reduced-motion: reduce) {
	.cf-drawer,
	.cf-drawer-backdrop { transition: none; }
}

.cf-drawer__head {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 1rem;
	padding: 1.1rem 1.3rem;
	border-bottom: 1px solid var(--cf-line);
	flex: 0 0 auto;
}

.cf-drawer__title {
	font-family: var(--cf-display);
	font-size: 1.05rem;
	font-weight: 600;
	color: var(--cf-ink);
	margin: 0;
}

.cf-drawer__close {
	display: inline-grid;
	place-items: center;
	width: 38px;
	height: 38px;
	padding: 0;
	border: 1px solid var(--cf-line);
	border-radius: 50%;
	background: transparent;
	color: var(--cf-ink);
	cursor: pointer;
}

/* Storefront's customizer prints an inline rule for button:hover that sets
 * background, border AND colour. Overriding only the background left the icon
 * at the parent's button text colour, which is white: 1.08 to 1 against this
 * tint, which is to say invisible, and well under the 3 to 1 that non-text
 * needs. Every property that rule touches is stated back here.
 *
 * focus-visible is included so the state a keyboard produces matches the one a
 * pointer produces. */
.cf-drawer__close:hover,
.cf-drawer__close:focus-visible {
	background: var(--cf-tint);
	border-color: var(--cf-line-strong);
	color: var(--cf-ink);
}

.cf-drawer__close svg {
	width: 17px;
	height: 17px;
	stroke: currentColor;
	fill: none;
	stroke-width: 2;
}

.cf-drawer__body {
	flex: 1 1 auto;
	overflow-y: auto;
	padding: 1.2rem 1.3rem;
	-webkit-overflow-scrolling: touch;
}

.cf-drawer__foot {
	flex: 0 0 auto;
	padding: 1rem 1.3rem 1.3rem;
	border-top: 1px solid var(--cf-line);
}

.cf-drawer__continue,
.cf-drawer .cf-drawer__continue {
	display: block;
	width: 100%;
	border-radius: 999px;
	text-align: center;
}

/* WooCommerce's mini cart, sitting inside the drawer. */

.cf-drawer .widget_shopping_cart_content { font-size: .95rem; }

.cf-drawer .cart_list {
	list-style: none;
	margin: 0 0 1rem;
	padding: 0;
}

.cf-drawer .cart_list li {
	position: relative;
	display: flex;
	gap: .8rem;
	align-items: flex-start;
	padding: .9rem 0;
	border-bottom: 1px solid var(--cf-line);
}

.cf-drawer .cart_list li:last-child { border-bottom: 0; }

.cf-drawer .cart_list li img {
	width: 54px;
	height: auto;
	border-radius: var(--cf-radius-sm);
	border: 1px solid var(--cf-line);
	order: -1;
}

.cf-drawer .cart_list li a { font-weight: 500; }

.cf-drawer .cart_list .quantity {
	display: block;
	font-family: var(--cf-mono);
	font-size: .78rem;
	color: var(--cf-muted);
}

.cf-drawer .woocommerce-mini-cart__total {
	display: flex;
	justify-content: space-between;
	align-items: baseline;
	padding: .9rem 0 0;
	margin: 0;
	border-top: 1px solid var(--cf-line);
	font-family: var(--cf-display);
	font-weight: 600;
	color: var(--cf-ink);
}

.cf-drawer .woocommerce-mini-cart__buttons {
	display: grid;
	gap: .6rem;
	margin: 1rem 0 0;
}

.cf-drawer .woocommerce-mini-cart__buttons a { text-align: center; }

.cf-drawer .woocommerce-mini-cart__empty-message {
	text-align: center;
	color: var(--cf-muted);
	padding: 3rem 0;
	margin: 0;
}

/* The page behind the drawer should not scroll under it. */
/* Reserve the scrollbar's space whether or not a scrollbar is there.

   The lock below removes the scrollbar for as long as the drawer is open. The
   layout viewport gets about 15px wider the moment it does, and every centred
   thing on the page, the logo, the menu and the breadcrumb, slides right by
   half of that. Nothing has moved; the page is being measured against a wider
   box.

   The same shift already happens without the drawer, between a page short
   enough not to scroll and a page that does, so reserving the gutter fixes
   both at once rather than only the one that is visible.

   Where scrollbar-gutter is not supported the declaration is ignored and the
   behaviour is exactly what it is today. Platforms with overlay scrollbars
   reserve nothing, because there is nothing to reserve. */

html { scrollbar-gutter: stable; }

/* The panel takes focus when the drawer is opened by pointer, so a reader
   using a screen reader hears the dialog and its label. It is not a control
   and it is not reachable by Tab, so it draws no ring. Both states are named
   because WebKit will match :focus-visible on a programmatic focus where
   Chromium will not, and this has to look the same in both. */

.cf-drawer:focus,
.cf-drawer:focus-visible {
	outline: none;
}

.cf-drawer-open,
.cf-drawer-open body { overflow: hidden; }

/* --- Focus visibility --------------------------------------------------- */

/* Storefront draws a focus outline on :focus, which fires on mouse and touch
   as well as keyboard. That is the blue box that flashes around the logo and
   the menu links when you click them.
 *
 * The outline is not removed, it is narrowed to :focus-visible, which the
 * browser sets only when focus arrives by keyboard. Deleting focus styles
 * outright would leave anyone navigating by keyboard with no idea where they
 * are on the page. */

a:focus:not(:focus-visible),
button:focus:not(:focus-visible),
.button:focus:not(:focus-visible),
input[type="button"]:focus:not(:focus-visible),
input[type="submit"]:focus:not(:focus-visible),
.custom-logo-link:focus:not(:focus-visible),
.cf-icon-link:focus:not(:focus-visible),
.cf-search-toggle:focus:not(:focus-visible),
.main-navigation a:focus:not(:focus-visible),
.site-header a:focus:not(:focus-visible),
.site-footer a:focus:not(:focus-visible),
.cf-drawer button:focus:not(:focus-visible) {
	outline: 0;
	box-shadow: none;
}

/* Keyboard focus stays obvious, and matches the brand rather than the
   browser default. */
a:focus-visible,
button:focus-visible,
.button:focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible,
.cf-icon-link:focus-visible,
.cf-search-toggle:focus-visible {
	outline: 2px solid var(--cf-focus);
	outline-offset: 3px;
	border-radius: 5px;
}

/* Dark surfaces flip the ring, once, for everything inside them.

   The ring has to contrast with what sits next to it, and no single colour
   does that on both. Indigo measures 10.25:1 on white and 1.63:1 on the
   indigo band; white is the reverse. This was previously handled by naming
   two containers and recolouring anchors inside them, which is why the blog
   index featured band was missed: its title and its Read the post button
   both drew an indigo ring on an indigo gradient.

   Because the token inherits, a control does not need to know what it is
   sitting on, and a new dark band is one entry here rather than one rule per
   focusable inside it. Add the container the same day you add the band. */

.cf-hero,
.cf-band,
.cf-feature,
.cf-404,
.ab-band,
.site-footer {
	--cf-focus: #fff;
}

/* --- Storefront's own menu button ---------------------------------------- */

/* This theme prints its own toggle into the logo row from PHP. Storefront's
   stays in the markup and stays bound by its navigation.js, because that
   script only binds a button found inside #site-navigation, but it is never
   shown. Hidden at every width, not just on handheld, since there is now no
   width at which it should appear.
 *
   Two selectors on purpose: the id is what Storefront gives the button today,
   and the structural selector catches it on any build that drops the id. The
   id also outranks the display rules further up without needing !important. */
#site-navigation-menu-toggle,
.site-header .storefront-primary-navigation button.menu-toggle {
	display: none;
}

/* Android and iOS paint a flash over a tapped link, and this used to turn it
   off on every link and button on the site because the grey was thought ugly.
   It is the only confirmation a touch user gets that their tap landed on
   something, and there is no hover state to fall back on. Suppressing it cost
   six rounds of diagnosis on a cart bug in 1.98.0: the wrong element was being
   hit on every tap and nothing on screen said so. Restoring the flash made the
   culprit obvious in a single tap.

   Deleted rather than recoloured. A translucent brand tint was the obvious
   next move, and it is exactly how this ends up too faint again. The platforms
   tune this value for visibility on their own displays, and that judgement is
   better than one made here against a desktop monitor. */

/* --- Search overlay on small screens ------------------------------------ */

@media (max-width: 767px) {

	/* Measured on the live site: the panel inherits the 63px header height,
	   but the field plus its padding plus the close button need more room
	   than that. Because the form was allowed to shrink, it was crushed to
	   36px while keeping its 14px padding, leaving an 8px content box. The
	   30px field then overflowed that box by 11px at each end and came to
	   rest 3px from the top.
	 *
	   The field was never mis-centred. It was spilling out of a container
	   smaller than itself, which is why every attempt to adjust the centring
	   changed nothing. Nothing here may now shrink below its contents, and
	   the panel grows past the header rather than squeezing what is inside. */

	.cf-search-overlay {
		display: grid;
		align-content: center;
		bottom: auto;
		min-height: 100%;
		padding: 0;
	}

	/* A plain block. The nested flex containers were what allowed the form
	   to be stretched by one parent and crushed by another. */
	.cf-search-overlay > .col-full {
		display: block;
		/* The base rule pins this to the overlay's height so it can centre the
		   form. Here the overlay is allowed to grow past the header instead, so
		   the height is released and align-content on the grid centres it, as
		   before. */
		height: auto;
		/* Also refuses to shrink. min-height beats height, so this holds even
		   if something further out tries to size it smaller than the field. */
		min-height: fit-content;
	}

	.cf-search-overlay .cf-search-overlay__form {
		display: flex;
		align-items: center;
		gap: .5rem;
		width: 100%;
		max-width: 100%;
		margin: 0;
		padding: 12px 0;
		min-height: fit-content;
		flex: none;
		align-self: center;
	}

	.cf-search-overlay .cf-search-overlay__form input.cf-search-field,
	.cf-search-overlay .cf-search-overlay__form input[type="search"] {
		/* A basis of zero rather than auto. With auto the field claims the
		   full width of its placeholder before shrinking, which pushed the
		   close button off the right of the screen. */
		flex: 1 1 0%;
		min-width: 0;
		width: 100%;
		height: auto;
		min-height: 0;
		line-height: 1.25;
		padding: 0;
		font-size: clamp( 1rem, 5.6vw, 1.5rem );
		text-overflow: ellipsis;
	}

	.cf-search-overlay .cf-search-close,
	.cf-search-overlay button.cf-search-close {
		flex: 0 0 34px;
		width: 34px;
		height: 34px;
		display: inline-grid;
		place-items: center;
	}
}

/* --- Search overlay: hairlines showing through --------------------------- */

/* The overlay sits inside the header, so the header's bottom border and the
   navigation row's top border fall outside it and read as a pale line across
   the bottom of the panel. Both are hidden while the panel is open, and
   restored when it closes. */

.cf-search-open .site-header,
.cf-search-open .site-header .storefront-primary-navigation {
	border-color: transparent;
}

.cf-search-open .storefront-primary-navigation { border-top-color: transparent; }


/* =========================================================================
   The journal
   =========================================================================
   Index, topic archives, single posts and comments. Built from the approved
   mockups: a full width feature band on the first page of the index, two up
   cards, a single column post at a measure the type is scaled to match, and a
   comment thread whose author badge comes from core's own bypostauthor class.
   ====================================================================== */

/* --- shared pieces ------------------------------------------------------ */

.cf-byline {
	font-family: var(--cf-mono);
	font-size: .74rem;
	letter-spacing: .03em;
	color: var(--cf-ink);
	display: flex;
	flex-wrap: wrap;
	margin: .35rem 0 0;
}

.cf-byline span + span::before {
	content: "|";
	color: var(--cf-line-strong);
	margin: 0 .55rem;
}

.cf-byline a { color: inherit; text-decoration: none; }
.cf-byline a:hover { color: var(--cf-indigo); text-decoration: underline; }

.cf-thumb--blank {
	display: block;
	width: 100%;
	aspect-ratio: 16 / 10;
	background: linear-gradient(135deg, #ecebf6 0%, #dcdaf0 55%, #cfcdea 100%);
	border-radius: var(--cf-radius-sm);
}

/* Chips are links to real archives, so they carry link resets. */
/* .cf-chip is already defined once, for the licence term on a product card.
   Redefining it here changed the size and display of those chips as a side
   effect, so only what the journal actually adds is stated: the link states a
   chip needs when it is a link to an archive, the count, and the current one. */
a.cf-chip { text-decoration: none; }
a.cf-chip:hover { border-color: var(--cf-indigo); }
.cf-chip small { font-size: .85em; opacity: .55; margin-left: .35em; }
.cf-chip.is-on { background: var(--cf-indigo); border-color: var(--cf-indigo); color: #fff; }
.cf-chip.is-on small { opacity: .75; }

/* --- index and archive head --------------------------------------------- */

/* The same top padding .cf-page-head carries, so the eyebrow starts at one
   height across the site.

   It used to arrive by accident. .cf-page-head has always had this padding and
   .cf-blog-head never did, and the gap was made up by an extra bottom margin
   on the hand drawn crumb that sat between them. That crumb is gone, and with
   it the compensation, which left the blog and topic eyebrows sitting 19px
   higher than everywhere else. Carried by the container now, so it holds
   whether or not a trail is above it. */
.cf-blog-head { padding-top: var(--cf-head-pad-top); margin: 0 0 1.2rem; }
.cf-blog-title {
	font-family: var(--cf-display);
	font-size: 2.6rem;
	font-weight: 700;
	letter-spacing: -.02em;
	line-height: 1.1;
	color: var(--cf-ink);
	margin: .2rem 0 0;
}
.cf-blog-intro { max-width: 40em; color: var(--cf-body); font-size: 1.05rem; margin: .7rem 0 0; }
.cf-topics {
	display: flex;
	gap: .5rem;
	flex-wrap: wrap;
	align-items: center;
	margin: 0 0 1.6rem;
	padding: 0 0 1.1rem;
	border-bottom: 1px solid var(--cf-line);
}
.cf-topics .cf-eyebrow { margin: 0 .5rem 0 0; }

/* --- the feature band --------------------------------------------------- */

/* Full bleed, so it breaks out of the content column the way the home hero
   does. The parent's clearfix pseudo elements are registered above. */
.cf-feature {
	background: linear-gradient(160deg, #14105c 0%, var(--cf-indigo) 70%, #3b3bc0 100%);
	color: #fff;
	padding: 3.2rem 0;
	margin: 0;
	overflow: hidden;
}

/* Printed above .col-full, so the gap below it belongs to the content that
   follows rather than to the band, exactly as the home hero does it. */
.cf-feature + #content.site-content,
.cf-feature + .site-content { padding-top: 2.6rem; }

.cf-feature__inner {
	max-width: 1180px;
	margin: 0 auto;
	padding: 0 1.4rem;
	box-sizing: border-box;
	display: grid;
	grid-template-columns: 1.1fr .9fr;
	gap: 2.4rem;
	align-items: center;
}

.cf-feature .cf-eyebrow { color: var(--cf-lilac); }
.cf-feature .cf-eyebrow::before { background: var(--cf-lilac); }

.cf-feature__title {
	font-family: var(--cf-display);
	font-size: 2.4rem;
	font-weight: 700;
	letter-spacing: -.02em;
	line-height: 1.12;
	margin: .3rem 0 .7rem;
}
/* The hover stays white and underlines rather than turning lilac. Lilac on
   this gradient measures 4.05 to 1 against the middle stop and less against
   the lightest, so it passed for large text and failed for anything smaller,
   which is a poor rule to leave in a stylesheet. White is 8.16 to 1 at the
   band's lightest point, and an underline signals the link without leaning on
   colour at all. */
.cf-feature__title a { color: #fff; text-decoration: none; }
.cf-feature__title a:hover,
.cf-feature__title a:focus-visible {
	color: #fff;
	text-decoration: underline;
	text-decoration-thickness: 2px;
	text-underline-offset: 4px;
}

.cf-feature__excerpt { color: rgba(255, 255, 255, .78); font-size: 1.05rem; max-width: 34em; margin: 0; }
.cf-feature .cf-byline { color: rgba(255, 255, 255, .72); margin-top: 1rem; }
.cf-feature .cf-byline a { color: inherit; }
.cf-feature .cf-byline span + span::before { color: rgba(255, 255, 255, .35); }
.cf-feature__cta { margin: 1.4rem 0 0; }

.cf-feature__media { display: block; }
.cf-feature__media img {
	display: block;
	width: 100%;
	height: auto;
	border-radius: 12px;
	box-shadow: 0 24px 60px rgba(0, 0, 0, .35);
}

/* --- the post grid ------------------------------------------------------ */

.cf-post-grid {
	display: grid;
	grid-template-columns: repeat(2, minmax(0, 1fr));
	gap: 1.6rem;
}

.cf-post-card {
	background: #fff;
	border: 1px solid var(--cf-line);
	border-radius: var(--cf-radius);
	padding: 1.1rem;
	box-shadow: var(--cf-shadow);
	display: grid;
	grid-template-columns: 8.5rem 1fr;
	gap: 1.1rem;
	align-items: start;
	margin: 0;
	transition: box-shadow .16s ease, translate .16s ease, border-color .16s ease;
}

/* The same lift the product cards use, so a card behaves the same way whatever
   is printed on it. focus-within is here and not on hover alone, because the
   card is reached by keyboard as well as by pointer and the state should not
   depend on which. */
.cf-post-card:hover,
.cf-post-card:focus-within,
.cf-keep__card:hover,
.cf-keep__card:focus-within {
	box-shadow: var(--cf-shadow-lift);
	border-color: var(--cf-line-strong);
	translate: 0 -2px;
}

/* The whole card is the click target. One real link, the title, is stretched
   over the card with a pseudo element, rather than wrapping the card in a
   second anchor: nested links are invalid, and two links to the same post
   makes a screen reader read the destination twice. The card is the
   positioning context for that stretch. */
.cf-post-card { position: relative; }

.cf-post-card__title a::after {
	content: "";
	position: absolute;
	inset: 0;
	border-radius: var(--cf-radius);
}

/* The byline's author link sits inside the area the stretch covers, so it
   needs lifting above it or it stops being clickable. Anything else added to
   a card that is meant to be its own link needs the same treatment. */
.cf-post-card .cf-byline a {
	position: relative;
	z-index: 1;
}

.cf-post-card__media { display: block; }
.cf-post-card__media img,
.cf-post-card__media .cf-thumb--blank {
	display: block;
	width: 100%;
	aspect-ratio: 1 / 1;
	object-fit: cover;
	border-radius: var(--cf-radius-sm);
}

.cf-post-card__title {
	font-family: var(--cf-display);
	font-size: 1.1rem;
	font-weight: 600;
	letter-spacing: -.015em;
	line-height: 1.28;
	margin: .45rem 0 .3rem;
	/* Post titles carry long unbreakable runs; break them rather than spill. */
	overflow-wrap: anywhere;
}
.cf-post-card__title a { color: var(--cf-ink); text-decoration: none; }
.cf-post-card__title a:hover { color: var(--cf-indigo); }
.cf-post-card__excerpt { font-size: .92rem; color: var(--cf-body); margin: .55rem 0 0; }

/* --- paging ------------------------------------------------------------- */

.cf-pager {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 1rem;
	flex-wrap: wrap;
	margin: 2.6rem 0 0;
	padding-top: 1.6rem;
	border-top: 1px solid var(--cf-line);
}
.cf-pager__pages { display: flex; gap: .4rem; align-items: center; flex-wrap: wrap; }
.cf-pager__pages .page-numbers {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-width: 2.3rem;
	height: 2.3rem;
	padding: 0 .6rem;
	border: 1px solid var(--cf-line);
	border-radius: var(--cf-radius-sm);
	font-family: var(--cf-mono);
	font-size: .8rem;
	letter-spacing: .04em;
	color: var(--cf-ink);
	text-decoration: none;
	background: #fff;
}
.cf-pager__pages a.page-numbers:hover { border-color: var(--cf-indigo); color: var(--cf-indigo); }
.cf-pager__pages .page-numbers.current { background: var(--cf-indigo); border-color: var(--cf-indigo); color: #fff; }
.cf-pager__pages .page-numbers.dots { border: 0; background: none; color: var(--cf-muted); min-width: 1rem; }
.cf-pager__of { font-family: var(--cf-mono); font-size: .74rem; letter-spacing: .06em; color: var(--cf-muted); }

/* --- single post -------------------------------------------------------- */

/* The measure and the type size move together. 960px of column at 20.8px is
   about 68 characters a line, which sits inside the comfortable range; the
   same column at the old 16.6px would have run to 90. The size eases down on
   phones, where the large setting cut lines to 31 characters. */
.single-post .cf-post,
.single-post .cf-keep,
.single-post .cf-comments { max-width: 60rem; margin-left: auto; margin-right: auto; }

.cf-post__head { padding: 1.4rem 0 .6rem; margin-bottom: 1.4rem; }
.cf-post__head .cf-eyebrow a { color: inherit; text-decoration: none; }
.cf-post__title {
	font-family: var(--cf-display);
	font-size: 3rem;
	font-weight: 700;
	letter-spacing: -.02em;
	line-height: 1.08;
	color: var(--cf-ink);
	margin: .3rem 0 .8rem;
	overflow-wrap: anywhere;
}
.cf-post__lead { font-size: 1.22rem; color: var(--cf-body); max-width: 34em; margin: .9rem 0 0; }

.cf-post__hero { margin: 0; }
.cf-post__hero img {
	display: block;
	width: 100%;
	height: auto;
	aspect-ratio: 16 / 6.5;
	object-fit: cover;
	border-radius: var(--cf-radius);
}
.cf-post__hero figcaption {
	font-family: var(--cf-mono);
	font-size: .68rem;
	letter-spacing: .05em;
	color: var(--cf-muted);
	margin: .6rem 0 0;
}

/* --- author band -------------------------------------------------------- */

.cf-author-band {
	display: grid;
	grid-template-columns: 56px 1fr auto;
	gap: 1rem;
	align-items: center;
	padding: 1.2rem 1.5rem;
	margin: 1.6rem 0 2.4rem;
	background: #fff;
	border: 1px solid var(--cf-line);
	border-radius: var(--cf-radius);
	box-shadow: var(--cf-shadow);
}

.cf-author__avatar {
	width: 56px;
	height: 56px;
	border-radius: 50%;
	display: block;
}
/* Avatars can be switched off site wide, in which case core returns nothing
   and this stands in rather than leaving a gap in the grid. */
.cf-author__avatar--blank { background: linear-gradient(135deg, var(--cf-indigo), var(--cf-lilac)); }

.cf-author__name { font-family: var(--cf-display); font-weight: 600; color: var(--cf-ink); font-size: 1rem; text-decoration: none; }
.cf-author__name:hover { color: var(--cf-indigo); }
.cf-author__bio { font-size: .9rem; color: var(--cf-body); margin: .15rem 0 0; }
.cf-author__when {
	font-family: var(--cf-mono);
	font-size: .72rem;
	letter-spacing: .04em;
	color: var(--cf-muted);
	text-align: right;
	white-space: nowrap;
	margin: 0;
}
.cf-author__when span { display: block; }
.cf-author__when b { color: var(--cf-indigo); font-weight: 500; }

/* --- post body ---------------------------------------------------------- */

.cf-post__body {
	font-size: clamp(1.04rem, .86rem + .8vw, 1.3rem);
	line-height: 1.68;
	color: var(--cf-body);
}
.cf-post__body h2 {
	font-family: var(--cf-display);
	font-size: 1.75rem;
	color: var(--cf-ink);
	letter-spacing: -.015em;
	margin: 2.6rem 0 .8rem;
	scroll-margin-top: 1.5rem;
}
.cf-post__body p { margin: 0 0 1.1rem; }
.cf-post__body blockquote {
	margin: 1.4rem 0;
	padding: .2rem 0 .2rem 1.2rem;
	border-left: 3px solid var(--cf-lilac);
	font-family: var(--cf-display);
	font-size: 1.4rem;
	font-weight: 500;
	color: var(--cf-ink);
	letter-spacing: -.01em;
}
.cf-post__body pre {
	font-family: var(--cf-mono);
	font-size: .88rem;
	line-height: 1.6;
	background: var(--cf-ink);
	color: #e6e6f2;
	padding: 1rem 1.2rem;
	border-radius: var(--cf-radius-sm);
	overflow: auto;
	margin: 0 0 1.3rem;
}
.cf-post__body code {
	font-family: var(--cf-mono);
	font-size: .88em;
	background: var(--cf-tint);
	border: 1px solid var(--cf-line);
	border-radius: 4px;
	padding: .08em .38em;
	color: var(--cf-indigo);
}
.cf-post__body pre code { background: none; border: 0; padding: 0; color: inherit; }

/* --- contents box ------------------------------------------------------- */

.cf-toc {
	background: var(--cf-tint);
	border: 1px solid var(--cf-line);
	border-radius: var(--cf-radius);
	padding: 1.1rem 1.3rem;
	margin: 0 0 1.6rem;
}
.cf-toc .cf-eyebrow { margin: 0 0 .7rem; }
.cf-toc ol { list-style: none; margin: 0; padding: 0; counter-reset: cftoc; }
.cf-toc li { counter-increment: cftoc; margin: 0 0 .45rem; }
.cf-toc li:last-child { margin-bottom: 0; }
.cf-toc a { font-family: var(--cf-display); font-weight: 500; font-size: .95rem; color: var(--cf-ink); text-decoration: none; }
.cf-toc a::before {
	content: counter(cftoc, decimal-leading-zero);
	font-family: var(--cf-mono);
	font-size: .7rem;
	color: var(--cf-muted);
	margin-right: .7rem;
	letter-spacing: .08em;
}
.cf-toc a:hover { color: var(--cf-indigo); }

/* --- tags and similar --------------------------------------------------- */

.cf-post__tags {
	display: flex;
	gap: .5rem;
	flex-wrap: wrap;
	align-items: center;
	margin: 2.4rem 0 0;
	padding: 1.4rem 0;
	border-top: 1px solid var(--cf-line);
	border-bottom: 1px solid var(--cf-line);
}
.cf-post__tags .cf-eyebrow { margin: 0 .4rem 0 0; }

.cf-keep { margin: 3rem 0 0; padding-top: 2.2rem; border-top: 1px solid var(--cf-line); }
.cf-keep__grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 1.4rem; margin-top: 1.3rem; }
.cf-keep__card {
	background: #fff;
	border: 1px solid var(--cf-line);
	border-radius: var(--cf-radius);
	padding: .9rem;
	box-shadow: var(--cf-shadow);
	display: flex;
	flex-direction: column;
	gap: .6rem;
	text-decoration: none;
	transition: box-shadow .16s ease, translate .16s ease, border-color .16s ease;
}
.cf-keep__card img,
.cf-keep__card .cf-thumb--blank {
	display: block;
	width: 100%;
	aspect-ratio: 16 / 10;
	object-fit: cover;
	border-radius: var(--cf-radius-sm);
}
.cf-keep__card .cf-chip { align-self: flex-start; }
.cf-keep__card b {
	font-family: var(--cf-display);
	font-weight: 600;
	font-size: .98rem;
	line-height: 1.28;
	color: var(--cf-ink);
	letter-spacing: -.01em;
	overflow-wrap: anywhere;
}
.cf-keep__card small { font-family: var(--cf-mono); font-size: .66rem; letter-spacing: .05em; color: var(--cf-muted); margin-top: auto; }
.cf-keep__card:hover b { color: var(--cf-indigo); }

/* --- comments ----------------------------------------------------------- */

.cf-comments { margin: 3.2rem 0 0; padding-top: 2.2rem; border-top: 1px solid var(--cf-line); }
.cf-comments__count { font-family: var(--cf-display); font-size: 1.5rem; color: var(--cf-ink); margin: .2rem 0 1.6rem; letter-spacing: -.015em; }
.cf-comment-list { list-style: none; margin: 0; padding: 0; }
.cf-comment-list li { padding: 0 0 1.5rem; }
.cf-comment-list .children { list-style: none; margin: 1.1rem 0 0; padding: 1.1rem 0 0 1.4rem; border-left: 2px solid var(--cf-line); }

.cf-comment { display: grid; grid-template-columns: 44px 1fr; gap: 1rem; align-items: start; }
.cf-comment__avatar { width: 44px; height: 44px; border-radius: 50%; display: block; }
.cf-comment__meta { margin: 0; }
.cf-comment__who { font-family: var(--cf-display); font-weight: 600; color: var(--cf-ink); font-size: .98rem; }
.cf-comment__when { font-family: var(--cf-mono); font-size: .7rem; letter-spacing: .05em; color: var(--cf-muted); margin-left: .6rem; text-decoration: none; }

/* Core already marks the post author's own comments. The badge is a rule
   rather than markup, so it can never name the wrong person. */
.cf-comment-list .bypostauthor > .cf-comment .cf-comment__who::after {
	content: "Author";
	font-family: var(--cf-mono);
	font-size: .58rem;
	letter-spacing: .12em;
	text-transform: uppercase;
	background: var(--cf-indigo);
	color: #fff;
	border-radius: 4px;
	padding: .16em .45em;
	margin-left: .5rem;
	vertical-align: 2px;
}

.cf-comment__text { margin: .45rem 0 .5rem; font-size: .97rem; color: var(--cf-body); line-height: 1.6; }
.cf-comment__text p { margin: 0 0 .8rem; }
.cf-comment__text p:last-child { margin-bottom: 0; }
.cf-comment__held { font-family: var(--cf-mono); font-size: .7rem; letter-spacing: .06em; color: var(--cf-indigo); margin: .3rem 0; }
.cf-comment__reply a {
	font-family: var(--cf-mono);
	font-size: .68rem;
	letter-spacing: .1em;
	text-transform: uppercase;
	color: var(--cf-indigo);
	text-decoration: none;
}

.cf-comment-form,
.comment-respond {
	margin: .6rem 0 0;
	padding: 1.6rem;
	background: var(--cf-tint);
	border: 1px solid var(--cf-line);
	border-radius: var(--cf-radius);
}
.cf-comment-form__title,
.comment-reply-title { font-family: var(--cf-display); font-size: 1.15rem; color: var(--cf-ink); margin: .2rem 0 .3rem; }
.cf-comment-form__note { font-size: .88rem; color: var(--cf-muted); margin: 0 0 1.1rem; }
.comment-respond label {
	display: block;
	font-family: var(--cf-mono);
	font-size: .66rem;
	letter-spacing: .12em;
	text-transform: uppercase;
	color: var(--cf-muted);
	margin: 0 0 .35rem;
}
.comment-respond input[type="text"],
.comment-respond input[type="email"],
.comment-respond input[type="url"],
.comment-respond textarea {
	width: 100%;
	font-family: inherit;
	font-size: var(--cf-field-size);
	color: var(--cf-ink);
	background: #fff;
	border: 1px solid var(--cf-line-strong);
	border-radius: var(--cf-radius-sm);
	padding: .62rem .8rem;
}
.comment-respond textarea { min-height: 7.5rem; resize: vertical; }
.comment-respond .comment-form-author,
.comment-respond .comment-form-email { display: inline-block; width: calc(50% - .45rem); vertical-align: top; }
.comment-respond .comment-form-author { margin-right: .8rem; }
.comment-respond .comment-form-cookies-consent {
	display: flex;
	gap: .5rem;
	align-items: flex-start;
	font-size: .82rem;
	color: var(--cf-muted);
	max-width: 26em;
}
.comment-respond .comment-form-cookies-consent input { width: auto; margin-top: .2rem; }
.comment-respond .comment-form-cookies-consent label {
	font-family: inherit;
	font-size: .82rem;
	letter-spacing: 0;
	text-transform: none;
	color: var(--cf-muted);
	margin: 0;
}
.comment-respond .form-submit { margin: 1rem 0 0; }

/* --- the journal on phones ---------------------------------------------- */

@media (max-width: 1023px) {
	.cf-post-grid { grid-template-columns: 1fr; }
	.cf-keep__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (max-width: 767px) {

	.cf-feature { padding: 2.4rem 0; }
	.cf-feature__inner { grid-template-columns: 1fr; gap: 1.4rem; }
	.cf-feature__title { font-size: 1.7rem; }
	.cf-blog-title { font-size: 1.95rem; }

	.cf-post-card { grid-template-columns: 1fr; gap: .8rem; }
	.cf-post-card__media img,
	.cf-post-card__media .cf-thumb--blank { aspect-ratio: 16 / 9; }

	.cf-post__title { font-size: 1.95rem; }
	.cf-post__lead { font-size: 1.05rem; }
	.cf-post__body h2 { font-size: 1.4rem; }
	.cf-post__body blockquote { font-size: 1.15rem; }
	.cf-post__hero img { aspect-ratio: 16 / 10; }

	.cf-author-band { grid-template-columns: 48px 1fr; gap: .85rem; padding: 1rem; }
	.cf-author__avatar { width: 48px; height: 48px; }
	.cf-author__when {
		grid-column: 1 / -1;
		text-align: left;
		padding-top: .5rem;
		border-top: 1px solid var(--cf-line);
		margin-top: .3rem;
	}
	.cf-author__when span { display: inline; }
	.cf-author__when span + span::before { content: "|"; color: var(--cf-line-strong); margin: 0 .5rem; }

	.cf-keep__grid { grid-template-columns: 1fr; }
	.cf-pager { justify-content: center; }
	.cf-pager__of { width: 100%; text-align: center; }

	.cf-comment { grid-template-columns: 36px 1fr; gap: .8rem; }
	.cf-comment__avatar { width: 36px; height: 36px; }
	.cf-comment-list .children { padding-left: 1rem; }
	.comment-respond .comment-form-author,
	.comment-respond .comment-form-email { display: block; width: 100%; margin-right: 0; }
}

/* =========================================================================
   Motion
   Four scroll-driven animations, approved from the prototype. Every rule
   animates transform, opacity or clip-path only, so none can cause layout
   shift. Each sits behind @supports, so a browser without scroll timelines
   gets the static page, and the markup is identical either way, so search
   and AI crawlers read exactly what they read without it.

   The animation shorthand resets animation-timeline, so the timeline is
   always declared after it. Reordering those two lines silently disables
   the effect.

   view() resolves against the nearest scroll container, and overflow: hidden
   on any ancestor creates one. The page wrapper rule near the top of this
   file exists so that ancestor is the viewport. If a plugin ever wraps the
   content in something with overflow hidden, these animations stop, and the
   cure is overflow: clip on that wrapper, not a change here.
   ====================================================================== */

/* 1. Reading progress. Fixed 2px line, filled by the document's scroll. */
.cf-progress {
	position: fixed;
	top: 0;
	left: 0;
	width: 100%;
	height: 2px;
	background: linear-gradient(90deg, var(--cf-indigo), var(--cf-lilac));
	transform-origin: 0 50%;
	transform: scaleX(0);
	z-index: 200;
	pointer-events: none;
}
@supports (animation-timeline: scroll()) {
	.cf-progress {
		animation: cf-progress linear both;
		animation-timeline: scroll(root block);
	}
}
@keyframes cf-progress { from { transform: scaleX(0); } to { transform: scaleX(1); } }

/* 2. Cards rise as they enter view. Progress is tied to the element's own
   position, so anything already in view at load is simply at 100%: nothing
   above the fold ever starts hidden. */
@supports (animation-timeline: view()) {
	.cf-post-card,
	ul.products li.product,
	.cf-steps .cf-card {
		animation: cf-rise linear both;
		animation-timeline: view(block);
		animation-range: entry 0% entry 45%;
	}
}
@keyframes cf-rise {
	from { opacity: 0; transform: translateY(14px); }
	to   { opacity: 1; transform: none; }
}

/* 3. The mapping strip resolves. Each destination is revealed by a clip-path
   wipe with a caret at its edge, one row after the next, as the strip comes
   into view. The badge and the footer arrive last. */
@supports (animation-timeline: view()) {
	.cf-map { view-timeline: --cf-map block; }
	.cf-map__dst {
		position: relative;
		animation: cf-resolve linear both;
		animation-timeline: --cf-map;
	}
	.cf-map__dst::after {
		content: "";
		position: absolute;
		right: -.35em;
		top: .15em;
		bottom: .15em;
		width: 2px;
		background: var(--cf-indigo);
		animation: cf-caret linear both;
		animation-timeline: --cf-map;
	}
	.cf-map__row:nth-child(2) .cf-map__dst,
	.cf-map__row:nth-child(2) .cf-map__dst::after { animation-range: entry 20% entry 45%; }
	.cf-map__row:nth-child(3) .cf-map__dst,
	.cf-map__row:nth-child(3) .cf-map__dst::after { animation-range: entry 35% entry 60%; }
	.cf-map__row:nth-child(4) .cf-map__dst,
	.cf-map__row:nth-child(4) .cf-map__dst::after { animation-range: entry 50% entry 75%; }
	.cf-map__row:nth-child(5) .cf-map__dst,
	.cf-map__row:nth-child(5) .cf-map__dst::after { animation-range: entry 65% entry 90%; }
	.cf-map__badge,
	.cf-map__foot {
		animation: cf-rise linear both;
		animation-timeline: --cf-map;
		animation-range: entry 80% cover 20%;
	}
}
@keyframes cf-resolve {
	from { clip-path: inset(0 100% 0 0); }
	to   { clip-path: inset(0 0 0 0); }
}
@keyframes cf-caret {
	0%   { opacity: 1; transform: translateX(-100%); }
	95%  { opacity: 1; }
	100% { opacity: 0; transform: translateX(0); }
}

/* 5. The eyebrow dash extends from nothing as its section enters. */
@supports (animation-timeline: view()) {
	.cf-eyebrow::before {
		transform-origin: 0 50%;
		animation: cf-dash linear both;
		animation-timeline: view(block);
		animation-range: entry 0% entry 35%;
	}
}
@keyframes cf-dash { from { transform: scaleX(0); } to { transform: scaleX(1); } }

@media (prefers-reduced-motion: reduce) {
	.cf-progress { animation: none; transform: scaleX(0); display: none; }
	.cf-post-card, ul.products li.product, .cf-steps .cf-card, .cf-map__dst, .cf-map__badge, .cf-map__foot, .cf-eyebrow::before {
		animation: none !important; opacity: 1; transform: none; clip-path: none;
	}
	.cf-map__dst::after { display: none; }
}


/* =========================================================================
   Search results
   ====================================================================== */

.cf-search-head { border-bottom: 0; padding-bottom: 0; margin-bottom: 1.6rem; }

.cf-search-big { display: flex; gap: .7rem; margin: 1.2rem 0 0; max-width: 44em; }

.cf-search-big input {
	flex: 1 1 auto;
	min-width: 0;
	font-family: inherit;
	font-size: 1.05rem;
	color: var(--cf-ink);
	background: #fff;
	border: 1px solid var(--cf-line-strong);
	border-radius: var(--cf-radius-sm);
	padding: .85rem 1rem;
}

.cf-search-big .button { padding: .85rem 1.4rem; flex: 0 0 auto; }

.cf-scopes {
	display: flex;
	gap: .5rem;
	flex-wrap: wrap;
	align-items: center;
	margin: 1.6rem 0 0;
	padding: 0 0 1rem;
	border-bottom: 1px solid var(--cf-line);
}

.cf-search-group-block { margin: 2.2rem 0 0; }

.cf-search-pages { list-style: none; margin: 1rem 0 0; padding: 0; border-top: 1px solid var(--cf-line); }
.cf-search-pages li { border-bottom: 1px solid var(--cf-line); }
.cf-search-pages a { display: block; padding: .9rem 0; text-decoration: none; }
.cf-search-pages b {
	font-family: var(--cf-display);
	font-weight: 600;
	font-size: 1.02rem;
	color: var(--cf-ink);
	display: block;
	letter-spacing: -.01em;
}
.cf-search-pages small { display: block; font-size: .9rem; color: var(--cf-body); margin-top: .2rem; }
.cf-search-pages a:hover b { color: var(--cf-indigo); }

.cf-search-empty {
	background: var(--cf-tint);
	border: 1px solid var(--cf-line);
	border-radius: var(--cf-radius);
	padding: 1.8rem;
	margin: 2rem 0 0;
}
.cf-search-empty h2 { font-family: var(--cf-display); font-size: 1.3rem; color: var(--cf-ink); margin: 0 0 .5rem; }
.cf-search-empty p { margin: 0 0 1rem; color: var(--cf-body); }
.cf-search-empty__links { display: flex; gap: .5rem; flex-wrap: wrap; margin: 0; }

/* The suggestion panel groups licences and articles under headings. */
.cf-search-group {
	font-family: var(--cf-mono);
	font-size: .62rem;
	letter-spacing: .14em;
	text-transform: uppercase;
	color: var(--cf-muted);
	margin: .5rem 0 .2rem;
	padding: 0 .9rem;
}
.cf-search-group:first-child { margin-top: 0; }

@media (max-width: 767px) {
	.cf-search-big { flex-direction: column; }
	.cf-search-group-block .products.columns-4 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}


/* =========================================================================
   Not found
   ====================================================================== */

.cf-404 {
	background: linear-gradient(160deg, #14105c 0%, var(--cf-indigo) 70%, #3b3bc0 100%);
	color: #fff;
	padding: 4.5rem 0;
	margin: 0;
	overflow: hidden;
}

/* Printed above .col-full, so the space below it belongs to the content that
   follows, the same arrangement the home hero and the blog feature use. */
.cf-404 + #content.site-content,
.cf-404 + .site-content { padding-top: 2rem; }

.cf-404__inner {
	max-width: 1180px;
	margin: 0 auto;
	padding: 0 1.4rem;
	box-sizing: border-box;
	text-align: center;
}

.cf-404 .cf-eyebrow { color: var(--cf-lilac); justify-content: center; }
.cf-404 .cf-eyebrow::before { background: var(--cf-lilac); }

.cf-404__num {
	font-family: var(--cf-display);
	font-weight: 700;
	font-size: 7rem;
	line-height: .9;
	letter-spacing: -.04em;
	margin: .4rem 0 0;
}

.cf-404__num span { color: var(--cf-lilac); }

.cf-404__title {
	font-family: var(--cf-display);
	font-size: 2rem;
	font-weight: 700;
	letter-spacing: -.02em;
	color: #fff;
	margin: 1rem 0 .7rem;
}

.cf-404__lead {
	color: rgba(255, 255, 255, .78);
	font-size: 1.05rem;
	max-width: 34em;
	margin: 0 auto;
}

/* auto on the sides, not 0. A margin shorthand here would replace the centring
   the rule above sets and drop the button against the left edge. */
.cf-404__cta { margin: 1.8rem auto 0; max-width: none; }
.cf-404__cta .button { padding: .9rem 1.8rem; font-size: 1rem; }

.cf-404-routes { text-align: center; padding: 0 0 2.6rem; }
.cf-404-routes .cf-eyebrow { justify-content: center; margin-bottom: .9rem; }
.cf-404-routes__links { display: flex; gap: .6rem; flex-wrap: wrap; justify-content: center; margin: 0; }

@media (max-width: 767px) {
	.cf-404 { padding: 3rem 0; }
	.cf-404__num { font-size: 4.5rem; }
	.cf-404__title { font-size: 1.6rem; }
}


/* =========================================================================
   About
   =========================================================================
   The founder cards and the mission band. The band reuses the 404 gradient,
   so the three full width indigo blocks on this site are one treatment.
   ====================================================================== */

/* The About page prints its heading inside the content, so the theme's own
 * .cf-page-head is suppressed. Its 1.2rem top padding is what puts the eyebrow
 * 27.2px below the header on every other page, so this block has to supply it.
 * Measured, not guessed: content starts 8px down on both, and 8 + 19.2 = 27.2. */
.ab-lead {
	max-width: 44em;
	padding-top: var(--cf-head-pad-top);
}
.ab-lead h1 {
	font-family: var(--cf-display);
	font-size: 2.8rem;
	font-weight: 700;
	letter-spacing: -.025em;
	line-height: 1.08;
	color: var(--cf-ink);
	margin: .3rem 0 1rem;
}
/* The eyebrow is a paragraph, so a bare p selector here was overriding its
 * size, colour and margin: it rendered at 18.4px in body grey instead of
 * 11.52px in indigo. Excluding it restores all three from .cf-eyebrow rather
 * than restating them, so the two cannot drift apart. */
.ab-lead p:not(.cf-eyebrow) { font-size: 1.15rem; color: var(--cf-body); margin: 0 0 1rem; }

.ab-facts {
	display: grid;
	grid-template-columns: repeat(4, 1fr);
	gap: 1.2rem;
	margin: 2.4rem 0 0;
	padding: 1.4rem 0;
	border-top: 1px solid var(--cf-line);
	border-bottom: 1px solid var(--cf-line);
}
.ab-fact dt {
	font-family: var(--cf-mono);
	font-size: .66rem;
	letter-spacing: .12em;
	text-transform: uppercase;
	color: var(--cf-muted);
	margin: 0 0 .3rem;
}
.ab-fact dd { font-family: var(--cf-display); font-weight: 600; font-size: 1rem; color: var(--cf-ink); margin: 0; }

/* This band lives inside the page content, so unlike the hero and the 404 it
 * cannot be printed outside .col-full. It breaks out with viewport width
 * margins instead. That is safe here only because the page wrapper carries
 * overflow-x: clip: the band overhangs by the scrollbar width and is clipped
 * rather than producing a sideways scroll.
 *
 * The bottom margin is stated rather than left to collapse. Without it the
 * heading of the next section rode up onto the band's edge. */
.ab-band {
	background: linear-gradient(160deg, #14105c 0%, var(--cf-indigo) 70%, #3b3bc0 100%);
	color: #fff;
	padding: 3rem 0;
	margin: 2.4rem calc(50% - 50vw) 2.6rem;
	width: 100vw;
	overflow: hidden;
}
.ab-band__inner {
	max-width: 1180px;
	margin: 0 auto;
	padding: 0 1.4rem;
	box-sizing: border-box;
	display: grid;
	grid-template-columns: 1fr 1fr;
	gap: 2.4rem;
}
.ab-band h2 { font-family: var(--cf-display); font-size: 1.5rem; color: #fff; margin: .4rem 0 .6rem; letter-spacing: -.015em; }
/* Same trap as .ab-lead p. The colour is deliberate on the dark band and the
 * eyebrow has its own lighter indigo there, but margin: 0 was flattening the
 * eyebrow's spacing below it too. */
.ab-band p:not(.cf-eyebrow) { color: rgba(255, 255, 255, .8); margin: 0; }
.ab-band .cf-eyebrow { color: var(--cf-lilac); }
.ab-band .cf-eyebrow::before { background: var(--cf-lilac); }

.ab-founders { display: grid; grid-template-columns: 1fr 1fr; gap: 1.6rem; margin: 1.4rem 0 0; }

/* The section that follows the band opens the column again. */
.ab-band + .cf-section,
.ab-band + * { margin-top: 0; }
.ab-founder {
	background: #fff;
	border: 1px solid var(--cf-line);
	border-radius: var(--cf-radius);
	box-shadow: var(--cf-shadow);
	overflow: hidden;
}
.ab-founder img { display: block; width: 100%; aspect-ratio: 1 / 1; object-fit: cover; }
.ab-founder__body { padding: 1.2rem 1.3rem 1.4rem; }
.ab-founder__name { font-family: var(--cf-display); font-weight: 700; font-size: 1.2rem; color: var(--cf-ink); margin: 0; letter-spacing: -.015em; }
.ab-founder__role {
	font-family: var(--cf-mono);
	font-size: .68rem;
	letter-spacing: .1em;
	text-transform: uppercase;
	color: var(--cf-indigo);
	margin: .3rem 0 .7rem;
}
.ab-founder__bio { font-size: .95rem; color: var(--cf-body); margin: 0 0 .8rem; }
.ab-founder__creds { list-style: none; margin: 0; padding: 0; }
.ab-founder__creds li {
	display: flex;
	align-items: baseline;
	gap: .55rem;
	font-family: var(--cf-mono);
	font-size: .72rem;
	color: var(--cf-muted);
	padding: .18rem 0;
}
/* The bullet is drawn rather than typed. A dash character here would be an
   em dash, which is not used anywhere on this site, and a CSS escape for one
   is easy to get wrong in a build script. */
.ab-founder__creds li::before {
	content: "";
	flex: 0 0 10px;
	height: 2px;
	background: var(--cf-indigo);
	border-radius: 1px;
	transform: translateY(-3px);
}
.ab-founder__links { display: flex; gap: 1.1rem; flex-wrap: wrap; margin: .8rem 0 0; }
.ab-founder__link {
	font-family: var(--cf-display);
	font-weight: 600;
	font-size: .85rem;
	color: var(--cf-indigo);
	text-decoration: none;
	margin: 0;
}
.ab-founder__link::after {
	content: "";
	display: inline-block;
	width: .5em;
	height: .5em;
	border-right: 1.5px solid currentColor;
	border-top: 1.5px solid currentColor;
	transform: rotate(45deg) translateY(-1px);
	margin-left: .4em;
}

.ab-cta {
	background: var(--cf-tint);
	border: 1px solid var(--cf-line);
	border-radius: var(--cf-radius);
	padding: 1.8rem;
	margin: 2.4rem 0 0;
	text-align: center;
}
.ab-cta h2 { font-family: var(--cf-display); font-size: 1.35rem; color: var(--cf-ink); margin: 0 0 .5rem; }
.ab-cta p { color: var(--cf-body); margin: 0 auto 1.2rem; max-width: 34em; }

@media (max-width: 767px) {
	.ab-lead h1 { font-size: 2rem; }
	.ab-founders, .ab-band__inner { grid-template-columns: 1fr; }
	.ab-facts { grid-template-columns: 1fr 1fr; }
}


/* =========================================================================
   WooCommerce messages
   =========================================================================
   Storefront paints these in its own $success green, which is the last place
   on the site still wearing the parent's palette and which collided with the
   indigo button sitting inside it. The surface is the theme's tint; green is
   kept for the mark and the edge, because a confirmation that carries no
   success colour at all reads as an ordinary notice.
   ====================================================================== */

.woocommerce-message {
	background: var(--cf-tint);
	border: 1px solid var(--cf-line);
	border-left: 3px solid #0f834d;
	border-radius: var(--cf-radius);
	color: var(--cf-ink);
	padding: 1rem 1.2rem;
	margin: 0 0 1.6rem;
	display: flex;
	align-items: center;
	gap: .9rem;
	font-size: .98rem;
	position: static;
	list-style: none;
}

.woocommerce-message::before {
	content: "";
	flex: 0 0 20px;
	height: 20px;
	border-radius: 50%;
	background: #0f834d url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M20 6L9 17l-5-5' fill='none' stroke='white' stroke-width='3.2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center / 13px no-repeat;
}

/* Storefront prints the button before the message text and floats it right.
   In a flex row that put the action ahead of the sentence, so the button is
   ordered after the text instead: message first, then what to do about it. */
/* Storefront strips this button back for its own green bar:
 *
 *   .woocommerce-message .button
 *     { float: right; padding: 0; background: none; color: #fff; box-shadow: none }
 *
 * White on green works. White on this theme's tint card is 1.08:1, which is
 * text you cannot see. The background, padding and shadow are all restored
 * here, not just the padding, which is what 1.66.0 got wrong. */
.woocommerce-message .button,
.woocommerce-message a.button,
.woocommerce-info .button,
.woocommerce-info a.button,
.woocommerce-error .button,
.woocommerce-error a.button {
	float: none;
	order: 3;
	margin-left: auto;
	padding: .5rem 1rem;
	font-size: .88rem;
	white-space: nowrap;
	background: var(--cf-indigo);
	color: #fff;
	border-radius: var(--cf-radius-sm);
	box-shadow: none;
}

.woocommerce-message .button:hover,
.woocommerce-message a.button:hover,
.woocommerce-info .button:hover,
.woocommerce-info a.button:hover,
.woocommerce-error .button:hover,
.woocommerce-error a.button:hover {
	background: var(--cf-indigo-deep);
	color: #fff;
	opacity: 1;
}

.woocommerce-message a,
.woocommerce-info a,
.woocommerce-error a { color: var(--cf-indigo); }

/* Storefront paints notice links white and drops them to 0.7 opacity on hover,
 * which is right for its own notice: a solid coloured bar. This theme rebuilds
 * the notice as a light tint card, so that hover renders near-white on
 * near-white and the link disappears under the cursor.
 *
 * The base colour was already overridden above; only the hover was missed. The
 * opacity has to be reset too, or the colour lands at 70% and still fails.
 *
 * a.button:hover is deliberately not matched here. Notice buttons keep their
 * own solid indigo fill and white text, set further up. */
.woocommerce-info a:not(.button):hover,
.woocommerce-info a:not(.button):focus,
.woocommerce-error a:not(.button):hover,
.woocommerce-error a:not(.button):focus {
	color: var(--cf-indigo-deep);
	opacity: 1;
	text-decoration: underline;
}

/* WooCommerce dims a classic button to opacity .25 while it works, which puts
 * white on indigo at 1.59:1. The button stays at full strength and the spinner
 * carries the state instead, the same decision taken for the block buttons on
 * the cart and checkout. */
.woocommerce .button.loading,
.woocommerce a.button.loading,
.woocommerce button.button.loading,
.woocommerce input.button.loading {
	opacity: 1;
	color: #fff;
}

.woocommerce .button.loading::after {
	opacity: .9;
}

/* The "View cart" link WooCommerce adds beside a product button after a
 * successful add.
 *
 * "It inherits nothing useful" was wrong, and that is what broke it. Storefront
 * paints .added_to_cart as a solid button from the Customizer button colours,
 * background-color #14105c with white text, at one class. The colour stated
 * here carries two classes and an element, so it won and the background did
 * not, leaving --cf-indigo text on #14105c. Measured at 1.63:1, and 1.90:1 on
 * hover. Unreadable, on every product card including the home page.
 *
 * This is meant to be a quiet link under the button, not a second solid button
 * competing with the first, so the box Storefront draws is removed rather than
 * recoloured. Indigo on the card measures 10.25:1, deep indigo on hover
 * 16.69:1. The background and border are reset on hover as well, because
 * Storefront states that separately and it would otherwise reappear under the
 * cursor. */
.woocommerce a.added_to_cart {
	display: inline-block;
	margin-top: .5rem;
	padding: 0;
	background: none;
	border: 0;
	box-shadow: none;
	font-family: var(--cf-display);
	font-weight: 600;
	font-size: .88rem;
	line-height: 1.5;
	color: var(--cf-indigo);
	text-align: center;
	text-decoration: underline;
}

.woocommerce a.added_to_cart:hover,
.woocommerce a.added_to_cart:focus {
	background: none;
	border: 0;
	box-shadow: none;
	color: var(--cf-indigo-deep);
	text-decoration: underline;
}

@media (max-width: 600px) {
	.woocommerce-message,
	.woocommerce-info,
	.woocommerce-error { flex-wrap: wrap; }
	.woocommerce-message .button,
	.woocommerce-info .button,
	.woocommerce-error .button { margin-left: 0; width: 100%; text-align: center; }
}


/* =========================================================================
   Checkout trust
   =========================================================================
   Placed where the research says these work: a row of promises above the form
   and the security block with the order summary. The same signals in the
   footer measure close to nothing.
   ====================================================================== */

.cf-ic {
	display: inline-block;
	background-repeat: no-repeat;
	background-position: center;
	background-size: contain;
	flex: 0 0 auto;
}

.cf-ic--bolt { background-image: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%232f2fa2' stroke-width='1.9' stroke-linecap='round' stroke-linejoin='round'><path d='M13 2L4 14h7l-1 8 9-12h-7z'/></svg>"); }
.cf-ic--shield { background-image: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%232f2fa2' stroke-width='1.9' stroke-linecap='round' stroke-linejoin='round'><path d='M12 3l7 3v6c0 4-3 7-7 9-4-2-7-5-7-9V6z'/><path d='M9 12l2 2 4-4'/></svg>"); }
.cf-ic--back { background-image: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%232f2fa2' stroke-width='1.9' stroke-linecap='round' stroke-linejoin='round'><path d='M3 12a9 9 0 1 0 3-6.7'/><path d='M3 4v5h5'/></svg>"); }
.cf-ic--lock { background-image: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%232f2fa2' stroke-width='1.9' stroke-linecap='round' stroke-linejoin='round'><rect x='4.5' y='10.5' width='15' height='10' rx='2.2'/><path d='M8.2 10.5V7.6a3.8 3.8 0 0 1 7.6 0v2.9'/><path d='M12 14.4v2.3'/></svg>"); }
.cf-ic--robot { background-image: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%232f2fa2' stroke-width='1.9' stroke-linecap='round' stroke-linejoin='round'><rect x='4' y='8' width='16' height='11' rx='2.5'/><path d='M12 5v3'/><circle cx='12' cy='4' r='1.2'/><path d='M9 13h.01M15 13h.01'/><path d='M9.5 16.2h5'/></svg>"); }

.cf-assure {
	display: grid;
	grid-template-columns: repeat(3, 1fr);
	gap: 1.4rem;
	margin: 0 0 1.8rem;
	padding: 1.1rem 1.3rem;
	background: var(--cf-tint);
	border: 1px solid var(--cf-line);
	border-radius: var(--cf-radius);
}
.cf-assure > div { display: flex; gap: .7rem; align-items: flex-start; }
.cf-assure .cf-ic { width: 22px; height: 22px; margin-top: .05rem; }
.cf-assure b { display: block; font-family: var(--cf-display); font-weight: 600; font-size: .92rem; color: var(--cf-ink); line-height: 1.3; }
.cf-assure span { display: block; font-size: .82rem; color: var(--cf-muted); margin-top: .15rem; line-height: 1.45; }

.cf-secure {
	padding: 1rem;
	border: 1px solid var(--cf-line);
	border-radius: var(--cf-radius);
	background: var(--cf-tint);
	margin: 1.6rem 0 0;
}
.cf-secure__row { display: flex; gap: .6rem; align-items: flex-start; font-size: .86rem; color: var(--cf-body); margin: 0 0 .7rem; line-height: 1.45; }
.cf-secure__row .cf-ic { width: 18px; height: 18px; margin-top: .1rem; }
.cf-secure__row:last-of-type { margin-bottom: 0; }
.cf-secure__pay { margin: .9rem 0 0; padding-top: .8rem; border-top: 1px solid var(--cf-line); }
.cf-pay-strip { display: block; max-width: 100%; height: auto; }
.cf-secure__help {
	font-family: var(--cf-mono);
	font-size: .7rem;
	color: var(--cf-muted);
	margin: .9rem 0 0;
	padding-top: .8rem;
	border-top: 1px solid var(--cf-line);
	line-height: 1.6;
}
.cf-secure__help a { color: var(--cf-indigo); text-decoration: none; }

/* The security block stays where PHP printed it: after the checkout, never
   inside it.
 *
 * It used to be moved into the totals column by script. That put a foreign
 * node inside the Checkout block, which is React, and React owns that subtree:
 * on a desktop the render had settled before the move so it survived, but on a
 * real phone the block re-rendered afterwards and the node was discarded,
 * which is why it appeared when a desktop window was narrowed and never on an
 * actual device. The same interference is the likeliest reason the Place Order
 * button changed column. Nothing here touches WooCommerce's tree any more.
 *
 * On a wide screen it is aligned to the width of the summary column so it
 * still reads as belonging to it. To have it sit flush under the totals
 * instead, place [cesarfeed_checkout_trust] inside the Checkout block in the
 * editor: that is the supported way in, and the automatic copy switches itself
 * off when the page places one by hand. */
@media (min-width: 1024px) {
	.woocommerce-checkout .cf-secure {
		max-width: 34%;
		margin-left: auto;
	}
}

/* Placed inside the Checkout block by shortcode. It is a child of the summary
   column now, so the 34% that makes an appended copy line up with that column
   would instead squeeze it to a third of the column and wrap the text one word
   per line. Full width of its container, and no auto margin. */
.wp-block-woocommerce-checkout .cf-secure,
.wp-block-woocommerce-checkout-totals-block .cf-secure {
	max-width: none;
	margin: 1rem 0 0;
	width: auto;
}

/* Kept for a page that places the shortcode inside the block by hand, where
   the block is a child of the summary column rather than a sibling of the
   checkout. */
/* Qualified with the body class on purpose. The fallback rule above is
   .woocommerce-checkout .cf-secure, so a bare .cf-secure--stitched loses to it
   on specificity and the block stays at 34% after being moved. */
.woocommerce-checkout .cf-secure--stitched {
	max-width: none;
	margin: .8rem 0 0;
}

/* Google allows its badge to be hidden only while the reCAPTCHA branding
   stays visible in the flow, which the security block above provides.
   visibility rather than display: display none takes the element out of the
   layout tree and has been observed to make the script misbehave. */
.grecaptcha-badge { visibility: hidden !important; }

@media (max-width: 767px) {
	.cf-assure { grid-template-columns: 1fr; gap: 1rem; }
	.woocommerce-checkout .cf-secure { max-width: none; }
}


/* =========================================================================
   Contact
   =========================================================================
   The page's own content is the form shortcode and nothing else. Everything
   here is the wrapper the theme puts around it, so the form ID stays editable
   per site without a template change.
   ====================================================================== */

.cf-ic--phone { background-image: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%232f2fa2' stroke-width='1.9' stroke-linecap='round' stroke-linejoin='round'><path d='M5 4h4l2 5-2.5 1.5a12 12 0 0 0 5 5L15 13l5 2v4a1 1 0 0 1-1 1A16 16 0 0 1 4 5a1 1 0 0 1 1-1z'/></svg>"); }
.cf-ic--mail { background-image: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%232f2fa2' stroke-width='1.9' stroke-linecap='round' stroke-linejoin='round'><rect x='3' y='5' width='18' height='14' rx='2'/><path d='M3.5 6.5l8.5 6 8.5-6'/></svg>"); }
.cf-ic--pin { background-image: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%232f2fa2' stroke-width='1.9' stroke-linecap='round' stroke-linejoin='round'><path d='M12 21s7-5.6 7-11a7 7 0 1 0-14 0c0 5.4 7 11 7 11z'/><circle cx='12' cy='10' r='2.6'/></svg>"); }
.cf-ic--cart { background-image: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%232f2fa2' stroke-width='1.9' stroke-linecap='round' stroke-linejoin='round'><path d='M3 4h2l2.4 11.2a2 2 0 0 0 2 1.6h7.6a2 2 0 0 0 2-1.6L21 8H6'/><circle cx='10' cy='20' r='1.2'/><circle cx='18' cy='20' r='1.2'/></svg>"); }
.cf-ic--wrench { background-image: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%232f2fa2' stroke-width='1.9' stroke-linecap='round' stroke-linejoin='round'><path d='M14.7 6.3a4.5 4.5 0 0 0 5.9 5.9L21 12l-9 9-3-3 9-9z'/><path d='M6.5 17.5l-2 2'/></svg>"); }
.cf-ic--spark { background-image: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%232f2fa2' stroke-width='1.9' stroke-linecap='round' stroke-linejoin='round'><path d='M12 3l2.1 5.4L19.5 10l-5.4 1.6L12 17l-2.1-5.4L4.5 10l5.4-1.6z'/></svg>"); }

.ct-lead { max-width: 42em; }
.ct-lead h2 {
	font-family: var(--cf-display);
	font-size: 1.6rem;
	font-weight: 700;
	letter-spacing: -.02em;
	color: var(--cf-ink);
	margin: 0 0 .6rem;
}
.ct-lead p { font-size: 1.05rem; color: var(--cf-body); margin: 0; }

.ct-routes { display: grid; grid-template-columns: repeat(3, 1fr); gap: 1rem; margin: 1.8rem 0 0; }
.ct-route {
	background: #fff;
	border: 1px solid var(--cf-line);
	border-radius: var(--cf-radius);
	padding: 1.1rem 1.2rem;
	box-shadow: var(--cf-shadow);
	display: block;
	text-decoration: none;
	transition: box-shadow .16s ease, translate .16s ease, border-color .16s ease;
}
/* translate, not transform: the scroll-driven rise animates transform on
   cards, and an animation outranks a hover rule on the property it owns. */
.ct-route:hover,
.ct-route:focus-within {
	box-shadow: var(--cf-shadow-lift);
	border-color: var(--cf-line-strong);
	translate: 0 -2px;
}
.ct-route .cf-ic { display: block; width: 22px; height: 22px; margin-bottom: .6rem; }
.ct-route b { display: block; font-family: var(--cf-display); font-weight: 600; font-size: 1rem; color: var(--cf-ink); letter-spacing: -.01em; }
.ct-route span { display: block; font-size: .88rem; color: var(--cf-body); margin-top: .25rem; line-height: 1.45; }
.ct-route em {
	display: block;
	font-family: var(--cf-mono);
	font-size: .68rem;
	letter-spacing: .06em;
	color: var(--cf-indigo);
	font-style: normal;
	margin-top: .6rem;
}

.ct-grid { display: grid; grid-template-columns: 1.3fr .85fr; gap: 2.4rem; margin: 2.4rem 0 0; align-items: start; }

/* The white card the form sits in. The fields inside are WPForms' own, so
   nothing here restyles them; the card only provides the surround. */
.ct-form {
	background: #fff;
	border: 1px solid var(--cf-line);
	border-radius: var(--cf-radius);
	padding: 1.6rem;
	box-shadow: var(--cf-shadow);
}
.ct-form > h2 { font-family: var(--cf-display); font-size: 1.35rem; color: var(--cf-ink); margin: 0 0 .3rem; }
.ct-form > p { color: var(--cf-body); font-size: .92rem; margin: 0 0 1.2rem; }

.ct-privacy {
	display: flex;
	gap: .55rem;
	align-items: flex-start;
	font-size: .8rem;
	color: var(--cf-muted);
	margin: 1rem 0 0;
	line-height: 1.5;
}
.ct-privacy .cf-ic { width: 16px; height: 16px; margin-top: .1rem; }

.ct-card { background: var(--cf-tint); border: 1px solid var(--cf-line); border-radius: var(--cf-radius); padding: 1.4rem; }
.ct-card h2 { font-family: var(--cf-display); font-size: 1.15rem; color: var(--cf-ink); margin: 0 0 1rem; }
.ct-item { display: flex; gap: .7rem; align-items: flex-start; margin: 0 0 1rem; }
.ct-item:last-child { margin-bottom: 0; }
.ct-item .cf-ic { width: 20px; height: 20px; margin-top: .1rem; }
.ct-item b {
	display: block;
	font-family: var(--cf-mono);
	font-size: .64rem;
	letter-spacing: .12em;
	text-transform: uppercase;
	color: var(--cf-muted);
}
.ct-item span { display: block; font-size: .95rem; color: var(--cf-ink); margin-top: .15rem; line-height: 1.45; }
.ct-item a { color: var(--cf-indigo); text-decoration: none; }

@media (max-width: 860px) {
	.ct-grid, .ct-routes { grid-template-columns: 1fr; }
}


/* =========================================================================
   Cart, checkout and account: the parent's spacing and button states
   =========================================================================
   INACTIVE BLOCK RULES LIVE IN THIS SECTION. Anything below that targets a
   .wc-block-* or .wp-block-woocommerce-* class does nothing on this store as
   of 1.78.0: Cart, Checkout and My Account are classic shortcode pages on
   www.cesarfeed.com, so those classes are never rendered.

   They are kept rather than deleted because they are tested, they cost a few
   KB, and WooCommerce may yet push the block cart and checkout onto stores
   that have not opted in. If that happens nothing needs rebuilding, the
   blocks go back on the page and these rules take effect again.

   The is-sticky override that used to sit at the end of this section was
   removed in 1.78.0. It existed only to stop the trust block drifting away
   from an appended copy of itself, which is not a problem the classic
   checkout has: the classic order review is not sticky at all.
   ====================================================================== */

/* Storefront hangs ms(8) of padding under the centred heading on these three
   pages, which is 6.854em, about 110px at a 16px root, on top of the heading's
   own margin. That is the empty band between the title and the contents.
   Qualified with body so it outranks the parent rule rather than relying on
   stylesheet order: both selectors are otherwise three classes deep, the same
   .storefront-full-width-content trap this theme has hit before. */
body.storefront-full-width-content.woocommerce-cart .entry-header,
body.storefront-full-width-content.woocommerce-checkout .entry-header,
body.storefront-full-width-content.woocommerce-account .entry-header {
	padding-bottom: 1.6rem;
}

/* WooCommerce hides a block button's label while it is loading, so the button
 * loses its visible name at the point of purchase, and because visibility:
 * hidden also drops the text out of the accessibility tree a screen reader is
 * left with an unnamed button.
 *
 * 1.71.0 targeted only the adjacent-sibling form with .wc-block-components-
 * spinner. That was too narrow: the cart's Proceed to Checkout uses
 * .wc-block-components-button__spinner instead, so the rule never matched
 * there and the label went on disappearing. Both spinner names are covered
 * now, and the label is stated unconditionally rather than only when a
 * particular sibling happens to be present.
 *
 * !important is deliberate. WooCommerce ships the hiding rule in its own
 * per-block stylesheets, which are enqueued per page and can load after the
 * theme, and it writes some of them body-qualified so specificity alone is a
 * tie. Losing this one means an unnamed button on the checkout, which is not
 * a race worth entering. */
body .wc-block-components-button__text {
	visibility: visible !important;
}

body .wc-block-components-button .wc-block-components-spinner,
body .wc-block-components-button .wc-block-components-button__spinner,
body .wc-block-cart__submit-button .wc-block-components-spinner,
body .wc-block-cart__submit-button .wc-block-components-button__spinner {
	position: relative;
	flex: 0 0 auto;
	width: 1.15em;
	height: 1.15em;
	margin: 0 .6em 0 0;
	inset: auto;
	transform: none;
}

/* Close the gap under Place Order on a narrow screen, where the block follows
   the checkout directly rather than sitting beside a taller column. */
@media (max-width: 1023px) {
	.woocommerce-checkout .wp-block-woocommerce-checkout {
		margin-bottom: 0;
		padding-bottom: 0;
	}

	.woocommerce-checkout .cf-secure {
		margin-top: 1rem;
	}
}


/* =========================================================================
   Classic notices: info and error
   =========================================================================
   1.66.0 brought .woocommerce-message onto the theme's palette but left its
   two siblings on Storefront's, so a store that shows all three was wearing
   two different design languages: an indigo-and-tint confirmation next to a
   flat blue information bar and a red error bar, both in the parent's shape.
   These match the confirmation, and keep a colour on the mark and the left
   edge so the three stay distinguishable at a glance.
   ====================================================================== */

.woocommerce-info,
.woocommerce-error {
	background: var(--cf-tint);
	border: 1px solid var(--cf-line);
	border-radius: var(--cf-radius);
	color: var(--cf-ink);
	padding: 1rem 1.2rem;
	margin: 0 0 1.6rem;
	display: flex;
	align-items: center;
	gap: .9rem;
	font-size: .98rem;
	position: static;
	list-style: none;
}

.woocommerce-info { border-left: 3px solid var(--cf-indigo); }
.woocommerce-error { border-left: 3px solid #b3261e; }

/* WooCommerce prints the error list as <ul class="woocommerce-error"> with one
   <li> per problem, so the flex row above would lay several errors side by
   side. The list is forced back into a column and the mark aligned to the
   first line rather than the centre of a tall block. */
ul.woocommerce-error {
	display: block;
	padding-left: 3.1rem;
	position: relative;
}

ul.woocommerce-error li { margin: 0 0 .35rem; }
ul.woocommerce-error li:last-child { margin-bottom: 0; }

.woocommerce-info::before,
.woocommerce-error::before {
	content: "";
	flex: 0 0 20px;
	height: 20px;
	border-radius: 50%;
	background-position: center;
	background-repeat: no-repeat;
	background-size: 13px;
}

.woocommerce-info::before {
	background-color: var(--cf-indigo);
	background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M12 11v6' fill='none' stroke='white' stroke-width='3.2' stroke-linecap='round'/%3E%3Ccircle cx='12' cy='6.6' r='1.9' fill='white'/%3E%3C/svg%3E");
}

.woocommerce-error::before {
	background-color: #b3261e;
	background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M12 6v7.4' fill='none' stroke='white' stroke-width='3.2' stroke-linecap='round'/%3E%3Ccircle cx='12' cy='18' r='1.9' fill='white'/%3E%3C/svg%3E");
}

ul.woocommerce-error::before {
	position: absolute;
	left: 1.2rem;
	top: 1.05rem;
	width: 20px;
}


/* =========================================================================
   My Account, classic
   =========================================================================
   www.cesarfeed.com serves My Account, Cart and Checkout from the classic
   shortcodes, and staging now does the same. Before 1.78.0 this theme had one
   rule for the whole account area, the page-header padding, so every one of
   these pages was rendering on Storefront's own styling: floated columns,
   the parent's link colours, and inputs that matched nothing else on the
   site.

   Layout is flex rather than the parent's floats, with row-gap held at zero
   on purpose. WooCommerce prints an empty .woocommerce-notices-wrapper as a
   sibling of the navigation on the login view, and a row gap would reserve
   space above the content for a notice that is not there.
   ====================================================================== */

/* Storefront prints a second, usually empty, .woocommerce wrapper directly
   inside .col-full for notices raised before the content. Notices carry their
   own bottom margin, so the wrapper needs none of its own. */
.woocommerce-account .col-full > .woocommerce { margin: 0; }

.woocommerce-account .entry-content > .woocommerce {
	display: flex;
	flex-wrap: wrap;
	align-items: flex-start;
	column-gap: 2rem;
	row-gap: 0;
}

/* Default for any child of this container: full width, its own row. The two
   rules below deliberately carry the same parent chain plus an element name,
   which puts them above this one on specificity rather than on source order.
   1.78.0 wrote them with two classes against this rule's three, so both lost
   and the account page rendered as a stack instead of two columns. */
.woocommerce-account .entry-content > .woocommerce > * {
	flex: 1 1 100%;
	min-width: 0;
}

/* --- Account navigation ------------------------------------------------- */

.woocommerce-account .entry-content > .woocommerce > nav.woocommerce-MyAccount-navigation {
	flex: 0 0 clamp(230px, 20%, 300px);
	float: none;
	width: auto;
	margin: 0;
}

/* No inner padding: the selected row is a band across the full width of the
   column, not a pill floating inside it. The corners are nested on the first
   and last links below rather than by clipping the list with overflow, which
   would also have clipped the focus ring. */
.woocommerce-account .woocommerce-MyAccount-navigation ul {
	margin: 0;
	padding: 0;
	list-style: none;
	background: #fff;
	border: 1px solid var(--cf-line);
	border-radius: var(--cf-radius);
	box-shadow: var(--cf-shadow);
}

.woocommerce-account .woocommerce-MyAccount-navigation li {
	margin: 0;
	padding: 0;
	border: 0;
	list-style: none;
}

/* Every rule from here down carries the ul li.woocommerce-MyAccount-navigation-
   link chain on purpose. Storefront writes its own at
   .woocommerce-account .woocommerce-MyAccount-navigation ul li a, which is the
   same two classes with one more element, so a shorter selector here would
   lose on specificity rather than win on source order. Same failure that put
   the account page in one column in 1.78.0. */
/* 1.55rem of horizontal padding is not arbitrary: it is the .55rem the list
   used to carry plus the 1rem the link used to carry. The fill is the link's
   background, so it runs to the card edge either way, but the label and the
   icon keep the inset they had before the list padding was removed. Changing
   one without the other is what moved the labels in 1.81.0. */
.woocommerce-account .woocommerce-MyAccount-navigation ul li.woocommerce-MyAccount-navigation-link a {
	display: block;
	padding: .85rem 1.55rem;
	border-radius: 0;
	font-family: var(--cf-display);
	font-size: .94rem;
	font-weight: 600;
	color: var(--cf-body);
	text-decoration: none;
	text-transform: none;
}

.woocommerce-account .woocommerce-MyAccount-navigation ul li.woocommerce-MyAccount-navigation-link a:hover {
	background: var(--cf-tint);
	color: var(--cf-indigo);
}

.woocommerce-account .woocommerce-MyAccount-navigation ul li.woocommerce-MyAccount-navigation-link.is-active > a {
	background: var(--cf-indigo);
	color: #fff;
}

/* Storefront prints each tab icon as a Font Awesome glyph in a::before,
 * floated to the right of the label, at a weight that all but vanishes on a
 * white card.
 *
 * These are decorative: every icon repeats the text label beside it, so WCAG
 * 1.4.11 Non-text Contrast does not apply and their faintness was never a
 * conformance failure. It was a visibility problem, which is a different and
 * still worth fixing thing.
 *
 * Measured on the card background: --cf-muted 4.92:1, past both the 3:1
 * non-text floor and the 4.5:1 text one, and deliberately quieter than the
 * label's 10.32:1 so the icon stays secondary to the words. Hover lifts it to
 * indigo at 10.25:1, and white on the selected fill is 10.25:1.
 *
 * opacity is reset alongside colour because a translucent glyph would drag the
 * measured ratio back below whatever the colour claims. */
.woocommerce-account .woocommerce-MyAccount-navigation ul li.woocommerce-MyAccount-navigation-link a::before {
	color: var(--cf-muted);
	opacity: 1;
}

.woocommerce-account .woocommerce-MyAccount-navigation ul li.woocommerce-MyAccount-navigation-link a:hover::before {
	color: var(--cf-indigo);
	opacity: 1;
}

.woocommerce-account .woocommerce-MyAccount-navigation ul li.woocommerce-MyAccount-navigation-link.is-active a::before,
.woocommerce-account .woocommerce-MyAccount-navigation ul li.woocommerce-MyAccount-navigation-link.is-active a:hover::before {
	color: #fff;
	opacity: 1;
}

/* The card's radius is 12px drawn outside a 1px border, so the fill inside it
   nests at 11px. Applied to the links rather than the list because the fill
   lives on the link. */
.woocommerce-account .woocommerce-MyAccount-navigation ul li:first-child a {
	border-radius: calc(var(--cf-radius) - 1px) calc(var(--cf-radius) - 1px) 0 0;
}

.woocommerce-account .woocommerce-MyAccount-navigation ul li:last-child a {
	border-radius: 0 0 calc(var(--cf-radius) - 1px) calc(var(--cf-radius) - 1px);
}

/* The site-wide focus ring sits 3px outside the element. On a link that now
 * runs to the card's edge that ring lands on the border, and anything that
 * clipped the fill to the card would take the ring with it. Drawn inside
 * instead, and recoloured for the selected row: indigo on the plain rows is
 * 10.25:1, white inside the indigo fill is 10.25:1, and an indigo ring on an
 * indigo fill would have been invisible. */
.woocommerce-account .woocommerce-MyAccount-navigation ul li.woocommerce-MyAccount-navigation-link a:focus-visible {
	outline: 2px solid var(--cf-indigo);
	outline-offset: -3px;
}

.woocommerce-account .woocommerce-MyAccount-navigation ul li.woocommerce-MyAccount-navigation-link.is-active a:focus-visible {
	outline-color: #fff;
}

/* Storefront nests its account nav rules under .hentry .entry-content, so what
 * it actually ships is
 *
 *   .hentry .entry-content .woocommerce-MyAccount-navigation ul
 *     li.woocommerce-MyAccount-navigation-link a { padding: ms(-1) 0 }
 *
 * Four classes and three elements. Every rule above is three and three, so
 * Storefront won these declarations outright and no amount of source order
 * would have changed it. That is why the labels sat flush against the card
 * edge through 1.80.0, 1.81.0 and 1.82.0: the padding being edited was never
 * the padding in effect.
 *
 * Only the contested declarations are restated here, on Storefront's own chain
 * plus the body class. Everything above is uncontested and stands as written,
 * which also means it still applies if the markup ever loses .hentry, at which
 * point Storefront's rule stops matching too. Measured against Storefront
 * 4.6.2. */
.woocommerce-account .hentry .entry-content .woocommerce-MyAccount-navigation ul {
	margin-left: 0;
	border-top: 1px solid var(--cf-line);
}

.woocommerce-account .hentry .entry-content .woocommerce-MyAccount-navigation ul li {
	border-bottom: 1px solid var(--cf-line);
}

/* The card already draws the bottom edge. */
.woocommerce-account .hentry .entry-content .woocommerce-MyAccount-navigation ul li:last-child {
	border-bottom: 0;
}

.woocommerce-account .hentry .entry-content .woocommerce-MyAccount-navigation ul li.woocommerce-MyAccount-navigation-link a {
	padding: .85rem 1.55rem;
}

/* Log out is a different kind of action from the pages above it and is set
   apart, so it is harder to hit by mistake on a phone. */
.woocommerce-account .woocommerce-MyAccount-navigation-link--customer-logout {
	margin-top: .3rem;
	border-top: 1px solid var(--cf-line);
	padding-top: .3rem;
}

.woocommerce-account .woocommerce-MyAccount-navigation ul li.woocommerce-MyAccount-navigation-link--customer-logout a {
	color: var(--cf-muted);
}

/* --- Account content ---------------------------------------------------- */

.woocommerce-account .entry-content > .woocommerce > div.woocommerce-MyAccount-content {
	flex: 1 1 0;
	float: none;
	width: auto;
	min-width: 0;
	margin: 0;
}

.woocommerce-account .woocommerce-MyAccount-content > p { color: var(--cf-body); }
/* :not(.button) is the point of this rule, not a detail of it. Without it this
   selector is an exact specificity tie with .woocommerce-info a.button, two
   classes and one element each, and it sits later in the file, so it won the
   tie and painted every button label in account content indigo on an indigo
   background. That is what made Browse products look like an empty block on
   the Orders tab, and it would have caught every button added here later. */
.woocommerce-account .woocommerce-MyAccount-content a:not(.button) { color: var(--cf-indigo); }

@media (max-width: 860px) {
	.woocommerce-account .entry-content > .woocommerce > nav.woocommerce-MyAccount-navigation {
		flex: 1 1 100%;
		margin-bottom: 1.6rem;
	}

	/* A list of rows rather than the pill grid this used to be. Each row is a
	   whole-width target with an icon, the label and a chevron, which reads as
	   somewhere to go rather than a button to press.

	   Two column widths are fixed and the label takes the rest, so every label
	   starts at the same x whatever its length. That was the problem the pill
	   grid was solving badly: Payment methods, the longest label, dictated the
	   layout for everything else. */
	.woocommerce-account .woocommerce-MyAccount-navigation ul {
		display: block;
		padding: 0;
	}

	.woocommerce-account .hentry .entry-content .woocommerce-MyAccount-navigation ul li {
		border-bottom: 1px solid var(--cf-line);
	}

	.woocommerce-account .hentry .entry-content .woocommerce-MyAccount-navigation ul li:last-child {
		border-bottom: 0;
	}

	.woocommerce-account .woocommerce-MyAccount-navigation ul li.woocommerce-MyAccount-navigation-link a,
	.woocommerce-account .hentry .entry-content .woocommerce-MyAccount-navigation ul li.woocommerce-MyAccount-navigation-link a {
		display: grid;
		grid-template-columns: 2.4rem minmax(0, 1fr) 1.1rem;
		align-items: center;
		gap: .85rem;
		min-height: 3.5rem;
		padding: .55rem .85rem;
		text-align: left;
		border-radius: 0;
	}

	.woocommerce-account .woocommerce-MyAccount-navigation ul li:first-child a,
	.woocommerce-account .woocommerce-MyAccount-navigation ul li:last-child a {
		border-radius: 0;
	}

	/* Storefront's own float-right glyph has no place in a grid row. */
	.woocommerce-account .woocommerce-MyAccount-navigation ul li.woocommerce-MyAccount-navigation-link a::before {
		display: none;
	}

	.cf-acct-nav__icon {
		display: grid;
		place-items: center;
		width: 2.4rem;
		height: 2.4rem;
		background: var(--cf-tint);
		border-radius: var(--cf-radius-sm);
	}

	.cf-acct-nav__icon svg {
		width: 1.25rem;
		height: 1.25rem;
		fill: none;
		stroke: var(--cf-indigo);
		stroke-width: 1.6;
	}

	.cf-acct-nav__go svg {
		width: 1.1rem;
		height: 1.1rem;
		fill: none;
		stroke: var(--cf-muted);
		stroke-width: 1.8;
	}

	/* On the selected row the fill is indigo, so the icon and chevron have to
	   invert or they disappear into it. */
	.woocommerce-account .woocommerce-MyAccount-navigation ul li.woocommerce-MyAccount-navigation-link.is-active > a .cf-acct-nav__icon {
		background: rgba(255, 255, 255, .16);
	}

	.woocommerce-account .woocommerce-MyAccount-navigation ul li.woocommerce-MyAccount-navigation-link.is-active > a .cf-acct-nav__icon svg,
	.woocommerce-account .woocommerce-MyAccount-navigation ul li.woocommerce-MyAccount-navigation-link.is-active > a .cf-acct-nav__go svg {
		stroke: #fff;
	}

	/* Drilled into a section, the menu gives its place to the section. This is
	   the whole of the drill-in: the class comes from the URL, so back, forward,
	   bookmarks and shared links all land correctly with no state to keep. */
	.woocommerce-account .woocommerce-MyAccount-navigation.is-drilled {
		display: none;
	}

	.cf-acct-back {
		margin: 0 0 1rem;
	}

	.cf-acct-back a {
		display: inline-flex;
		align-items: center;
		gap: .35rem;
		min-height: 2.75rem;
		padding: .35rem .15rem;
		font-family: var(--cf-mono);
		font-size: .78rem;
		letter-spacing: .06em;
		text-transform: uppercase;
		color: var(--cf-indigo);
		text-decoration: none;
	}

	.cf-acct-back a:hover,
	.cf-acct-back a:focus-visible {
		color: var(--cf-indigo-deep);
		text-decoration: underline;
	}

	.cf-acct-back svg {
		width: 1.05rem;
		height: 1.05rem;
		fill: none;
		stroke: currentColor;
		stroke-width: 1.9;
	}

	/* Storefront floats each icon right at width ms(2) plus a left margin, about
	   32px of a cell that is only around 170px wide on a phone. Payment methods
	   needs more than what is left, which is what broke the row. The icons carry
	   no information the label beside them does not already state, so they are
	   dropped at this width and the label gets the whole cell. */
	.woocommerce-account .woocommerce-MyAccount-navigation ul li.woocommerce-MyAccount-navigation-link a::before {
		display: none;
	}

	/* Log out spans the full width and keeps its rule off the pages above it,
	   which is the same separation it has on the desktop column. */
	.woocommerce-account .woocommerce-MyAccount-navigation-link--customer-logout {
		grid-column: 1 / -1;
		border-top: 1px solid var(--cf-line);
		margin-top: .25rem;
		padding-top: .65rem;
	}
}

/* --- Login and register ------------------------------------------------- */

.woocommerce-account #customer_login.col2-set {
	display: grid;
	grid-template-columns: repeat(2, minmax(0, 1fr));
	gap: 1.6rem;
}

.woocommerce-account #customer_login .u-column1,
.woocommerce-account #customer_login .u-column2 {
	float: none;
	width: auto;
	margin: 0;
	padding: 1.7rem;
	background: #fff;
	border: 1px solid var(--cf-line);
	border-radius: var(--cf-radius);
	box-shadow: var(--cf-shadow);
}

.woocommerce-account #customer_login h2 {
	margin: 0 0 1.2rem;
	padding: 0;
	border: 0;
	font-family: var(--cf-display);
	font-size: 1.3rem;
	font-weight: 700;
	color: var(--cf-ink);
}

@media (max-width: 782px) {
	.woocommerce-account #customer_login.col2-set { grid-template-columns: 1fr; }
}

/* --- Standalone account forms ------------------------------------------- */

/* Lost password and set password both render as a bare form directly inside
   .woocommerce with no navigation beside them. Given a card and a ceiling on
   width so the fields do not run the full page. */
.woocommerce-account .woocommerce-ResetPassword {
	max-width: 34rem;
	/* Centred in the column. The card is capped at 34rem inside a content area
	   about twice that wide, so margin: 0 left it against the left edge with the
	   rest of the row empty, under a heading that runs the full width. */
	margin: 0 auto;
	padding: 1.7rem;
	background: #fff;
	border: 1px solid var(--cf-line);
	border-radius: var(--cf-radius);
	box-shadow: var(--cf-shadow);
}

.woocommerce-account .woocommerce-ResetPassword > p:first-child {
	margin-top: 0;
	color: var(--cf-body);
}

/* --- Contact form ---------------------------------------------------------

   The theme had no rules for this form at all, so it was taking Storefront's
   bare treatment: "background-color: rgb(95%, 95%, 95%); border: 0", which is
   the grey box. Every other form on the site is a white field with a hairline
   border, so this states the same values rather than inventing a third look.

   The checkbox group is a list, and lists inside content carry an indent so
   markers have somewhere to sit. This one has no markers, so it states its own
   spacing and is excluded from that rule above. */
.wpforms-container input[type="text"],
.wpforms-container input[type="email"],
.wpforms-container input[type="tel"],
.wpforms-container input[type="url"],
.wpforms-container input[type="number"],
.wpforms-container input[type="password"],
.wpforms-container textarea,
.wpforms-container select {
	width: 100%;
	font-family: inherit;
	font-size: var(--cf-field-size);
	color: var(--cf-ink);
	background: #fff;
	border: 1px solid var(--cf-line-strong);
	border-radius: var(--cf-radius-sm);
	padding: .62rem .8rem;
}

.wpforms-container ul {
	margin: 0;
	padding: 0;
	list-style: none;
}

.wpforms-container ul li {
	margin: 0 0 .4em;
}

/* --- Form controls ------------------------------------------------------
   These were written for the account page and scoped to .woocommerce-account,
   so none of them reached the login form WooCommerce prints on the checkout:
   the fields fell back to the parent's bare treatment with the label beside
   the input. The scope is widened here rather than copied, so the two forms
   cannot drift apart.
   ------------------------------------------------------------------------ */

/* Matched to the comment form, which is where this theme's input treatment
   was set. Checkbox labels are excluded from the small-caps label style:
   "Remember me" is a sentence sitting next to a control, not a field name. */
.woocommerce-account .woocommerce form .form-row label:not(.woocommerce-form__label-for-checkbox),
.woocommerce-checkout .woocommerce-form-login .form-row label:not(.woocommerce-form__label-for-checkbox),
.woocommerce-account .woocommerce form .form-row > label:not(.woocommerce-form__label-for-checkbox),
.woocommerce-checkout .woocommerce-form-login .form-row > label:not(.woocommerce-form__label-for-checkbox) {
	display: block;
	font-family: var(--cf-display);
	font-size: .66rem;
	font-weight: 600;
	letter-spacing: .12em;
	text-transform: uppercase;
	color: var(--cf-muted);
	margin: 0 0 .35rem;
}

.woocommerce-account .woocommerce .input-text,
.woocommerce-checkout .woocommerce-form-login .input-text,
.woocommerce-account .woocommerce input[type="text"],
.woocommerce-checkout .woocommerce-form-login input[type="text"],
.woocommerce-account .woocommerce input[type="email"],
.woocommerce-checkout .woocommerce-form-login input[type="email"],
.woocommerce-account .woocommerce input[type="tel"],
.woocommerce-checkout .woocommerce-form-login input[type="tel"],
.woocommerce-account .woocommerce input[type="password"],
.woocommerce-checkout .woocommerce-form-login input[type="password"] {
	width: 100%;
	font-family: inherit;
	font-size: var(--cf-field-size);
	color: var(--cf-ink);
	background: #fff;
	border: 1px solid var(--cf-line-strong);
	border-radius: var(--cf-radius-sm);
	padding: .62rem .8rem;
}

.woocommerce-account .woocommerce form .form-row { margin: 0 0 1.1rem; padding: 0; }
.woocommerce-account .woocommerce form .form-row:last-child { margin-bottom: 0; }

.woocommerce-account .woocommerce .required,
.woocommerce-checkout .woocommerce-form-login .required {
	color: #b3261e;
	border: 0;
	text-decoration: none;
}

/* Half-width pairs. The parent floats these; inline-block keeps them side by
   side without a float to clear, which matters because WooCommerce drops an
   empty <div class="clear"> between the pair and the submit row. */
.woocommerce-account .woocommerce form .form-row-first,
.woocommerce-checkout .woocommerce-form-login .form-row-first,
.woocommerce-account .woocommerce form .form-row-last,
.woocommerce-checkout .woocommerce-form-login .form-row-last {
	float: none;
	display: inline-block;
	vertical-align: top;
	width: calc(50% - .65rem);
}

.woocommerce-account .woocommerce form .form-row-first { margin-right: 1.1rem; }
.woocommerce-account .woocommerce form .clear { display: none; }

@media (max-width: 640px) {
	.woocommerce-account .woocommerce form .form-row-first,
	.woocommerce-checkout .woocommerce-form-login .form-row-first,
	.woocommerce-account .woocommerce form .form-row-last,
	.woocommerce-checkout .woocommerce-form-login .form-row-last {
		width: 100%;
		margin-right: 0;
	}
}

/* The checkout login form is core's global/form-login.php, which marks its two
 * rows first and last, meaning side by side. That suits the account page. Here
 * the card is 34rem and the submit button spans all of it, so half-width fields
 * beside a full-width button read as unfinished.
 *
 * It also repairs an incomplete edit. When the account form rules were widened
 * to reach this form, the pass only twinned selectors that ended a line. The
 * gutter rule and the .clear rule were each written on one line and stayed
 * scoped to the account page, so this form inherited the 50% width with neither
 * the gutter nor the clearing div suppressed, and the fields stacked at half
 * width instead of pairing. */
.woocommerce-checkout .woocommerce-form-login .form-row-first,
.woocommerce-checkout .woocommerce-form-login .form-row-last {
	display: block;
	width: 100%;
	margin-right: 0;
}

.woocommerce-checkout .woocommerce-form-login .clear {
	display: none;
}

.woocommerce-account .woocommerce .woocommerce-form__label-for-checkbox,
.woocommerce-checkout .woocommerce-form-login .woocommerce-form__label-for-checkbox {
	display: flex;
	align-items: center;
	gap: .5rem;
	font-size: .92rem;
	color: var(--cf-body);
	text-transform: none;
	letter-spacing: 0;
}

.woocommerce-account .woocommerce .woocommerce-form__input-checkbox { margin: 0; }

/* The parent floats these submit buttons to the right of the row they share
   with the remember-me checkbox, which on a narrow screen leaves a button
   hanging half off the field it belongs to. Full width of the card instead. */
.woocommerce-account .woocommerce-form-login__submit,
.woocommerce-checkout .woocommerce-form-login__submit,
.woocommerce-account .woocommerce-form-register__submit,
.woocommerce-checkout .woocommerce-form-register__submit,
.woocommerce-account .woocommerce-ResetPassword button[type="submit"],
.woocommerce-checkout .woocommerce-ResetPassword button[type="submit"] {
	float: none;
	display: block;
	width: 100%;
	margin: 1rem 0 0;
	text-align: center;
}

.woocommerce-account .woocommerce-LostPassword,
.woocommerce-checkout .woocommerce-LostPassword {
	margin: 1.1rem 0 0;
	font-size: .9rem;
}

.woocommerce-account .woocommerce-LostPassword a,
.woocommerce-checkout .woocommerce-LostPassword a { color: var(--cf-indigo); }

/* The register link inside the login message. The original template carried an
 * inline hex, which no stylesheet could override and which sat at 4.57:1 on
 * white. Indigo reaches 10.25:1 and follows the palette. */
.woocommerce-checkout .woocommerce-form-login .cf-register-link {
	color: var(--cf-indigo);
	font-weight: 600;
}

.woocommerce-checkout .woocommerce-form-login .cf-register-link:hover,
.woocommerce-checkout .woocommerce-form-login .cf-register-link:focus {
	color: var(--cf-indigo-deep);
	text-decoration: underline;
}

/* The message paragraph above the fields. */
.woocommerce-checkout .woocommerce-form-login > p:first-of-type {
	margin: 0 0 1.4rem;
	color: var(--cf-body);
	line-height: 1.6;
}

/* On the account page this form sits inside a card. On the checkout it is a
 * bare stack of rows under the notice, so it gets the same treatment here or
 * the fields read as loose and unowned. */
/* Icons, chevrons and the back link belong to the phone list only. Above 768px
   the account column is unchanged from what it was. */
@media (min-width: 768px) {
	.cf-acct-nav__icon,
	.cf-acct-nav__go,
	.cf-acct-back {
		display: none;
	}
}

/* --- In-page anchors -----------------------------------------------------
   A link to a section on the same page glides rather than jumps.

   Gated on prefers-reduced-motion. A long animated scroll is one of the
   clearest triggers for motion sensitivity, and the reader still arrives in
   exactly the same place with it off, just instantly.

   scroll-margin-top keeps the section's eyebrow clear of the top edge on
   arrival, so it reads as a section rather than as text starting mid-viewport.
   ------------------------------------------------------------------------ */

html {
	scroll-behavior: smooth;
}

@media (prefers-reduced-motion: reduce) {
	html {
		scroll-behavior: auto;
	}
}

.cf-section[id] {
	scroll-margin-top: 2.5rem;
}

/* The target takes focus so the next Tab continues from the section rather
   than from the button. That focus is programmatic, not the reader reaching
   for it, so no ring is drawn: :focus-visible still shows one if they ever
   tab to it themselves. */
.cf-section[tabindex="-1"]:focus:not(:focus-visible) {
	outline: none;
}

/* --- Account gate ---------------------------------------------------------
   Login and register in one card, one at a time. The two panels sit in the
   same box so the switcher swaps content rather than moving the customer to a
   different-looking page.

   Both panels ship visible with the switchers hidden; script inverts that. So
   the rules below must not assume a panel is ever hidden by CSS, or a page
   without JavaScript would show two stacked cards with no way between them.
   ------------------------------------------------------------------------ */

.cf-account-gate {
	max-width: 34rem;
	margin: 0 auto;
	background: #fff;
	border: 1px solid var(--cf-line);
	border-radius: var(--cf-radius);
	padding: 1.8rem;
}

.woocommerce-account .cf-account-gate h2 {
	font-size: 1.4rem;
	margin: 0 0 1.2rem;
}

.cf-account-gate__panel + .cf-account-gate__panel {
	margin-top: 2rem;
	padding-top: 2rem;
	border-top: 1px solid var(--cf-line);
}

/* Once script runs only one panel is on screen, so the divider between them
   would be a rule above nothing. */
.cf-account-gate[data-active] .cf-account-gate__panel[hidden] + .cf-account-gate__panel,
.cf-account-gate[data-active] .cf-account-gate__panel:not([hidden]) + .cf-account-gate__panel {
	margin-top: 0;
	padding-top: 0;
	border-top: 0;
}

.cf-account-gate__switch {
	margin: 1.4rem 0 0;
	text-align: center;
	font-size: .92rem;
	color: var(--cf-body);
}

/* A button, because it changes what is on screen rather than going anywhere.
   Styled as a link so it still reads as one. */
.cf-account-gate__link {
	background: none;
	border: 0;
	padding: 0;
	font: inherit;
	color: var(--cf-indigo);
	font-weight: 600;
	text-decoration: underline;
	cursor: pointer;
}

/* Storefront's generated CSS paints button:hover with a darkened button fill
 * and matching border. The base rule above clears those, but a hover rule that
 * only changed colour let the fill come back underneath, which put indigo text
 * on an indigo box. Every property the base state resets has to be reset in
 * every interactive state, not just the resting one. */
.cf-account-gate__link:hover,
.cf-account-gate__link:focus,
.cf-account-gate__link:focus-visible,
.cf-account-gate__link:active {
	background: none;
	border: 0;
	box-shadow: none;
	color: var(--cf-indigo-deep);
}

.cf-account-gate__link:focus-visible {
	outline: 2px solid var(--cf-focus);
	outline-offset: 3px;
	border-radius: 2px;
}

@media (max-width: 767px) {
	.cf-account-gate { padding: 1.3rem; }
}

/* --- Register page ------------------------------------------------------
   The [cesarfeed_register] shortcode wraps its output in .woocommerce-account
   .woocommerce so the account form styling above applies unchanged. Only the
   page-level framing is set here, since the standalone page has no two-column
   layout to sit inside.
   ------------------------------------------------------------------------ */

.cf-register {
	max-width: 34rem;
	margin: 0 auto;
}

.cf-register form.woocommerce-form-register {
	background: #fff;
	border: 1px solid var(--cf-line);
	border-radius: var(--cf-radius);
	padding: 1.8rem;
}

.cf-register .woocommerce-privacy-policy-text p {
	font-size: .85rem;
	line-height: 1.55;
	color: var(--cf-body);
}

.cf-register-note {
	max-width: 34rem;
	margin: 0 auto;
	text-align: center;
	color: var(--cf-body);
}

.woocommerce-checkout form.woocommerce-form-login {
	background: #fff;
	border: 1px solid var(--cf-line);
	border-radius: var(--cf-radius);
	padding: 1.6rem;
	margin: 0 auto 2rem;
	max-width: 34rem;
}

/* Logged out, this page is one card and a line of text while everything above
 * it runs full width, so a left-hugging column reads as a fault rather than a
 * choice.
 *
 * The line of text is the awkward part. Core prints it with
 * echo esc_html( apply_filters( 'woocommerce_checkout_must_be_logged_in_message', ... ) ),
 * so it is a bare text node and markup passed through that filter would be
 * escaped and shown literally. It cannot be wrapped, which leaves centring it
 * from its container and putting the container's other children back.
 *
 * Scoped to logged out, because once the customer is in, that same container
 * holds the entire checkout. */
body:not(.logged-in).woocommerce-checkout .woocommerce {
	text-align: center;
}

body:not(.logged-in).woocommerce-checkout .woocommerce .cf-assure,
body:not(.logged-in).woocommerce-checkout .woocommerce .cf-secure,
body:not(.logged-in).woocommerce-checkout .woocommerce .woocommerce-form-login-toggle,
body:not(.logged-in).woocommerce-checkout .woocommerce form.woocommerce-form-login {
	text-align: left;
}

.woocommerce-account .woocommerce-privacy-policy-text p {
	font-size: .85rem;
	line-height: 1.55;
	color: var(--cf-muted);
	margin: 0 0 1rem;
}

/* --- Account tables ----------------------------------------------------- */

/* NOT VERIFIED AGAINST CAPTURED MARKUP. Orders, downloads, addresses, payment
   methods and account details were written from WooCommerce's stock templates
   rather than from a saved copy of the rendered page, unlike everything above
   them in this section. Walk each tab and check before this ships to www. */

.woocommerce-account .woocommerce-MyAccount-content table.shop_table {
	width: 100%;
	margin: 0 0 1.6rem;
	background: #fff;
	border: 1px solid var(--cf-line);
	border-collapse: separate;
	border-spacing: 0;
	border-radius: var(--cf-radius);
	font-size: .94rem;
}

.woocommerce-account .woocommerce-MyAccount-content table.shop_table th {
	padding: .8rem .9rem;
	background: var(--cf-tint);
	border-bottom: 1px solid var(--cf-line);
	font-family: var(--cf-display);
	font-size: .68rem;
	font-weight: 700;
	letter-spacing: .1em;
	text-transform: uppercase;
	color: var(--cf-muted);
	text-align: left;
}

.woocommerce-account .woocommerce-MyAccount-content table.shop_table td {
	padding: .85rem .9rem;
	border-bottom: 1px solid var(--cf-line);
	color: var(--cf-body);
	vertical-align: middle;
}

.woocommerce-account .woocommerce-MyAccount-content table.shop_table tr:last-child td {
	border-bottom: 0;
}

.woocommerce-account .woocommerce-MyAccount-content table.shop_table a:not(.button) { color: var(--cf-indigo); }

/* --- Addresses and account details -------------------------------------- */

.woocommerce-account .woocommerce-Addresses.col2-set {
	display: grid;
	grid-template-columns: repeat(2, minmax(0, 1fr));
	gap: 1.6rem;
}

.woocommerce-account .woocommerce-Addresses .u-column1,
.woocommerce-account .woocommerce-Addresses .u-column2 {
	float: none;
	width: auto;
	margin: 0;
	padding: 1.5rem;
	background: #fff;
	border: 1px solid var(--cf-line);
	border-radius: var(--cf-radius);
	box-shadow: var(--cf-shadow);
}

.woocommerce-account .woocommerce-Address-title h2,
.woocommerce-account .woocommerce-Address-title h3 {
	margin: 0;
	font-family: var(--cf-display);
	font-size: 1.1rem;
	color: var(--cf-ink);
}

.woocommerce-account .woocommerce-Address-title {
	display: flex;
	align-items: baseline;
	justify-content: space-between;
	gap: .8rem;
	margin-bottom: .9rem;
}

.woocommerce-account .woocommerce-Address-title a:not(.button) { color: var(--cf-indigo); font-size: .9rem; }
.woocommerce-account .woocommerce-Address address { font-style: normal; color: var(--cf-body); line-height: 1.6; }

@media (max-width: 782px) {
	.woocommerce-account .woocommerce-Addresses.col2-set { grid-template-columns: 1fr; }
}

.woocommerce-account .woocommerce-EditAccountForm fieldset {
	margin: 1.8rem 0 0;
	padding: 1.3rem 1.5rem;
	border: 1px solid var(--cf-line);
	border-radius: var(--cf-radius);
	background: var(--cf-tint);
}

.woocommerce-account .woocommerce-EditAccountForm legend {
	padding: 0 .5rem;
	font-family: var(--cf-display);
	font-size: 1rem;
	font-weight: 700;
	color: var(--cf-ink);
}

/* WooCommerce emits the submit row of the address and account forms as a bare
   <p> with no class, so none of the .form-row spacing reaches it and it
   inherits only the base paragraph rule, which sets a bottom margin and no top
   one. The button ends up flush against the last field. Storefront declares
   nothing here, so this is uncontested.

   Matched on what the element is, the paragraph in an account form that is not
   a field row, rather than on its position, so it holds if WooCommerce adds or
   reorders rows. 2rem against the 1.1rem between fields, which reads as a
   break rather than another row. */
.woocommerce-account .woocommerce-address-fields > p:not(.form-row),
.woocommerce-account .woocommerce-EditAccountForm > p:not(.form-row) {
	margin: 2rem 0 0;
}

.woocommerce-account .woocommerce-Pagination { margin-top: 1.2rem; }
.woocommerce-account .woocommerce-Pagination a:not(.button) { color: var(--cf-indigo); }


/* =========================================================================
   Selects: native and Select2
   =========================================================================
   The blue on an open dropdown was WordPress admin chrome reaching the
   storefront. WooCommerce's select2 paints the highlighted option with
   var(--wp-admin-theme-color, #0073aa), so with no admin theme set on the
   front end every store gets #0073aa. Everything here is measured against
   WooCommerce 11.0.1's select2 stylesheet.

   The important change is not colour. WooCommerce gives a focus border to the
   MULTIPLE control only. The single control, which is what Country and State
   use, gets none, and it is a focusable <span> rather than an <input>, so the
   theme's global focus ring does not reach it either. A keyboard user had no
   indication of where they were on the checkout. That is WCAG 2.4.7 and it is
   fixed below.

   Measured: highlighted option white on indigo 10.25:1, up from 5.21:1 on the
   admin blue. Selected option 17.26:1. Control text 18.64:1. Placeholder uses
   --cf-body at 10.32:1 rather than --cf-muted, because --cf-muted would have
   moved it down from WooCommerce's 9.74:1 and trading contrast down is not
   worth a slightly softer grey. The chevron is non-text and needs 3:1, so it
   uses --cf-muted at 4.92:1.

   Our stylesheet is enqueued after select2.css, so equal specificity already
   resolves this way. body is added anyway, to decide it on specificity rather
   than on load order.
   ====================================================================== */

/* --- Native selects ----------------------------------------------------- */

.woocommerce select,
.woocommerce-account select,
.entry-content select,
.woocommerce-ordering select {
	-webkit-appearance: none;
	appearance: none;
	font-family: inherit;
	font-size: var(--cf-field-size);
	color: var(--cf-ink);
	background-color: #fff;
	background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 8'%3E%3Cpath d='M1 1.5L6 6.5L11 1.5' fill='none' stroke='%236b6f8a' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
	background-repeat: no-repeat;
	background-position: right .75rem center;
	background-size: 12px 8px;
	border: 1px solid var(--cf-line-strong);
	border-radius: var(--cf-radius-sm);
	padding: .62rem 2.2rem .62rem .8rem;
	line-height: 1.4;
}

/* --- Select2: the closed control ---------------------------------------- */

body .select2-container--default .select2-selection--single {
	height: auto;
	margin: 0;
	background-color: #fff;
	border: 1px solid var(--cf-line-strong);
	border-radius: var(--cf-radius-sm);
	padding: .5rem .8rem;
}

body .select2-container--default .select2-selection--single .select2-selection__rendered {
	color: var(--cf-ink);
	font-size: var(--cf-field-size);
	line-height: 1.5;
	padding-left: 0;
	padding-right: 1.5rem;
}

body .select2-container--default .select2-selection--single .select2-selection__placeholder {
	color: var(--cf-body);
}

/* WooCommerce draws the arrow as a CSS triangle on a <b>. Replaced with the
   same chevron the native selects use, so the two match wherever both appear
   on one page. */
body .select2-container--default .select2-selection--single .select2-selection__arrow {
	height: 100%;
	top: 0;
	right: .6rem;
	width: 12px;
}

body .select2-container--default .select2-selection--single .select2-selection__arrow b {
	position: absolute;
	top: 50%;
	left: 0;
	margin: 0;
	width: 12px;
	height: 8px;
	border: 0;
	background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 8'%3E%3Cpath d='M1 1.5L6 6.5L11 1.5' fill='none' stroke='%236b6f8a' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center / 12px 8px no-repeat;
	transform: translateY(-50%);
}

body .select2-container--default.select2-container--open .select2-selection--single .select2-selection__arrow b {
	transform: translateY(-50%) rotate(180deg);
}

/* The WCAG 2.4.7 fix. --focus covers the keyboard case, --open covers the
   pointer case, and :focus-visible is stated as well so the control is covered
   even if select2 stops setting its own classes. */
body .select2-container--default .select2-selection--single:focus-visible,
body .select2-container--default.select2-container--focus .select2-selection--single,
body .select2-container--default.select2-container--open .select2-selection--single {
	outline: 2px solid var(--cf-indigo);
	outline-offset: 2px;
	border-color: var(--cf-indigo);
}

body .select2-container--default .select2-selection--multiple {
	background-color: #fff;
	border: 1px solid var(--cf-line-strong);
	border-radius: var(--cf-radius-sm);
}

body .select2-container--default.select2-container--focus .select2-selection--multiple {
	border: 1px solid var(--cf-indigo);
	outline: 2px solid var(--cf-indigo);
	outline-offset: 2px;
}

/* --- Select2: the open panel -------------------------------------------- */

body .select2-dropdown {
	background-color: #fff;
	color: var(--cf-ink);
	border: 1px solid var(--cf-line);
	border-radius: var(--cf-radius-sm);
	box-shadow: var(--cf-shadow-lift);
	overflow: hidden;
}

body .select2-container--default .select2-search--dropdown {
	padding: .5rem;
}

body .select2-container--default .select2-search--dropdown .select2-search__field {
	font-family: inherit;
	font-size: var(--cf-field-size);
	color: var(--cf-ink);
	border: 1px solid var(--cf-line-strong);
	border-radius: var(--cf-radius-sm);
	padding: .5rem .65rem;
}

/* The panel clips to its rounded corners, so this ring is drawn inside the
   field rather than outside it, where the clip would eat it. */
body .select2-container--default .select2-search--dropdown .select2-search__field:focus-visible {
	outline: 2px solid var(--cf-indigo);
	outline-offset: -2px;
}

body .select2-container--default .select2-results__option {
	padding: .55rem .8rem;
	font-size: .95rem;
	color: var(--cf-ink);
}

/* Already chosen, but not the row under the cursor or the keyboard caret. */
body .select2-container--default .select2-results__option[data-selected="true"],
body .select2-container--default .select2-results__option[aria-selected="true"] {
	background-color: var(--cf-tint);
	color: var(--cf-ink);
	font-weight: 600;
}

/* Stated last on purpose. An option can be both selected and highlighted, and
   these two rules are the same specificity, so source order decides which one
   the user sees. The highlight has to win: it is the one tracking where the
   keyboard is. */
body .select2-container--default .select2-results__option--highlighted[data-selected],
body .select2-container--default .select2-results__option--highlighted[aria-selected] {
	background-color: var(--cf-indigo);
	color: #fff;
}


/* =========================================================================
   Classic checkout
   =========================================================================
   Storefront already builds the two columns: at its 768px desktop breakpoint
   .col2-set spans 5 of 9 and #order_review_heading with #order_review span the
   last 4, cleared right. #customer_details keeps .col-1 and .col-2 unfloated,
   so billing stacks above shipping and order notes inside the left column.
   That is the arrangement this page is meant to have, so none of it is
   replaced. Everything below is styling on top of it.

   Storefront's checkout selectors are ID-rooted, #payment .place-order and the
   like, so every rule here carries .woocommerce-checkout to sit one class
   above them. .payment_methods itself is left alone: Storefront sets its
   margin and padding with !important, and the li is the better handle anyway.

   Measured against Storefront 4.6.2 and WooCommerce 11.0.1.
   ====================================================================== */

/* --- Column headings ---------------------------------------------------- */

.woocommerce-checkout .woocommerce-billing-fields > h3,
.woocommerce-checkout .woocommerce-shipping-fields > h3,
.woocommerce-checkout .woocommerce-additional-fields > h3,
.woocommerce-checkout #order_review_heading {
	margin: 0 0 1.1rem;
	font-family: var(--cf-display);
	font-size: 1.2rem;
	font-weight: 700;
	color: var(--cf-ink);
}

.woocommerce-checkout .woocommerce-shipping-fields,
.woocommerce-checkout .woocommerce-additional-fields {
	margin-top: 2rem;
}

/* --- Fields ------------------------------------------------------------- */

.woocommerce-checkout form.checkout .form-row {
	margin: 0 0 1.1rem;
	padding: 0;
}

.woocommerce-checkout form.checkout .form-row label {
	display: block;
	margin: 0 0 .35rem;
	font-family: var(--cf-display);
	font-size: .66rem;
	font-weight: 600;
	letter-spacing: .12em;
	text-transform: uppercase;
	color: var(--cf-muted);
}

/* Checkbox rows are sentences beside a control, not field names, so they are
 * kept out of the small-caps label treatment above.
 *
 * A hanging indent rather than flex. WooCommerce renders the terms label with
 * three children:
 *
 *     <input type="checkbox">
 *     <span class="woocommerce-terms-and-conditions-checkbox-text">...</span>
 *     <span class="required">*</span>
 *
 * As a flex row that makes the asterisk a third item, so it parked at the far
 * end of the row and centred itself vertically against two lines of wrapped
 * text instead of following the words. Flex cannot fix that: the text and the
 * asterisk are separate elements with no wrapper to group them.
 *
 * In normal flow both spans are inline, so the asterisk follows the sentence
 * wherever it ends, and the checkbox hangs in the padding beside the first
 * line however many lines the text runs to. */
.woocommerce-checkout form.checkout .form-row label.checkbox,
.woocommerce-checkout form.checkout .form-row label.woocommerce-form__label-for-checkbox {
	display: block;
	position: relative;
	padding-left: 1.85rem;
	font-family: inherit;
	font-size: .92rem;
	font-weight: 400;
	line-height: 1.55;
	letter-spacing: 0;
	text-transform: none;
	color: var(--cf-body);
}

.woocommerce-checkout form.checkout .form-row label.checkbox > input[type="checkbox"],
.woocommerce-checkout form.checkout .form-row label.woocommerce-form__label-for-checkbox > input[type="checkbox"] {
	position: absolute;
	top: .18em;
	left: 0;
	width: 17px;
	height: 17px;
	margin: 0;
	accent-color: var(--cf-indigo);
}

.woocommerce-checkout form.checkout .input-text,
.woocommerce-checkout form.checkout input[type="text"],
.woocommerce-checkout form.checkout input[type="email"],
.woocommerce-checkout form.checkout input[type="tel"],
.woocommerce-checkout form.checkout input[type="password"],
.woocommerce-checkout form.checkout textarea {
	width: 100%;
	font-family: inherit;
	font-size: var(--cf-field-size);
	color: var(--cf-ink);
	background: #fff;
	border: 1px solid var(--cf-line-strong);
	border-radius: var(--cf-radius-sm);
	padding: .62rem .8rem;
}

.woocommerce-checkout form.checkout textarea { min-height: 6.5rem; }

.woocommerce-checkout form.checkout .required {
	color: #b3261e;
	border: 0;
	text-decoration: none;
}

/* WooCommerce marks a failed field by class. Storefront signals it with an
   inset box-shadow only, which is a colour-only cue; the border moves too so
   the state does not depend on seeing a thin red edge. */
.woocommerce-checkout form.checkout .woocommerce-invalid input.input-text,
.woocommerce-checkout form.checkout .woocommerce-invalid select {
	border-color: #b3261e;
}

.woocommerce-checkout form.checkout .woocommerce-validated input.input-text {
	border-color: var(--cf-line-strong);
}

/* --- Order review table ------------------------------------------------- */

/* One number governs the card's padding and the table's cell padding, because
   they have to agree: the table is pulled out to the card's edges so its
   header reads as a band rather than a floating strip, and the cells then put
   the text back on the card's padding line. Two separate values would drift
   apart the first time either is touched. */
.woocommerce-checkout #order_review {
	--cf-review-pad: 1.4rem;
	background: #fff;
	border: 1px solid var(--cf-line);
	border-radius: var(--cf-radius);
	box-shadow: var(--cf-shadow);
	padding: var(--cf-review-pad);

	/* The header band is pulled up to the card's top edge, so the corner has to
	   be cut by the card rather than left square underneath it. */
	overflow: hidden;
}

.woocommerce-checkout #order_review table.shop_table {
	width: calc(100% + var(--cf-review-pad) * 2);

	/* Pulled out on three sides, not two. The table already ran to the card's
	   left and right edges so the header would read as a band, but the card's
	   top padding was still above it, which left a strip of white card between
	   the border and the band. The band starts at the border now. */
	margin: calc(var(--cf-review-pad) * -1) calc(var(--cf-review-pad) * -1) 1.4rem;
	border: 0;
	border-collapse: collapse;
	font-size: .94rem;
}

.woocommerce-checkout #order_review table.shop_table th,
.woocommerce-checkout #order_review table.shop_table td {
	padding: .7rem var(--cf-review-pad);
	border-bottom: 1px solid var(--cf-line);
	vertical-align: top;
	text-align: left;
}

/* Storefront paints th cells in shop tables. In a two-column totals table that
   colours the label and not the amount, so Subtotal, Total and the renewal row
   each rendered as a half-grey row that stopped dead in the middle. The header
   band above is the only row meant to carry a fill. */
.woocommerce-checkout #order_review table.shop_table tbody th,
.woocommerce-checkout #order_review table.shop_table tfoot th {
	background: none;
}

/* padding-top was zeroed here in 1.89.0, when the table sat inside the card's
   own padding and a top padding on the first row would have doubled it. Since
   1.94.0 the table runs to the card's edges and this row is a tinted band, so
   it needs padding on both sides like any other band. Left as it was, the
   label sat hard against the top edge: measured 15px of space above the glyphs
   against 42 below.

   vertical-align is stated too. The base rule above uses top, which is right
   for a body row where a wrapped product name should line up with its price,
   and wrong for a single-line header in a band of its own. */
.woocommerce-checkout #order_review table.shop_table thead th {
	vertical-align: middle;
	font-family: var(--cf-display);
	font-size: .68rem;
	font-weight: 700;
	letter-spacing: .1em;
	text-transform: uppercase;
	color: var(--cf-muted);
}

.woocommerce-checkout #order_review table.shop_table td.product-total,
.woocommerce-checkout #order_review table.shop_table th.product-total,
.woocommerce-checkout #order_review table.shop_table tfoot td {
	text-align: right;
	white-space: nowrap;
}

.woocommerce-checkout #order_review table.shop_table tfoot th {
	font-family: var(--cf-display);
	font-weight: 600;
	color: var(--cf-body);
}

.woocommerce-checkout #order_review table.shop_table tfoot .order-total th,
.woocommerce-checkout #order_review table.shop_table tfoot .order-total td {
	padding-bottom: 0;
	border-bottom: 0;
	font-size: 1.1rem;
	color: var(--cf-ink);
}

.woocommerce-checkout #order_review table.shop_table tfoot .order-total td { font-weight: 700; }

/* The quantity WooCommerce appends to a line name. */
.woocommerce-checkout #order_review .product-quantity {
	color: var(--cf-muted);
	font-weight: 400;
}

/* --- Payment methods ---------------------------------------------------- */

.woocommerce-checkout #payment {
	background: none;
	border-radius: 0;
}

.woocommerce-checkout #payment .payment_methods > li.wc_payment_method {
	margin: 0 0 .5rem;
	background: #fff;
	border: 1px solid var(--cf-line-strong);
	border-radius: var(--cf-radius-sm);
	overflow: hidden;
}

/* Storefront hides the real radio and draws a Font Awesome glyph on the label
 * instead:
 *
 *     > label::before { content: <fa-circle>; }
 *     > input[type="radio"]:first-child { @include screen-reader-text(); }
 *     > input:checked + label::before { content: <fa-dot-circle>; }
 *
 * fa-circle is a SOLID filled disc, so an unselected method rendered as a
 * filled black dot and read as the chosen one, while the selected method was a
 * ring. The states were the wrong way round, and the glyph took its colour from
 * the label, which this theme sets to --cf-ink.
 *
 * The real control is shown instead of restyling the glyph. It carries the
 * right states for free, takes accent-color, gets the platform's own focus
 * ring, and scales with the user's settings. Only word-wrap in Storefront's
 * hiding mixin is !important, so every part of it can be undone normally.
 *
 * The li becomes a grid, which also retires the absolute positioning and the
 * 2.6rem label indent that existed to clear a control nobody could see. The
 * radio sits at 1rem from the card edge rather than 2.6rem. */
.woocommerce-checkout #payment .payment_methods > li.wc_payment_method {
	display: grid;
	grid-template-columns: auto 1fr;
	align-items: center;
	column-gap: .7rem;
}

.woocommerce-checkout #payment .payment_methods > li.wc_payment_method > input.input-radio[type="radio"]:first-child {
	grid-column: 1;
	position: static;
	width: 18px;
	height: 18px;
	margin: 0 0 0 1rem;
	padding: 0;
	border: 0;
	clip: auto;
	-webkit-clip-path: none;
	clip-path: none;
	overflow: visible;
	accent-color: var(--cf-indigo);
}

.woocommerce-checkout #payment .payment_methods > li.wc_payment_method > label {
	grid-column: 2;
	display: flex;
	align-items: center;
	gap: .6rem;
	padding: .85rem 1rem .85rem 0;
	font-family: var(--cf-display);
	font-size: .95rem;
	font-weight: 600;
	color: var(--cf-ink);
	cursor: pointer;
}

/* The glyph is retired, not recoloured. Storefront declares it twice, once as
   the base marker and again for the checked state at a heavier weight:

     #payment .payment_methods li.wc_payment_method
       > input[type="radio"]:first-child:checked + label::before   (1,5,4)

   1.101.0 only answered the base rule at (1,3,3), so the glyph came back on
   whichever method was selected and sat beside the real radio. Both states are
   turned off here, the second at (1,6,4) so it outranks the rule that put it
   back. */
.woocommerce-checkout #payment .payment_methods > li.wc_payment_method > label::before,
.woocommerce-checkout #payment .payment_methods > li.wc_payment_method > input[type="radio"]:first-child:checked + label::before {
	content: none;
}

.woocommerce-checkout #payment .payment_methods > li.wc_payment_method > .payment_box {
	grid-column: 1 / -1;
}

/* The selected method is filled as well as bordered, so the choice does not
   rest on the radio dot alone. --cf-tint against #fff is a light cue, so the
   border carries it: --cf-indigo on white is 10.25:1. */
.woocommerce-checkout #payment .payment_methods > li.wc_payment_method:has(> input:checked) {
	border-color: var(--cf-indigo);
	background: var(--cf-tint);
}

.woocommerce-checkout #payment .payment_methods > li.wc_payment_method > input.input-radio[type="radio"]:focus-visible {
	outline: 2px solid var(--cf-indigo);
	outline-offset: 2px;
}

/* Symmetric on purpose. 1.89.0 set the left to 2.6rem to line this box up
   under the label text, which carries that indent to clear the absolutely
   positioned radio. But the radio only occupies the label row, so the indent
   bought nothing below it: it pushed the gateway's own panel off centre, 95px
   of inset on the left against 40px on the right as rendered, and took 26px of
   width off a card form that wants all of it. The box aligns with the radio
   rather than with the label text, which is the edge the container itself
   uses. */
.woocommerce-checkout #payment .payment_methods .payment_box {
	margin: 0;
	padding: 0 1rem 1rem;
	background: none;
	font-size: .92rem;
	color: var(--cf-body);
}

/* Storefront points a triangle at the selected method from a box it colours
   itself. The box is no longer a separate colour, so the pointer has nothing
   to point from. */
.woocommerce-checkout #payment .payment_methods .payment_box::before {
	display: none;
}

/* Storefront gives the gateway's fieldset padding: 1em 0 0 at its own reduced
   font size, which measures 13px and shows as a band of empty box above the
   gateway's own card. Nothing sits in it. The fieldset keeps no padding at all
   and the payment box's 1rem does the spacing. */
.woocommerce-checkout #payment .payment_methods .payment_box fieldset {
	margin: 0;
	padding: 0;
	border: 0;
}

/* Storefront caps every embed on the site:
 *
 *     embed, iframe, object, video { max-width: 100%; }
 *
 * max-width clamps the used width after width is resolved, so it beats an
 * inline width regardless of origin. Stripe mounts its Payment Element with
 *
 *     margin: -4px; width: calc(100% + 8px);
 *
 * deliberately oversizing the iframe and pulling it back so its content lines
 * up with the container. The cap held the width at 100% while the negative
 * margins stayed, so the iframe sat 4px left of its container and stopped 4px
 * short on the right. Measured on the rendered checkout: container left 51.2
 * right 297.6, iframe left 47.2 right 293.6, same width, shifted.
 *
 * Lifting the cap on this one iframe lets Stripe's own compensation work as
 * intended. No !important is needed: Storefront's rule is a bare element
 * selector.
 *
 * Two earlier attempts are worth recording so they are not repeated. 1.106.0
 * tried to centre the shortfall with auto margins, which never applied because
 * Stripe writes margin inline. 1.107.0 forced width: 100% !important, which did
 * apply and produced the same 4px offset by a different route, then masked the
 * real cause when the page was measured. Both are gone. */
.woocommerce-checkout #payment .payment_methods .payment_box .wc-stripe-upe-element iframe {
	max-width: none;
}

.woocommerce-checkout #payment .payment_methods li img {
	float: none;
	margin-left: auto;
	max-height: 26px;
	width: auto;
}

/* --- Place order -------------------------------------------------------- */

.woocommerce-checkout #payment .place-order {
	padding: 0;
	margin: 1.4rem 0 0;
}

.woocommerce-checkout #payment .place-order .woocommerce-privacy-policy-text p {
	margin: 0 0 1rem;
	font-size: .85rem;
	line-height: 1.55;
	color: var(--cf-muted);
}

.woocommerce-checkout #payment .place-order .woocommerce-privacy-policy-text a { color: var(--cf-indigo); }

.woocommerce-checkout #payment .place-order .woocommerce-terms-and-conditions-wrapper {
	margin: 0 0 .2rem;
}

.woocommerce-checkout #payment .place-order .form-row.terms,
.woocommerce-checkout #payment .place-order .validate-required {
	margin: 0 0 1rem;
}

.woocommerce-checkout #payment .place-order .button#place_order {
	display: block;
	width: 100%;
	margin: 0;
	font-size: 1rem;
	white-space: normal;
}

/* --- PayPal's own containers -------------------------------------------- */

/* 1.89.0 carried a rule here that claimed WooCommerce PayPal Payments prints
   its button containers as siblings of #order_review, and floated them back
   into the summary column. That was a misreading of the markup at limited
   depth. #ppc-button-ppcp-applepay, #ppc-button-ppcp-googlepay and
   .ppcp-messages are all children of #order_review already, and #place_order
   is inside #payment inside #order_review, so the rule matched nothing and
   never ran. Removed rather than corrected: there is nothing to correct, the
   containers are where they need to be on their own.

   .ppcp-messages is the Pay-in-4 line above the methods and does need its
   spacing stated, since it arrives with none. */
.woocommerce-checkout .ppcp-messages { margin: 0 0 1rem; }

/* --- The trust block, now inside the summary column --------------------- */

/* Rendered on woocommerce_review_order_after_submit, so it sits inside
   .place-order under the button. It was written to be a wide band across the
   foot of the page and is now roughly a third of that, so the width cap and
   the centring that suited the old position are dropped and the block is
   simply separated from the button above it. */
.woocommerce-checkout #payment .place-order .cf-secure {
	max-width: none;
	margin: 1.4rem 0 0;
	padding-top: 1.2rem;
	border-top: 1px solid var(--cf-line);
}

.woocommerce-checkout .cf-assure { margin-bottom: 2rem; }

/* --- Narrow screens ----------------------------------------------------- */

/* Storefront's two columns only exist from 768px, so below that the page is
   already one column and nothing needs undoing. The review panel loses its
   card inset so it does not sit in a box inside a box on a phone. */
@media (max-width: 767px) {
	/* Only the one variable changes: the table's bleed and its cell padding
	   follow it automatically. */
	.woocommerce-checkout #order_review {
		--cf-review-pad: 1.1rem;
	}

	.woocommerce-checkout #payment .place-order .button#place_order {
		font-size: 1.05rem;
		padding-top: .9rem;
		padding-bottom: .9rem;
	}
}


/* =========================================================================
   Recurring totals row, Subscriptions For WooCommerce
   =========================================================================
   The plugin adds an extra tfoot row to the review table after the order
   total. Markup taken from www's rendered checkout rather than assumed:

     <tr class="wps_recurring_bifurcation_wrapper">
       <th><h4>Renewal For <a>Product</a></h4></th>
       <td><ul><li><label>Subtotal:</label><span>...</span></li>
               <li><label>Total:</label><span>...<span class="wps_sfw_interval">
               / Month</span></span></li></ul></td>
     </tr>

   Written now, ahead of the plugin running on staging, because the markup is
   known exactly and the alternative is discovering it unstyled on the one page
   where a customer is deciding whether to pay.
   ====================================================================== */

.woocommerce-checkout #order_review table.shop_table tfoot tr.wps_recurring_bifurcation_wrapper th,
.woocommerce-checkout #order_review table.shop_table tfoot tr.wps_recurring_bifurcation_wrapper td {
	padding: 1rem var(--cf-review-pad) 0;
	border-bottom: 0;
	border-top: 1px solid var(--cf-line);
	vertical-align: top;
	white-space: normal;
}

.woocommerce-checkout #order_review .wps_recurring_bifurcation_wrapper h4 {
	margin: 0;
	font-family: var(--cf-display);
	font-size: .68rem;
	font-weight: 700;
	letter-spacing: .1em;
	text-transform: uppercase;
	color: var(--cf-muted);
	line-height: 1.5;
}

/* The product name is a link inside that heading and should read as a name,
   not as more small caps. */
.woocommerce-checkout #order_review .wps_recurring_bifurcation_wrapper h4 a {
	display: inline-block;
	font-size: .92rem;
	letter-spacing: 0;
	text-transform: none;
	color: var(--cf-indigo);
}

.woocommerce-checkout #order_review .wps_recurring_bifurcation_wrapper ul {
	margin: 0;
	padding: 0;
	list-style: none;
}

.woocommerce-checkout #order_review .wps_recurring_bifurcation_wrapper li {
	display: flex;
	align-items: baseline;
	justify-content: space-between;
	gap: .8rem;
	margin: 0 0 .3rem;
	font-size: .92rem;
	color: var(--cf-body);
	text-align: left;
}

.woocommerce-checkout #order_review .wps_recurring_bifurcation_wrapper li:last-child {
	margin-bottom: 0;
	font-weight: 700;
	color: var(--cf-ink);
}

/* This label sits in a table cell, not a form row, so it is held clear of the
   checkout's small-caps field-label treatment. */
.woocommerce-checkout #order_review .wps_recurring_bifurcation_wrapper label {
	margin: 0;
	font: inherit;
	color: inherit;
	letter-spacing: 0;
	text-transform: none;
}

.woocommerce-checkout #order_review .wps_sfw_interval {
	font: inherit;
	color: inherit;
	white-space: nowrap;
}


/* =========================================================================
   Classic cart
   =========================================================================
   Storefront lays this out already: table.cart full width, then
   .cart-collaterals with .cart_totals floated right at 5 of 9 above its 768px
   breakpoint, and table.shop_table_responsive stacked into rows with
   data-title labels below it. None of that is replaced.

   Every rule carries the .woocommerce-cart body class so it sits one class
   above Storefront's own table.cart and .cart_totals selectors. Its desktop
   rules live in a media query, which does not affect specificity, so these win
   at every width and the stacked view is handled explicitly at the end.

   Measured against Storefront 4.6.2 and WooCommerce 11.0.1.
   ====================================================================== */

.woocommerce-cart .woocommerce-cart-form table.cart {
	width: 100%;
	margin: 0 0 2rem;
	background: #fff;
	border: 1px solid var(--cf-line);
	border-radius: var(--cf-radius);
	border-collapse: separate;
	border-spacing: 0;
	font-size: .95rem;
}

.woocommerce-cart .woocommerce-cart-form table.cart thead th {
	padding: .85rem 1rem;
	background: var(--cf-tint);
	border-bottom: 1px solid var(--cf-line);
	font-family: var(--cf-display);
	font-size: .68rem;
	font-weight: 700;
	letter-spacing: .1em;
	text-transform: uppercase;
	color: var(--cf-muted);
	text-align: left;
}

.woocommerce-cart .woocommerce-cart-form table.cart td {
	padding: 1rem;
	border-bottom: 1px solid var(--cf-line);
	vertical-align: middle;
	color: var(--cf-body);
}

.woocommerce-cart .woocommerce-cart-form table.cart td.product-subtotal,
.woocommerce-cart .woocommerce-cart-form table.cart th.product-subtotal {
	text-align: right;
	white-space: nowrap;
}

.woocommerce-cart .woocommerce-cart-form table.cart td.product-name a {
	font-family: var(--cf-display);
	font-weight: 600;
	color: var(--cf-ink);
	text-decoration: none;
}

.woocommerce-cart .woocommerce-cart-form table.cart td.product-name a:hover { color: var(--cf-indigo); }

/* Storefront guards the checkout review table against unbreakable product
   names and leaves the cart's unguarded. These names carry tokens like
   "(iOS/macOS/visionOS)", which no browser will break, and a table cannot be
   narrower than its widest unbreakable content. anywhere rather than
   break-word on purpose: only anywhere affects the min-content width, which is
   the measurement that decides whether the table fits. */
.woocommerce-cart .woocommerce-cart-form table.cart td { overflow-wrap: anywhere; }

.woocommerce-cart .woocommerce-cart-form table.cart td.product-thumbnail img {
	width: 64px;
	height: auto;
	border-radius: var(--cf-radius-sm);
	border: 1px solid var(--cf-line);
}

/* Remove: a bare multiplication sign by default, which is a small target and
   easy to hit by accident next to the quantity field. Given a 32px circle,
   which also clears the 24px minimum target size, and red only on hover so a
   destructive action is not shouting on every row. */
/* position: relative is load-bearing, not cosmetic. Storefront does not show
 * WooCommerce's "x" text at all:
 *
 *     a.remove { text-indent: -9999px; overflow: hidden; position: relative; }
 *     a.remove::before { content: <times-circle>; position: absolute;
 *                        top:0; left:0; right:0; bottom:0; text-align:center; }
 *
 * The text is pushed off screen and the visible mark is that pseudo-element,
 * stretched to the anchor's own edges. So the anchor's positioning is doing two
 * jobs: placing itself, and being the containing block for its icon.
 *
 * 1.95.0 set this to static to undo Storefront's absolute placement of the
 * anchor, and took the containing block away with it. The ::before then
 * resolved its four zero offsets against the initial containing block and
 * covered the whole page. It hit-tests as a.remove, so every tap anywhere on
 * the cart removed the item, and because a pseudo-element is excluded from
 * getBoundingClientRect() the anchor still measured 32x32 while doing it. The
 * stray grey x floating in the middle of the card was that same pseudo-element,
 * centred in the page rather than in the button.
 *
 * relative takes the anchor out of Storefront's absolute placement and keeps
 * the icon contained, which is what Storefront itself switches to at desktop
 * widths. That is why this never reproduced on a narrowed desktop window.
 *
 * No border or fill here: the icon is already a filled circle with a cut-out
 * cross, so drawing another circle around it made two. --cf-body on the row is
 * 10.32:1, and red on hover is 5.53:1. */
.woocommerce-cart .woocommerce-cart-form table.cart td.product-remove a.remove {
	position: relative;
	display: block;
	width: 32px;
	height: 32px;
	background: none;
	border: 0;
	overflow: hidden;
	text-decoration: none;
}

.woocommerce-cart .woocommerce-cart-form table.cart td.product-remove a.remove::before {
	line-height: 32px;
	font-size: 22px;
	color: var(--cf-body);
}

.woocommerce-cart .woocommerce-cart-form table.cart td.product-remove a.remove:hover::before,
.woocommerce-cart .woocommerce-cart-form table.cart td.product-remove a.remove:focus-visible::before {
	color: #b3261e;
}

/* The number shown for a line whose quantity is fixed. Sized and coloured to
   sit where the input would have been rather than to imitate one, since there
   is nothing to type into. */
.woocommerce-cart .woocommerce-cart-form table.cart .cf-qty-fixed {
	display: inline-block;
	min-width: 2.2rem;
	font-family: var(--cf-display);
	font-size: var(--cf-field-size);
	font-weight: 600;
	color: var(--cf-ink);
	text-align: center;
}

.woocommerce-cart .woocommerce-cart-form table.cart .quantity .qty {
	width: 5rem;
	max-width: none;
	padding: .5rem .4rem;
	font-family: inherit;
	font-size: var(--cf-field-size);
	color: var(--cf-ink);
	text-align: center;
	background: #fff;
	border: 1px solid var(--cf-line-strong);
	border-radius: var(--cf-radius-sm);
}

/* --- The actions row ---------------------------------------------------- */

.woocommerce-cart .woocommerce-cart-form table.cart td.actions {
	padding: 1rem;
	border-top: 0;
	border-bottom: 0;
	background: var(--cf-tint);
}

.woocommerce-cart .woocommerce-cart-form table.cart td.actions .coupon {
	display: flex;
	gap: .5rem;
	float: left;
	margin: 0;
	padding: 0;
	border: 0;
}

.woocommerce-cart .woocommerce-cart-form table.cart td.actions .coupon .input-text {
	width: 12rem;
	margin: 0;
	padding: .55rem .7rem;
	font-family: inherit;
	font-size: var(--cf-field-size);
	color: var(--cf-ink);
	background: #fff;
	border: 1px solid var(--cf-line-strong);
	border-radius: var(--cf-radius-sm);
}

/* --- Totals panel ------------------------------------------------------- */

.woocommerce-cart .cart-collaterals .cart_totals {
	padding: 1.4rem;
	background: #fff;
	border: 1px solid var(--cf-line);
	border-radius: var(--cf-radius);
	box-shadow: var(--cf-shadow);
}

.woocommerce-cart .cart-collaterals .cart_totals > h2 {
	margin: 0 0 1.1rem;
	font-family: var(--cf-display);
	font-size: 1.2rem;
	font-weight: 700;
	color: var(--cf-ink);
}

.woocommerce-cart .cart-collaterals .cart_totals table.shop_table {
	width: 100%;
	margin: 0 0 1.2rem;
	border: 0;
	border-collapse: collapse;
	font-size: .95rem;
}

.woocommerce-cart .cart-collaterals .cart_totals table.shop_table th,
.woocommerce-cart .cart-collaterals .cart_totals table.shop_table td {
	padding: .7rem 0;
	border-bottom: 1px solid var(--cf-line);
	text-align: left;
	color: var(--cf-body);
}

.woocommerce-cart .cart-collaterals .cart_totals table.shop_table td { text-align: right; }

.woocommerce-cart .cart-collaterals .cart_totals table.shop_table th {
	font-family: var(--cf-display);
	font-weight: 600;
}

.woocommerce-cart .cart-collaterals .cart_totals table.shop_table .order-total th,
.woocommerce-cart .cart-collaterals .cart_totals table.shop_table .order-total td {
	padding-bottom: 0;
	border-bottom: 0;
	font-size: 1.1rem;
	color: var(--cf-ink);
}

.woocommerce-cart .wc-proceed-to-checkout {
	margin: 0;
	padding: 0;
}

.woocommerce-cart .wc-proceed-to-checkout .checkout-button {
	display: block;
	width: 100%;
	margin: 0 0 .8rem;
	text-align: center;
	font-size: 1rem;
}

.woocommerce-cart .wc-proceed-to-checkout .ppcp-messages { margin: 0 0 1rem; }

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

/* NOT VERIFIED AGAINST CAPTURED MARKUP: the cart had an item in it when this
   page was saved, so the empty state is written from WooCommerce's stock
   template. Check it before this ships to www. */
.woocommerce-cart .cart-empty { font-size: 1.05rem; }
.woocommerce-cart .return-to-shop { margin-top: 1.2rem; }

/* --- Stacked, below Storefront's 768px breakpoint ----------------------- */

/* Storefront turns the rows into stacked blocks with the column name printed
   from data-title in a ::before. The cell padding above is sized for a table
   cell and is too heavy once each cell is its own row. */
@media (max-width: 767px) {
	.woocommerce-cart .woocommerce-cart-form table.cart td {
		padding: .6rem 1rem;
		text-align: right;
	}

	.woocommerce-cart .woocommerce-cart-form table.cart td.product-thumbnail img {
		margin-left: auto;
	}

	/* Storefront hangs this outside the cell's top-right corner:
	
	     td.product-remove { padding: 0; position: relative; }
	     td.product-remove a.remove { position: absolute;
	                                  top: -ms(-2); right: -ms(-2); }
	
	   Absolute, with negative offsets, which suits the small x it ships and
	   which it resets to position:relative at desktop only. 1.93.0 turned that
	   into a 32px circle, so it protrudes far enough to leave the table: the
	   console reports its right edge at 168 against the containing cell's 157,
	   and on a phone it lands off-screen entirely, which is why no remove
	   control was visible on the cart at all. Put back into normal flow. */
	.woocommerce-cart .woocommerce-cart-form table.cart td.product-remove {
		position: static;
		padding: .6rem 1rem;
		border-top: 0;
	}

	/* Position is settled in the base rule above and must not be touched here:
	   static would detach the icon pseudo-element again. Only placement within
	   the stacked row belongs in this block. */
	.woocommerce-cart .woocommerce-cart-form table.cart td.product-remove a.remove {
		margin-left: auto;
	}

	.woocommerce-cart .woocommerce-cart-form table.cart .quantity .qty { width: 4.5rem; }

	.woocommerce-cart .woocommerce-cart-form table.cart td.actions .coupon {
		float: none;
		flex-wrap: wrap;
		margin-bottom: .8rem;
	}

	.woocommerce-cart .woocommerce-cart-form table.cart td.actions .coupon .input-text { width: 100%; }
	.woocommerce-cart .woocommerce-cart-form table.cart td.actions .coupon .button { width: 100%; }
	.woocommerce-cart .woocommerce-cart-form table.cart td.actions > .button { width: 100%; }
}


/* =========================================================================
   Form controls on narrow screens
   =========================================================================
   iOS Safari zooms the page whenever a focused input, select or textarea
   computes below 16px. Every control here sat between 14.40px and 15.36px, so
   it fired on the coupon field, the checkout, the account forms, the login and
   the shop sorting select.

   The zoom is not only untidy. Once it happens the visual and layout viewports
   disagree, and a following tap can land on different coordinates than the one
   under the finger. On the cart that is next to a remove link, which is a
   plain GET link with no confirmation.

   16px is the threshold rather than a preference, so it is stated as a number
   and not as a rem value that a root font-size change could drop below it.
   Done on the token so no rule's specificity is involved: a custom property
   overridden here reaches every rule that reads it.
   ====================================================================== */

@media (max-width: 767px) {
	:root { --cf-field-size: 16px; }
}


/* =========================================================================
   Order received
   =========================================================================
   The last page of the purchase and the first one a customer sees as an owner,
   and until now the only surface in the classic pass with no theme styling at
   all. Written against the saved markup of order 10248.

   Scoped to .woocommerce-order-received rather than reusing the checkout
   rules: WordPress puts woocommerce-checkout on this body too, so anything
   written against that class leaks onto this page.

   Storefront gives ul.order_details a torn-paper edge with two absolutely
   positioned pseudo-elements. They are turned off here, since the list is a
   card rather than a receipt stub.
   ====================================================================== */

.woocommerce-order-received .woocommerce-notice--success {
	margin: 0 0 1.8rem;
	padding: 1.1rem 1.3rem;
	background: var(--cf-tint);
	border: 1px solid var(--cf-line);
	border-left: 3px solid var(--cf-indigo);
	border-radius: var(--cf-radius);
	font-family: var(--cf-display);
	font-size: 1.05rem;
	font-weight: 600;
	color: var(--cf-ink);
}

/* --- The order summary strip -------------------------------------------- */

.woocommerce-order-received ul.order_details::before,
.woocommerce-order-received ul.order_details::after {
	display: none;
}

/* gap over a --cf-line background draws the separators, so a cell that wraps
   onto a second row never leaves a stray border hanging off the end. */
.woocommerce-order-received ul.order_details {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
	gap: 1px;
	margin: 0 0 2.2rem;
	padding: 0;
	list-style: none;
	background: var(--cf-line);
	border: 1px solid var(--cf-line);
	border-radius: var(--cf-radius);
	box-shadow: var(--cf-shadow);
	overflow: hidden;
}

.woocommerce-order-received ul.order_details li {
	margin: 0;
	padding: 1.1rem 1.2rem;
	background: #fff;
	border: 0;
	font-family: var(--cf-display);
	font-size: .66rem;
	font-weight: 600;
	letter-spacing: .12em;
	text-transform: uppercase;
	color: var(--cf-muted);
}

/* An order email can be long and has no break opportunity in it, and a grid
   cell will not shrink below its widest unbreakable content. anywhere rather
   than break-word, for the same reason as the cart. */
.woocommerce-order-received ul.order_details li strong {
	display: block;
	margin-top: .35rem;
	font-size: .98rem;
	font-weight: 700;
	letter-spacing: 0;
	text-transform: none;
	color: var(--cf-ink);
	overflow-wrap: anywhere;
}

/* The gateway's own instructions, printed after the summary. */
.woocommerce-order-received .woocommerce-order > p:not(.woocommerce-notice) {
	margin: 0 0 2.2rem;
	color: var(--cf-body);
}

/* --- Sections ----------------------------------------------------------- */

.woocommerce-order-received .woocommerce-order-details,
.woocommerce-order-received .woocommerce-customer-details {
	margin: 0 0 2.2rem;
}

.woocommerce-order-received .woocommerce-order-details__title,
.woocommerce-order-received .woocommerce-column__title {
	margin: 0 0 1.1rem;
	font-family: var(--cf-display);
	font-size: 1.2rem;
	font-weight: 700;
	color: var(--cf-ink);
}

/* --- The order table ---------------------------------------------------- */

.woocommerce-order-received table.order_details {
	width: 100%;
	margin: 0;
	background: #fff;
	border: 1px solid var(--cf-line);
	border-collapse: separate;
	border-spacing: 0;
	border-radius: var(--cf-radius);
	font-size: .95rem;
}

.woocommerce-order-received table.order_details th,
.woocommerce-order-received table.order_details td {
	padding: .85rem 1.1rem;
	border-bottom: 1px solid var(--cf-line);
	text-align: left;
	vertical-align: top;
	color: var(--cf-body);
}

.woocommerce-order-received table.order_details thead th {
	background: var(--cf-tint);
	font-family: var(--cf-display);
	font-size: .68rem;
	font-weight: 700;
	letter-spacing: .1em;
	text-transform: uppercase;
	color: var(--cf-muted);
}

/* Storefront fills th cells in shop tables, which in a two-column footer
   colours the label and leaves the amount white. Same half-grey row the
   checkout review had. */
.woocommerce-order-received table.order_details tbody th,
.woocommerce-order-received table.order_details tfoot th {
	background: none;
	font-family: var(--cf-display);
	font-weight: 600;
}

.woocommerce-order-received table.order_details td.product-total,
.woocommerce-order-received table.order_details th.product-total,
.woocommerce-order-received table.order_details tfoot td {
	text-align: right;
	white-space: nowrap;
}

.woocommerce-order-received table.order_details tfoot tr:last-child th,
.woocommerce-order-received table.order_details tfoot tr:last-child td {
	border-bottom: 0;
	font-size: 1.05rem;
	color: var(--cf-ink);
}

.woocommerce-order-received table.order_details .product-name a {
	font-family: var(--cf-display);
	font-weight: 600;
	color: var(--cf-ink);
	text-decoration: none;
	overflow-wrap: anywhere;
}

.woocommerce-order-received table.order_details .product-name a:hover { color: var(--cf-indigo); }

.woocommerce-order-received table.order_details .wc-item-meta,
.woocommerce-order-received table.order_details .product-quantity {
	color: var(--cf-muted);
	font-weight: 400;
}

/* --- Customer details --------------------------------------------------- */

.woocommerce-order-received .woocommerce-customer-details address {
	padding: 1.2rem 1.3rem;
	background: #fff;
	border: 1px solid var(--cf-line);
	border-radius: var(--cf-radius);
	box-shadow: var(--cf-shadow);
	font-style: normal;
	line-height: 1.7;
	color: var(--cf-body);
	overflow-wrap: anywhere;
}

.woocommerce-order-received .woocommerce-customer-details address p {
	margin: .5rem 0 0;
}

.woocommerce-order-received .woocommerce-customer-details address a {
	color: var(--cf-indigo);
}

@media (max-width: 767px) {
	.woocommerce-order-received ul.order_details li { padding: .9rem 1rem; }

	.woocommerce-order-received table.order_details th,
	.woocommerce-order-received table.order_details td { padding: .75rem .9rem; }
}


/* =========================================================================
   Line item thumbnails
   =========================================================================
   Beside the product name in the checkout summary and on the order details
   table. Floated rather than laid out with flex, because the cell holds mixed
   inline content: the name, the quantity strong, and any item meta. A flex
   container would need a wrapper around all of it that WooCommerce does not
   print.

   The float is contained with a ::after on the cell rather than overflow or
   display: flow-root, either of which would change how a table cell behaves.
   ====================================================================== */

/* Storefront caps the name column at 45%, which it sized for a name with
   nothing beside it, and wraps it with overflow-wrap: anywhere. That value
   both allows a break inside a word and lowers the column's min-content
   contribution, so the auto table layout is free to squeeze it. With a 48px
   float in the cell that left roughly 82px for the text on a phone, less than
   the word "BigCommerce" needs, and the name broke mid-word.

   The subtotal column only ever holds a short amount, so the width goes to the
   side that has to hold a product name and an image. */
.woocommerce-checkout #order_review table.shop_table th.product-name,
.woocommerce-checkout #order_review table.shop_table td.product-name,
.woocommerce-order-received table.order_details th.product-name,
.woocommerce-order-received table.order_details td.product-name {
	width: 68%;
}

.cf-line-thumb {
	float: left;
	margin: .1rem .75rem .25rem 0;
	line-height: 0;
}

.cf-line-thumb img {
	display: block;
	width: 48px;
	height: auto;
	background: #fff;
	border: 1px solid var(--cf-line);
	border-radius: var(--cf-radius-sm);
}

.woocommerce-checkout #order_review table.shop_table td.product-name::after,
.woocommerce-order-received table.order_details td.product-name::after {
	content: "";
	display: block;
	clear: both;
}

@media (max-width: 767px) {
	.cf-line-thumb img { width: 40px; }
}


/* =========================================================================
   Add to cart opens the drawer
   =========================================================================
   WooCommerce inserts a "View cart" link after a loop button once the item is
   added. With the drawer opening on the same event that link is a second, worse
   answer to the same question, so it is hidden.

   Gated on .cf-drawer-ready, which the script adds to <html> only once the
   drawer has initialised. If the script fails to load, or throws before that
   line, the class never appears and the link stays exactly where WooCommerce
   put it. The page cannot end up with neither a drawer nor a way to the cart.
   ====================================================================== */

.cf-drawer-ready .woocommerce a.added_to_cart,
.cf-drawer-ready ul.products li.product a.added_to_cart {
	display: none;
}

/* The single product button spends a moment in flight now that its form posts
   over AJAX. WooCommerce's own loop buttons use the same class. */
.woocommerce div.product form.cart button.loading,
.woocommerce div.product form.cart .button.loading {
	opacity: .75;
	cursor: progress;
}


/* =========================================================================
   Cart line items on narrow screens
   =========================================================================
   Storefront stacks a responsive table by turning every cell into its own
   full-width row with the column name printed from data-title. Correct, and
   very tall: six labelled rows per item before the coupon.

   Each item row becomes a grid instead. A tr is display: table-row by default
   and can be made a grid container directly, so the cells move into named
   areas with no wrapper that WooCommerce does not print:

       thumb  name      remove
       thumb  price     price
       thumb  quantity  subtotal

   The .actions row is deliberately not matched. It holds the coupon field and
   Update cart and should stay full width.

   The data-title labels are kept on price, quantity and subtotal rather than
   hidden. Storefront hides the thead at this width, which takes the column
   headers out of the accessibility tree, so those generated labels are the
   only thing naming the values. A bare "1" and a bare "$19.99" are ambiguous
   without them. Only the Product label goes, since the name is self-evident.
   ====================================================================== */

@media (max-width: 767px) {
	.woocommerce-cart .woocommerce-cart-form table.cart tbody tr.cart_item {
		display: grid;
		grid-template-columns: 76px minmax(0, 1fr) auto;
		grid-template-areas:
			"thumb name     remove"
			"thumb price    price"
			"thumb quantity quantity"
			"thumb subtotal subtotal";
		align-items: center;
		column-gap: .9rem;
		row-gap: .4rem;
		padding: 1rem;
		border-bottom: 1px solid var(--cf-line);
	}

	.woocommerce-cart .woocommerce-cart-form table.cart tbody tr.cart_item > td {
		padding: 0;
		border: 0;
		text-align: left;
	}

	.woocommerce-cart .woocommerce-cart-form table.cart tbody tr.cart_item > td.product-thumbnail {
		grid-area: thumb;
		align-self: start;
	}

	.woocommerce-cart .woocommerce-cart-form table.cart tbody tr.cart_item > td.product-thumbnail img {
		width: 76px;
		margin: 0;
	}

	.woocommerce-cart .woocommerce-cart-form table.cart tbody tr.cart_item > td.product-name {
		grid-area: name;
		font-size: .98rem;
		line-height: 1.35;
	}

	.woocommerce-cart .woocommerce-cart-form table.cart tbody tr.cart_item > td.product-remove {
		grid-area: remove;
		align-self: start;
	}

	.woocommerce-cart .woocommerce-cart-form table.cart tbody tr.cart_item > td.product-price {
		grid-area: price;
	}

	.woocommerce-cart .woocommerce-cart-form table.cart tbody tr.cart_item > td.product-quantity {
		grid-area: quantity;
	}

	.woocommerce-cart .woocommerce-cart-form table.cart tbody tr.cart_item > td.product-subtotal {
		grid-area: subtotal;
		text-align: right;
		font-weight: 700;
		color: var(--cf-ink);
		white-space: nowrap;
	}

	/* Storefront floats these labels left of a full-width cell. In a grid cell
	   that would push the value onto its own line, so they run inline. */
	.woocommerce-cart .woocommerce-cart-form table.cart tbody tr.cart_item > td::before {
		float: none;
		display: inline;
		margin-right: .35rem;
		font-family: var(--cf-display);
		font-size: .68rem;
		font-weight: 700;
		letter-spacing: .08em;
		text-transform: uppercase;
		color: var(--cf-muted);
	}

	.woocommerce-cart .woocommerce-cart-form table.cart tbody tr.cart_item > td.product-name::before {
		content: none;
	}

	.woocommerce-cart .woocommerce-cart-form table.cart tbody tr.cart_item .quantity .qty {
		width: 4rem;
	}

	/* The row draws its own separator now. */
	.woocommerce-cart .woocommerce-cart-form table.cart tbody tr.cart_item:last-of-type {
		border-bottom: 0;
	}
}


/* =========================================================================
   Quantity stepper
   =========================================================================
   WooCommerce ships no stepper, and Storefront hides .plus and .minus inside
   table.cart, which is why these carry cf-qty instead. The buttons print
   either side of the field on both the cart and the product page, and not at
   all when the field is the hidden one WooCommerce renders for anything sold
   individually.
   ====================================================================== */

/* Three separated controls rather than one joined group. Butted against the
   field the buttons read as part of it and are easy to mis-tap on a phone; a
   gap gives each one its own edge, which is also how the old site does it. */
.quantity:has(.cf-qty) {
	display: inline-flex;
	align-items: stretch;
	gap: .5rem;
	vertical-align: middle;
}

.cf-qty {
	display: inline-grid;
	place-items: center;
	width: 40px;
	min-height: 40px;
	padding: 0;
	background: var(--cf-tint);
	border: 1px solid var(--cf-line-strong);
	border-radius: var(--cf-radius-sm);
	color: var(--cf-ink);
	font-family: var(--cf-display);
	font-size: 1.05rem;
	line-height: 1;
	cursor: pointer;
}

.cf-qty:hover {
	background: var(--cf-line);
	color: var(--cf-indigo);
}

.cf-qty:focus-visible {
	outline: 2px solid var(--cf-indigo);
	outline-offset: -2px;
}

.quantity:has(.cf-qty) .qty {
	min-height: 40px;
}

/* The field is type="number", so the browser draws its own spinner inside it.
 * With the buttons either side that is a second control for the same job, in a
 * much smaller target.
 *
 * Scoped to a field that actually has the stepper. If the buttons ever fail to
 * render, the native arrows are still there and the quantity is still
 * changeable, rather than the field losing both ways of adjusting it.
 *
 * The type stays as number: it carries the keyboard, the validation and the
 * role that assistive technology reads. Only the painted arrows go. */
.quantity:has(.cf-qty) .qty {
	-moz-appearance: textfield;
	appearance: textfield;
}

.quantity:has(.cf-qty) .qty::-webkit-outer-spin-button,
.quantity:has(.cf-qty) .qty::-webkit-inner-spin-button {
	-webkit-appearance: none;
	appearance: none;
	margin: 0;
}

.woocommerce-cart .woocommerce-cart-form table.cart .quantity:has(.cf-qty) .qty {
	width: 3.5rem;
}

/* More clearance on a phone, where the header sits directly above and a
   mis-tap lands on it. */
@media (max-width: 767px) {
	:root { --cf-crumb-gap: 1.6rem; }
}

@media (max-width: 767px) {
	.cf-qty { width: 44px; min-height: 44px; }

	.quantity:has(.cf-qty) .qty,
	.woocommerce-cart .woocommerce-cart-form table.cart .quantity:has(.cf-qty) .qty {
		min-height: 44px;
		width: 3.25rem;
	}
}


/* ==========================================================================
   Link system
   ==========================================================================

   One place decides how a link looks, in both states, everywhere.

   The fault this replaces is the same shape as the parent layout register
   near the top of this file. Storefront underlines every anchor inside
   .hentry .entry-content and removes the underline again on hover, at
   specificity (0,2,1) and (0,3,1). Component rules in this theme are written
   at (0,1,0) or (0,1,1), so on any page whose body runs through the_content
   the parent decided the answer and the component rule was dead text. The
   Contact route cards are the visible case: the whole card, heading and
   description included, is underlined today because .ct-route says
   text-decoration: none at (0,1,0) and loses.

   The rule, on a light background: a text link is --cf-link and underlined at
   rest, and on hover it keeps the underline and moves to --cf-link-hover.
   Breadcrumbs are out of it by decision. The footer is on the indigo band and
   has its own pair above.

   Invariant, same as the layout register: a component that needs to suppress
   the underline inside content is added to the register below in the same
   edit that creates it. Writing text-decoration: none on its own rule is not
   enough and will look like it worked everywhere except inside content.
   ========================================================================== */

/* --- Text links ----------------------------------------------------------
   An anchor styled as a button is not a text link, and the :not() below is how
   these rules say so.

   1.143.0 did not carry it, and the result was that every button inside page
   content turned --cf-link-hover on hover: navy text on a dark button, which
   on the cart page made Proceed to checkout almost unreadable. Storefront
   exempts a.button, a.components-button and a.wp-block-button__link from its
   own underline, but only from the underline, so nothing was protecting the
   colour. .added_to_cart is added on top: WooCommerce styles it as a button
   and Storefront has never heard of it, so it was picking up a rest underline
   too.

   The first three names are Storefront's own definition of a button link,
   taken from its remove-button-underline mixin rather than invented here.
   Anything else the theme styles as a button belongs in this list, in the same
   edit that styles it.

   Colour is deliberately not set here. The base a rule already supplies
   --cf-link to anything that does not override it, so a broad colour
   declaration at this weight would repaint component links that set their own
   ink or muted colour on purpose. Decoration is the only thing this rule owns.
   ------------------------------------------------------------------------ */

.hentry .entry-content a:not(.button, .components-button, .wp-block-button__link, .added_to_cart),
.cf-post__body a:not(.button, .components-button, .wp-block-button__link, .added_to_cart),
.cf-comment__text a:not(.button, .components-button, .wp-block-button__link, .added_to_cart),
.cf-section__head a.cf-section__link {
	text-decoration: underline;
	text-decoration-thickness: var(--cf-underline);
	text-underline-offset: var(--cf-underline-offset);
}

/* The contents box reads as a list of links, so it joins the text links
   rather than the register. It is the one component whose rest colour
   changes: it was --cf-ink, which made it the only link on a light background
   that was not --cf-link. */

.hentry .entry-content .cf-toc a {
	color: var(--cf-link);
	text-decoration: underline;
	text-decoration-thickness: var(--cf-underline);
	text-underline-offset: var(--cf-underline-offset);
}

/* --- Hover ---------------------------------------------------------------
   The underline is restated outside the hover media query on purpose. A touch
   screen leaves :hover stuck on whatever the finger last passed over, and
   Storefront's own hover rule removes the underline, so without this the line
   would vanish under a stray tap on a phone. The colour change is the part
   that belongs to a real pointer.
   ------------------------------------------------------------------------ */

.hentry .entry-content a:not(.button, .components-button, .wp-block-button__link, .added_to_cart):hover,
.cf-post__body a:not(.button, .components-button, .wp-block-button__link, .added_to_cart):hover,
.cf-comment__text a:not(.button, .components-button, .wp-block-button__link, .added_to_cart):hover,
.hentry .entry-content .cf-toc a:hover,
.cf-section__head a.cf-section__link:hover {
	text-decoration: underline;
	text-decoration-thickness: var(--cf-underline);
	text-underline-offset: var(--cf-underline-offset);
}

@media (hover: hover) {

	.hentry .entry-content a:not(.button, .components-button, .wp-block-button__link, .added_to_cart):hover,
	.cf-post__body a:not(.button, .components-button, .wp-block-button__link, .added_to_cart):hover,
	.cf-comment__text a:not(.button, .components-button, .wp-block-button__link, .added_to_cart):hover,
	.hentry .entry-content .cf-toc a:hover,
	.cf-section__head a.cf-section__link:hover {
		color: var(--cf-link-hover);
	}
}

/* --- Parent link register ------------------------------------------------
   Components that are controls rather than text: a card, a chip, a title, a
   breadcrumb. Each already says text-decoration: none on its own rule; this
   restates it at a weight that outranks the parent, inside content, for both
   states. Listing a component that never renders inside content costs
   nothing and is the safer error.
   ------------------------------------------------------------------------ */

.hentry .entry-content :is(
	.ct-route,
	.ab-founder__link,
	a.cf-chip,
	a.added_to_cart,
	.cf-post-card__title a,
	.cf-feature__title a,
	.cf-keep__card,
	.cf-byline a,
	.cf-author__name,
	.cf-comment__when,
	.cf-comment__reply a,
	.cf-search-pages a,
	.cf-acct-back a,
	.cf-breadcrumb a,
	.woocommerce-breadcrumb a,
	.cf-pager__pages .page-numbers,
	.woocommerce-tabs ul.tabs li.active a
),
.hentry .entry-content :is(
	.ct-route,
	.ab-founder__link,
	a.cf-chip,
	a.added_to_cart,
	.cf-post-card__title a,
	.cf-feature__title a,
	.cf-keep__card,
	.cf-byline a,
	.cf-author__name,
	.cf-comment__when,
	.cf-comment__reply a,
	.cf-search-pages a,
	.cf-acct-back a,
	.cf-breadcrumb a,
	.woocommerce-breadcrumb a,
	.cf-pager__pages .page-numbers,
	.woocommerce-tabs ul.tabs li.active a
):hover {
	text-decoration: none;
}

/* The route card is a whole anchor wrapping a heading, a description and a
   call to action. Only the call to action should read as the link, so the
   underline is drawn on it rather than on the card, and the card's hover
   moves its colour. */

.hentry .entry-content .ct-route em {
	text-decoration: underline;
	text-decoration-thickness: var(--cf-underline);
	text-underline-offset: var(--cf-underline-offset);
}

@media (hover: hover) {

	.hentry .entry-content .ct-route:hover em,
	.hentry .entry-content .ct-route:focus-within em {
		color: var(--cf-link-hover);
	}
}

/* --- Tap floor on touch --------------------------------------------------
   A standalone link is not inside a sentence, so 2.5.8's inline exception
   does not cover it. Measured on a phone these came out 24 to 25px tall,
   which clears the 24px minimum by about a pixel. This lifts them to 44px
   without moving the text: the box grows around it.
   ------------------------------------------------------------------------ */

@media (pointer: coarse) {

	.cf-section__head a.cf-section__link {
		display: inline-flex;
		align-items: center;
		min-height: 44px;
	}
}
