/* ==========================================================================
   COMPONENTS — buttons, hero, category tiles, cards, trust row, forms.
   ========================================================================== */

/* --------------------------------------------------------------------------
   Buttons. 44px minimum block-size everywhere — the touch-target floor.
   -------------------------------------------------------------------------- */

.lm-btn {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: var(--lm-s2);
	min-block-size: 44px;
	padding-inline: var(--lm-s5);
	padding-block: var(--lm-s2);
	border: 1px solid transparent;
	border-radius: var(--lm-radius-sm);
	font-family: inherit;
	font-size: var(--lm-fs-base);
	font-weight: 500;
	line-height: 1.4;
	text-align: center;
	text-decoration: none;
	cursor: pointer;
	transition: background-color var(--lm-dur) var(--lm-ease),
	            border-color var(--lm-dur) var(--lm-ease),
	            color var(--lm-dur) var(--lm-ease),
	            transform var(--lm-dur-fast) var(--lm-ease-out);
}

/* Scale rather than a 1px nudge — a press should look pressed. Fast, because
   feedback that lags the finger stops feeling like feedback. */
.lm-btn:active { transform: scale(0.98); }

.lm-btn--primary {
	background-color: var(--lm-navy);
	color: var(--lm-on-primary);
}

.lm-btn--primary:hover {
	background-color: var(--lm-navy-deep);
	color: var(--lm-on-primary);
}

.lm-btn--secondary {
	background-color: transparent;
	border-color: var(--lm-navy);
	color: var(--lm-navy);
}

.lm-btn--secondary:hover {
	background-color: var(--lm-navy);
	color: var(--lm-on-primary);
}

.lm-btn--ghost {
	background-color: transparent;
	color: var(--lm-navy);
	padding-inline: var(--lm-s2);
}

.lm-btn--ghost:hover {
	color: var(--lm-teal);
	text-decoration: underline;
}

.lm-btn--block {
	inline-size: 100%;
}

.lm-btn[disabled],
.lm-btn[aria-disabled="true"] {
	opacity: 0.55;
	cursor: not-allowed;
	transform: none;
}

/* Inline-end-pointing chevron that flips with direction automatically. */
.lm-btn__arrow {
	inline-size: 1em;
	block-size: 1em;
	flex: 0 0 auto;
}

[dir="rtl"] .lm-btn__arrow { transform: scaleX(-1); }

/* --------------------------------------------------------------------------
   HERO

   Production used a one-slide slider over a 2268x750 background PNG, with the
   three stat "badges" baked into 301x301 images and hidden entirely below
   1024px. Here: no slider, CSS + inline SVG for the ground, live text stats
   that are visible on every screen size.
   -------------------------------------------------------------------------- */

.lm-hero {
	position: relative;
	background-color: var(--lm-wash);
	overflow: hidden;
	padding-block: var(--lm-s7);
}

/* The chevron ribbon, inlined as a background from the 641-byte source SVG
   that every decorative PNG on the old site was rendered from. */
.lm-hero__pattern {
	position: absolute;
	inset-block-start: 0;
	inset-inline-end: 0;
	inline-size: min(560px, 58%);
	block-size: 100%;
	color: var(--lm-navy);
	opacity: 0.07;
	pointer-events: none;
}

.lm-hero__pattern svg {
	inline-size: 100%;
	block-size: 100%;
}

.lm-hero__inner {
	position: relative;
	display: grid;
	gap: var(--lm-s6);
	align-items: center;
	grid-template-columns: 1fr;
}

/* Centred on phones. The hero stacks to a single column there, so
   start-aligned copy sits against one edge with a ragged gap opposite it;
   centring balances the column. The stat cards keep their own start-aligned
   internal layout — only the surrounding copy centres. */
@media (max-width: 767px) {
	.lm-hero__copy {
		text-align: center;
	}

	.lm-hero__lead {
		margin-inline: auto;
	}

	.lm-hero__cta {
		justify-content: center;
	}
}

@media (min-width: 768px) {
	.lm-hero { padding-block: var(--lm-s8); }
	.lm-hero__inner {
		grid-template-columns: 1.05fr 0.95fr;
		gap: var(--lm-s7);
	}
}

@media (min-width: 1024px) {
	.lm-hero__inner {
		grid-template-columns: 1fr 0.85fr 0.7fr;
	}
}

.lm-hero__title {
	font-size: var(--lm-fs-display);
	font-weight: 400;   /* production ran weight 400 headings; only the brand span is bold */
	margin-block-end: var(--lm-s4);
}

.lm-hero__title .lm-grad {
	font-weight: 700;
	display: inline-block;
}

.lm-hero__lead {
	color: var(--lm-ink);
	max-width: 46ch;
	margin-block-end: var(--lm-s5);
}

.lm-hero__cta {
	display: flex;
	flex-wrap: wrap;
	gap: var(--lm-s3);
	align-items: center;
}

.lm-hero__art {
	justify-self: center;
}

.lm-hero__art img {
	inline-size: min(100%, 380px);
	filter: drop-shadow(0 18px 32px rgb(3 64 120 / 0.16));
}

@media (min-width: 1024px) {
	.lm-hero__art img { inline-size: min(100%, 420px); }
}

/* --- Stat rail -----------------------------------------------------------
   Was three 301x301 PNGs with "+1000 / +15 / 98%" rasterised into pixels,
   `hide-for-small` so mobile users never saw them at all.
   -------------------------------------------------------------------------- */

/* One card per row at every width. Three across on a 360px screen left each
   card ~100px wide, which forced the figure above the text and squeezed both
   labels to two or three words per line. Full width keeps the same horizontal
   composition the desktop column uses. */
.lm-stats {
	display: grid;
	gap: var(--lm-s3);
	grid-template-columns: 1fr;
	/* This is a <ul>, so the base `:where(ul, ol)` indent applied 24px of
	   padding-inline-start — which in RTL is the right edge, leaving the rail
	   visibly out of line with every other block in the hero. */
	list-style: none;
	margin: 0;
	padding: 0;
}

.lm-stat {
	display: flex;
	align-items: center;
	gap: var(--lm-s3);
	background-color: var(--lm-bg);
	border: 1px solid var(--lm-border);
	border-radius: 17px;   /* prod bg_radius="17" on these exact cards */
	padding: var(--lm-s3);
	box-shadow: var(--lm-shadow-sm);
}

.lm-stat__fig {
	flex: 0 0 auto;
	display: grid;
	place-items: center;
	inline-size: 52px;
	block-size: 52px;
	border-radius: var(--lm-radius-sm);
	/* Not --lm-gradient: white on its teal stop is 4.43:1, a hair under AA.
	   Starting from the text-weight teal keeps the same look and clears it. */
	background-image: linear-gradient(180deg, var(--lm-teal-text), var(--lm-navy));
	color: var(--lm-on-primary);
	font-weight: 700;
	font-size: var(--lm-fs-base);
	letter-spacing: -0.02em;
}

.lm-stat__body { min-width: 0; }

.lm-stat__title {
	display: block;
	color: var(--lm-navy);
	font-size: var(--lm-fs-base);
	font-weight: 500;
	line-height: 1.35;
}

.lm-stat__note {
	display: block;
	color: var(--lm-ink-muted);
	font-size: var(--lm-fs-sm);
	line-height: 1.4;
}



/* --------------------------------------------------------------------------
   CATEGORY TILES

   Replaces eight 300x300 PNGs (341 KB total) that were Apple Color Emoji
   inside a navy ring — a licensing problem as much as a design one. These are
   inline SVG at roughly 200 bytes each and recolour with currentColor.
   -------------------------------------------------------------------------- */

.lm-cats {
	display: grid;
	gap: var(--lm-s4);
	grid-template-columns: repeat(2, 1fr);
}

@media (min-width: 480px) { .lm-cats { grid-template-columns: repeat(3, 1fr); } }
@media (min-width: 768px) { .lm-cats { grid-template-columns: repeat(4, 1fr); } }
@media (min-width: 1024px) { .lm-cats { grid-template-columns: repeat(8, 1fr); } }

.lm-cat {
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: var(--lm-s2);
	padding: var(--lm-s3) var(--lm-s2);
	border-radius: var(--lm-radius);
	color: var(--lm-ink-strong);
	text-decoration: none;
	transition: background-color var(--lm-dur) var(--lm-ease),
	            transform var(--lm-dur) var(--lm-ease);
}

.lm-cat:hover {
	background-color: var(--lm-bg);
	color: var(--lm-navy);
	transform: translateY(-2px);
	box-shadow: var(--lm-shadow-sm);
}

.lm-cat__icon {
	display: grid;
	place-items: center;
	inline-size: 64px;
	block-size: 64px;
	border-radius: 50%;
	border: 2px solid var(--lm-teal);
	background-color: var(--lm-bg);
	color: var(--lm-navy);
	transition: background-color var(--lm-dur) var(--lm-ease),
	            color var(--lm-dur) var(--lm-ease),
	            border-color var(--lm-dur) var(--lm-ease);
}

.lm-cat:hover .lm-cat__icon {
	background-color: var(--lm-navy);
	border-color: var(--lm-navy);
	color: var(--lm-on-primary);
}

.lm-cat__icon svg {
	inline-size: 30px;
	block-size: 30px;
}

.lm-cat__label {
	font-size: var(--lm-fs-sm);
	font-weight: 500;
	text-align: center;
	line-height: 1.35;
}

/* --------------------------------------------------------------------------
   PROMO CARDS

   Replaces four 400x208 PNGs whose headlines were baked into the image, with
   no alt text, all four linking to the same URL.
   -------------------------------------------------------------------------- */

.lm-cards {
	display: grid;
	gap: var(--lm-s4);
	grid-template-columns: 1fr;
}

@media (min-width: 560px) { .lm-cards { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1024px) { .lm-cards { grid-template-columns: repeat(4, 1fr); } }

.lm-promo {
	display: flex;
	flex-direction: column;
	gap: var(--lm-s2);
	padding: var(--lm-s5);
	border-radius: var(--lm-radius-lg);
	background-color: var(--lm-bg);
	border: 1px solid var(--lm-border);
	color: var(--lm-ink);
	text-decoration: none;
	block-size: 100%;
	transition: border-color var(--lm-dur) var(--lm-ease),
	            box-shadow var(--lm-dur) var(--lm-ease),
	            transform var(--lm-dur) var(--lm-ease);
}

.lm-promo:hover {
	border-color: var(--lm-teal);
	box-shadow: var(--lm-shadow);
	transform: translateY(-3px);
	color: var(--lm-ink);
}

.lm-promo__icon {
	inline-size: 40px;
	block-size: 40px;
	color: var(--lm-teal);
}

.lm-promo__title {
	font-size: var(--lm-fs-lg);
	font-weight: 500;
	color: var(--lm-navy);
	margin: 0;
}

.lm-promo__text {
	font-size: var(--lm-fs-base);
	color: var(--lm-ink-muted);
	margin: 0;
	flex: 1 1 auto;
}

.lm-promo__more {
	font-size: var(--lm-fs-base);
	font-weight: 500;
	color: var(--lm-teal-text);
	display: inline-flex;
	align-items: center;
	gap: var(--lm-s1);
}

/* --------------------------------------------------------------------------
   CRAFT STORY BAND
   Replaces the dead "flash sale" section: a 2024-hardcoded countdown, a fire
   emoji PNG, and a product grid with no sale filter and no sale prices.
   -------------------------------------------------------------------------- */

.lm-story {
	display: grid;
	gap: var(--lm-s6);
	align-items: center;
	grid-template-columns: 1fr;
}

@media (min-width: 768px) {
	.lm-story { grid-template-columns: 0.9fr 1.1fr; gap: var(--lm-s7); }
}

.lm-story__art {
	justify-self: center;
	position: relative;
}

.lm-story__art img {
	inline-size: min(100%, 340px);
	border-radius: var(--lm-radius-lg);
}

.lm-story__list {
	list-style: none;
	padding: 0;
	margin-block: var(--lm-s4) 0;
	display: grid;
	gap: var(--lm-s3);
}

.lm-story__list li {
	display: flex;
	align-items: flex-start;
	gap: var(--lm-s3);
	margin: 0;
}

.lm-story__tick {
	flex: 0 0 auto;
	inline-size: 24px;
	block-size: 24px;
	color: var(--lm-success-strong);   /* --lm-success is 2.65:1 on white */
	margin-block-start: 2px;
}

/* --------------------------------------------------------------------------
   TRUST ROW
   The five footer USP icons, previously shipped as 301x301 PNGs with
   keyboard-mash filenames (saddawdawas.png, dawd.png, adw.png, sadas.png).
   Same artwork, now inline SVG under 3 KB total.
   -------------------------------------------------------------------------- */

.lm-trust {
	display: grid;
	gap: var(--lm-s4);
	grid-template-columns: repeat(2, 1fr);
	list-style: none;
	margin: 0;
	padding: 0;   /* same base-list indent as .lm-stats */
}

@media (min-width: 640px) { .lm-trust { grid-template-columns: repeat(3, 1fr); } }
@media (min-width: 1024px) { .lm-trust { grid-template-columns: repeat(5, 1fr); } }

.lm-trust__item {
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: var(--lm-s2);
	text-align: center;
	padding: var(--lm-s4) var(--lm-s2);
}

.lm-trust__icon {
	inline-size: 44px;
	block-size: 44px;
	color: var(--lm-navy);
}

.lm-trust__label {
	font-size: var(--lm-fs-base);
	font-weight: 500;
	color: var(--lm-ink-strong);
	line-height: 1.4;
}

/* --------------------------------------------------------------------------
   CALLBACK / LEAD CAPTURE
   Kept from production — it is the site's only homepage form and its primary
   lead channel. Overlay colour is prod's rgba(0,68,130,0.703) on the brand navy.
   -------------------------------------------------------------------------- */

.lm-callback {
	background-color: var(--lm-navy);
	background-image: linear-gradient(135deg, var(--lm-navy-deep), var(--lm-navy) 55%, var(--lm-teal));
	color: var(--lm-on-primary);
	border-radius: var(--lm-radius-lg);
	padding: var(--lm-s6);
	position: relative;
	overflow: hidden;
}

.lm-callback__inner {
	position: relative;
	display: grid;
	gap: var(--lm-s5);
	align-items: center;
	grid-template-columns: 1fr;
}

@media (min-width: 768px) {
	.lm-callback { padding: var(--lm-s7); }
	.lm-callback__inner { grid-template-columns: 1.3fr 0.7fr; gap: var(--lm-s6); }
}

.lm-callback h2,
.lm-callback p { color: var(--lm-on-primary); }

.lm-callback h2 {
	display: flex;
	align-items: center;
	gap: var(--lm-s3);
}

.lm-callback__icon {
	inline-size: 34px;
	block-size: 34px;
	flex: 0 0 auto;
}

.lm-callback__lead {
	max-width: 54ch;
	opacity: 0.92;
	margin-block-end: 0;
}

.lm-callback__art { justify-self: center; }

.lm-callback__art img { inline-size: min(100%, 220px); }

/* --------------------------------------------------------------------------
   FORMS
   -------------------------------------------------------------------------- */

.lm-field {
	margin-block-end: var(--lm-s4);
}

.lm-field > label,
label.lm-label {
	display: block;
	margin-block-end: var(--lm-s2);
	font-size: var(--lm-fs-base);
	font-weight: 500;
	color: var(--lm-ink-strong);
}

.lm-req {
	color: var(--lm-alert-text);
	margin-inline-start: 2px;
}

input[type="text"],
input[type="email"],
input[type="tel"],
input[type="url"],
input[type="number"],
input[type="password"],
input[type="search"],
input[type="date"],
textarea,
select {
	inline-size: 100%;
	min-block-size: 44px;
	padding: var(--lm-s2) var(--lm-s3);
	border: 1px solid var(--lm-border);
	border-radius: var(--lm-radius-sm);
	background-color: var(--lm-bg);
	color: var(--lm-ink-strong);
	font-family: inherit;
	font-size: var(--lm-fs-lg);   /* never below 16px: iOS zooms the viewport otherwise */
	line-height: 1.5;
	transition: border-color var(--lm-dur) var(--lm-ease),
	            box-shadow var(--lm-dur) var(--lm-ease);
}

textarea { min-block-size: 120px; padding-block: var(--lm-s3); }

input:focus,
textarea:focus,
select:focus {
	border-color: var(--lm-teal);
	box-shadow: 0 0 0 3px rgb(18 130 162 / 0.18);
	outline: none;
}

input::placeholder,
textarea::placeholder {
	color: var(--lm-ink-muted);
	opacity: 0.75;
}

/* Invalid state — paired with a text message, never colour alone. */
input[aria-invalid="true"],
textarea[aria-invalid="true"],
select[aria-invalid="true"] {
	border-color: var(--lm-alert);
	background-color: rgb(199 4 53 / 0.03);
}

.lm-help {
	display: block;
	margin-block-start: var(--lm-s1);
	font-size: var(--lm-fs-sm);
	color: var(--lm-ink-muted);
}

.lm-error {
	display: flex;
	align-items: flex-start;
	gap: var(--lm-s2);
	margin-block-start: var(--lm-s2);
	font-size: var(--lm-fs-base);
	color: var(--lm-alert-text);
	font-weight: 500;
}

.lm-error__icon {
	flex: 0 0 auto;
	inline-size: 18px;
	block-size: 18px;
	margin-block-start: 3px;
}

/* Error summary — focusable, at the top of the form, linking to each field.
   Complements inline errors; never replaces them. */
.lm-errsum {
	border: 2px solid var(--lm-alert);
	border-radius: var(--lm-radius-sm);
	background-color: rgb(199 4 53 / 0.05);
	padding: var(--lm-s4);
	margin-block-end: var(--lm-s5);
}

.lm-errsum:focus-visible {
	outline: 3px solid var(--lm-alert);
	outline-offset: 2px;
}

.lm-errsum h2 {
	font-size: var(--lm-fs-lg);
	color: var(--lm-alert-text);
	margin-block-end: var(--lm-s2);
}

.lm-errsum ul {
	margin: 0;
	padding-inline-start: var(--lm-s5);
}

.lm-errsum a {
	color: var(--lm-alert-text);
	font-weight: 500;
}

/* Checkbox / radio rows need a real 44px hit area. */
.lm-check {
	display: flex;
	align-items: flex-start;
	gap: var(--lm-s3);
	min-block-size: 44px;
	padding-block: var(--lm-s2);
	cursor: pointer;
}

.lm-check input[type="checkbox"],
.lm-check input[type="radio"] {
	inline-size: 20px;
	block-size: 20px;
	min-block-size: 0;
	margin: 0;
	margin-block-start: 3px;
	flex: 0 0 auto;
	accent-color: var(--lm-navy);
	cursor: pointer;
}

/* --------------------------------------------------------------------------
   BADGES & NOTICES
   -------------------------------------------------------------------------- */

.lm-badge {
	display: inline-block;
	padding: 2px var(--lm-s2);
	border-radius: var(--lm-radius-pill);
	background-color: var(--lm-teal-text);   /* --lm-teal is 4.43:1 with white */
	color: var(--lm-on-primary);
	font-size: var(--lm-fs-sm);
	font-weight: 500;
	line-height: 1.6;
}

.lm-notice {
	display: flex;
	align-items: flex-start;
	gap: var(--lm-s3);
	padding: var(--lm-s4);
	border-radius: var(--lm-radius-sm);
	border-inline-start: 4px solid var(--lm-teal);
	background-color: var(--lm-surface);
	font-size: var(--lm-fs-base);
	margin-block-end: var(--lm-s4);
}

.lm-notice--error { border-inline-start-color: var(--lm-alert); }
.lm-notice--success { border-inline-start-color: var(--lm-success); }

/* --------------------------------------------------------------------------
   EMPTY STATE — for category archives with no products yet. Directly targets
   the "homepage looks too empty" complaint by making sparse pages read as
   deliberate rather than broken.
   -------------------------------------------------------------------------- */

.lm-empty {
	grid-column: 1 / -1;
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: var(--lm-s3);
	padding: var(--lm-s8) var(--lm-s4);
	text-align: center;
	border: 1px dashed var(--lm-border-strong);
	border-radius: var(--lm-radius-lg);
	background-color: var(--lm-wash);
	color: var(--lm-ink-muted);
}

.lm-empty__icon {
	inline-size: 56px;
	block-size: 56px;
	color: var(--lm-teal);
	opacity: 0.6;
}

/* --------------------------------------------------------------------------
   PAGE HEADER (archives, single pages)
   -------------------------------------------------------------------------- */

.lm-pagehead {
	background-color: var(--lm-wash);
	border-block-end: 1px solid var(--lm-border);
	padding-block: var(--lm-s6);
	margin-block-end: var(--lm-s7);
}

.lm-pagehead h1 { margin-block-end: var(--lm-s2); }

.lm-pagehead p {
	color: var(--lm-ink-muted);
	max-width: 60ch;
	margin-block-end: 0;
}

.lm-breadcrumb {
	font-size: var(--lm-fs-sm);
	color: var(--lm-ink-muted);
	margin-block-end: var(--lm-s3);
}

.lm-breadcrumb a { color: var(--lm-ink-muted); text-decoration: none; }
.lm-breadcrumb a:hover { color: var(--lm-navy); text-decoration: underline; }

/* --------------------------------------------------------------------------
   PROSE — the five legal pages and other long-form content.
   -------------------------------------------------------------------------- */

.lm-prose {
	max-width: 72ch;
}

.lm-prose h2 {
	margin-block-start: var(--lm-s6);
	font-size: var(--lm-fs-lg);
}

.lm-prose h3 {
	margin-block-start: var(--lm-s5);
	font-size: var(--lm-fs-lg);
}

.lm-prose table { margin-block: var(--lm-s5); }

.lm-prose :is(h2, h3) + p { margin-block-start: 0; }

/* --------------------------------------------------------------------------
   MAP — the contact page's location embed.

   Replaces an overlay card that the previous page carried inline. That card was
   absolutely positioned with physical `right`, sized at 20/15/12px (outside the
   type scale), and set near-white text over a `backdrop-filter` with no
   background colour of its own — so its legibility depended entirely on how
   light the map tiles underneath happened to be.

   A caption BELOW the frame is legible unconditionally, needs no stacking
   context, and flips with the document rather than being pinned to one side.

   The iframe is a third-party embed, so it is `loading="lazy"`: it costs
   nothing until the visitor actually scrolls the map into view.
   -------------------------------------------------------------------------- */

.lm-map {
	margin-block: var(--lm-s5);
	margin-inline: 0;
	border: 1px solid var(--lm-border);
	border-radius: var(--lm-radius);
	overflow: hidden;
	background-color: var(--lm-surface);
}

.lm-map__frame {
	display: block;
	inline-size: 100%;
	block-size: 320px;
	border: 0;
}

@media (min-width: 768px) {
	.lm-map__frame { block-size: 420px; }
}

.lm-map__caption {
	padding: var(--lm-s3) var(--lm-s4);
	border-block-start: 1px solid var(--lm-border);
	font-size: var(--lm-fs-base);
	color: var(--lm-ink);
}

/* Prose pages get their buttons from content, so give a content-level button
   the same block spacing a paragraph would have. */
.lm-prose .lm-btn { margin-block-start: var(--lm-s2); }

/* --------------------------------------------------------------------------
   Contact Form 7 inside the callback band.

   CF7 emits its own markup and cannot be restructured from the theme, so it is
   styled by targeting what it actually outputs. The label is made visible —
   production shipped a placeholder-only "۰۹", and a placeholder is not a label:
   it disappears the moment the customer starts typing.
   -------------------------------------------------------------------------- */

.lm-callback__form { margin-block-start: var(--lm-s5); }

.lm-callback__form .wpcf7-form { margin: 0; }

.lm-callback__form label {
	display: block;
	margin-block-end: var(--lm-s2);
	font-size: var(--lm-fs-base);
	font-weight: 500;
	color: var(--lm-on-primary);
}

.lm-callback__form .wpcf7-form-control-wrap { display: block; }

.lm-callback__form input[type="tel"] {
	inline-size: 100%;
	background-color: color-mix(in srgb, var(--lm-on-primary) 12%, transparent);
	border-color: color-mix(in srgb, var(--lm-on-primary) 35%, transparent);
	color: var(--lm-on-primary);
}

.lm-callback__form input[type="tel"]::placeholder {
	color: color-mix(in srgb, var(--lm-on-primary) 62%, transparent);
	opacity: 1;
}

.lm-callback__form input[type="tel"]:focus {
	background-color: color-mix(in srgb, var(--lm-on-primary) 18%, transparent);
	border-color: var(--lm-on-primary);
	box-shadow: 0 0 0 3px color-mix(in srgb, var(--lm-on-primary) 26%, transparent);
}

.lm-callback__form input[type="submit"] {
	min-block-size: 44px;
	inline-size: 100%;
	margin-block-start: var(--lm-s3);
	padding-inline: var(--lm-s6);
	border: 0;
	border-radius: var(--lm-radius-sm);
	background-color: var(--lm-on-primary);
	color: var(--lm-navy);
	font-family: inherit;
	font-size: var(--lm-fs-lg);
	font-weight: 700;
	cursor: pointer;
	transition: background-color var(--lm-dur) var(--lm-ease);
}

.lm-callback__form input[type="submit"]:hover {
	background-color: var(--lm-wash);
}

@media (min-width: 480px) {
	/* Field and button share a row once there is space for both. */
	.lm-callback__form .wpcf7-form > p:last-of-type,
	.lm-callback__form form > p:last-of-type {
		display: flex;
		gap: var(--lm-s3);
		align-items: flex-end;
	}
	.lm-callback__form input[type="submit"] {
		inline-size: auto;
		margin-block-start: 0;
		flex: 0 0 auto;
	}
}

/* CF7 response messages, in the band's inverted colour scheme. */
.lm-callback__form .wpcf7-response-output {
	margin: var(--lm-s3) 0 0;
	padding: var(--lm-s3);
	border: 1px solid color-mix(in srgb, var(--lm-on-primary) 40%, transparent);
	border-radius: var(--lm-radius-sm);
	font-size: var(--lm-fs-base);
	color: var(--lm-on-primary);
}

.lm-callback__form .wpcf7-not-valid-tip {
	display: block;
	margin-block-start: var(--lm-s2);
	font-size: var(--lm-fs-base);
	font-weight: 500;
	color: #ffd7de;
}

.lm-callback__art {
	justify-self: center;
	inline-size: 100%;
	display: grid;
	place-items: center;
}

/* A definite size, not a percentage. Inside a `justify-self: center` grid item
   the wrapper sizes to the SVG's intrinsic width, so a percentage resolved
   against that and left ~100px of dead space on one side. */
.lm-callback__deco {
	inline-size: 160px;
	block-size: 160px;
	color: color-mix(in srgb, var(--lm-on-primary) 38%, transparent);
}

/* Search form used on 404 and search pages. */
.lm-searchform {
	display: flex;
	flex-wrap: wrap;
	gap: var(--lm-s2);
	max-width: 520px;
	margin-block: var(--lm-s4);
}

.lm-searchform input[type="search"] { flex: 1 1 220px; }

.lm-searchlist {
	list-style: none;
	margin: 0;
	padding: 0;
	display: grid;
	gap: var(--lm-s4);
}

.lm-searchlist li {
	padding-block-end: var(--lm-s4);
	border-block-end: 1px solid var(--lm-border);
	margin: 0;
}

.lm-searchlist a {
	font-size: var(--lm-fs-lg);
	font-weight: 500;
	color: var(--lm-navy);
	text-decoration: none;
}

.lm-searchlist p {
	margin-block: var(--lm-s1) 0;
	color: var(--lm-ink-muted);
	font-size: var(--lm-fs-base);
}

/* Post thumbnails on the blog index. */
.lm-post__thumb img {
	border-radius: var(--lm-radius-sm);
	aspect-ratio: 4 / 3;
	object-fit: cover;
	inline-size: 100%;
}

/* ==========================================================================
   SCROLL REVEAL

   The `.lm-reveal` class is added by JavaScript, never present in the served
   HTML. That is the whole safety design: if the JS bundle fails to load, no
   element ever receives the class, so nothing is hidden and the page is simply
   static. Putting `opacity: 0` on a plain content selector would mean a single
   failed request renders the entire site blank.

   Only transform and opacity animate, so this stays on the compositor and never
   triggers layout.
   ========================================================================== */

.lm-reveal {
	opacity: 0;
	transform: translateY(var(--lm-reveal-y));
	transition: opacity 320ms var(--lm-ease-out),
	            transform 320ms var(--lm-ease-out);
	transition-delay: var(--lm-reveal-delay, 0ms);
}

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

/* The global prefers-reduced-motion block in base.css already collapses every
   transition to 0.01ms, so a reveal resolves instantly there. This is belt and
   braces for the case where the JS check is somehow bypassed. */
@media (prefers-reduced-motion: reduce) {
	.lm-reveal {
		opacity: 1;
		transform: none;
		transition: none;
	}
}

/* --------------------------------------------------------------------------
   Cart count bump.

   Adding to cart from a grid changes a number in the header that the eye is
   nowhere near. A single scale pulse is the cheapest way to say "that worked"
   without a toast covering the page.
   -------------------------------------------------------------------------- */

@keyframes lm-bump {
	0%   { transform: scale(1); }
	40%  { transform: scale(1.3); }
	100% { transform: scale(1); }
}

.lm-cart-count.is-bumping {
	animation: lm-bump 420ms var(--lm-ease-out);
}

/* Press feedback on the smaller interactive surfaces, matching .lm-btn. */
.lm-chip:active,
.lm-cat:active,
.lm-pill:active,
ul.products li.product .button:active {
	transform: scale(0.98);
}
