/*
 * Ktanim components.
 *
 * Generated by scripts/build-css.sh from assets/css/src/*.css — do not edit
 * this file; edit the source part and rebuild.
 *
 * Depends on tokens.css for every colour, radius, shadow, duration and space.
 * RTL-first: direction comes from <html dir>, and layout uses logical
 * properties only — no left/right, no rtl.css (CLAUDE.md rule 5).
 */

/* ===== src/00-base.css ===== */

/* Primitives: page frame, media reset, accessibility helpers, icon host. */

/*
 * The design system's base.css has no media reset, and WordPress serves the
 * custom logo and uploaded images at their intrinsic width. Without this the
 * store's 415px logo pushes the document to 431px on a 390px viewport and the
 * whole page scrolls sideways. Icons are excluded: ktanim_icon() sets an
 * explicit width and height on each <svg> host.
 */
img,
video,
iframe,
embed,
object {
	max-inline-size: 100%;
	block-size: auto;
}

/*
 * There is deliberately no `overflow-x: clip` backstop here.
 *
 * It breaks the sticky header on this site. The cookie-notice plugin sets
 * `body.scb-open { overflow: hidden }` while its banner is up. Normally that is
 * harmless: <html> is `visible`, so the body's overflow propagates to the
 * viewport and the body itself is treated as visible. Put any non-visible
 * overflow on <html> and that propagation stops — the body becomes its own
 * scroll container, which never scrolls, and every sticky descendant dies with
 * it. Measured in the browser: header top stayed at -1180px instead of 0.
 *
 * The backstop was redundant regardless. Nothing overflows, which is enforced by
 * the media reset above and checked at 390 and 1280 each phase.
 */

.kt-container {
	max-inline-size: var(--page-max);
	margin-inline: auto;
	padding-inline: var(--space-4);
}

@media (min-width: 820px) {

	.kt-container {
		padding-inline: var(--gutter);
	}
}

.kt-section {
	padding-block: var(--space-12);
}

@media (min-width: 820px) {

	.kt-section {
		padding-block: var(--section-y);
	}
}

.kt-icon {
	display: inline-flex;
	flex: 0 0 auto;
	vertical-align: middle;
}

/*
 * Directional glyphs — chevrons and arrows in pagination, breadcrumbs and
 * "next" affordances. Authored with LTR semantics and mirrored by direction, so
 * the same markup reads correctly either way.
 */
[dir="rtl"] .kt-icon--dir {
	transform: scaleX(-1);
}

/* Visually hidden, still announced. */
.screen-reader-text {
	position: absolute;
	overflow: hidden;
	clip-path: inset(50%);
	margin: -1px;
	border: 0;
	inline-size: 1px;
	block-size: 1px;
	padding: 0;
	white-space: nowrap;
	word-wrap: normal;
}

.kt-skip-link {
	position: absolute;
	inset-block-start: var(--space-2);
	inset-inline-start: var(--space-2);
	z-index: 100;
	transform: translateY(-200%);
	border-radius: var(--radius-pill);
	background: var(--surface-brand);
	padding: var(--space-3) var(--space-5);
	color: var(--text-inverse);
	font-family: var(--font-core);
	text-decoration: none;
	transition: var(--t-hover);
}

.kt-skip-link:focus {
	transform: translateY(0);
	color: var(--text-inverse);
}

/* --------------------------------------------------------------------------
 * Page frame
 * -------------------------------------------------------------------------- */

.kt-site {
	display: flex;
	flex-direction: column;
	min-block-size: 100vh;
}

.kt-site-main {
	flex: 1 0 auto;
}

.kt-header-area,
.kt-footer {
	flex: 0 0 auto;
}

/* --------------------------------------------------------------------------
 * Motion
 *
 * The design system asks for fades paired with a 3-4px translate and one
 * infinite animation (the hero marquee). Honour a reduced-motion preference:
 * IS 5568 follows WCAG 2.0 AA, and an endless marquee is exactly what 2.2.2
 * is about.
 * -------------------------------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {

	*,
	*::before,
	*::after {
		animation-duration: 0.01ms !important;
		animation-iteration-count: 1 !important;
		transition-duration: 0.01ms !important;
		scroll-behavior: auto !important;
	}
}

/* ===== src/10-button.css ===== */

/*
 * Button and IconButton.
 *
 * DS Button.jsx: five variants x three sizes. Pill radius, 2.5px border on every
 * variant (so a ghost button occupies the same box as a primary), --font-core at
 * regular weight, gap --space-2 between icon and label.
 *
 *   sm  36px / 0 16px / --fs-sm
 *   md  44px / 0 24px / --fs-body
 *   lg  54px / 0 34px / --fs-lg
 *
 * Hover is one step darker for solid fills and a blue-100 wash for ghost and
 * outline, which also take a blue-700 border on hover. Press is
 * translateY(--press-shift) with the shadow dropped. Never opacity, never scale.
 */

.kt-btn {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: var(--space-2);
	border: var(--border-w-thick) solid var(--blue-700);
	border-radius: var(--radius-pill);
	background: var(--blue-700);
	block-size: 44px;
	padding-inline: var(--space-6);
	color: var(--white);
	font-family: var(--font-core);
	font-size: var(--fs-body);
	font-weight: var(--fw-regular);
	line-height: 1;
	white-space: nowrap;
	text-decoration: none;
	cursor: pointer;
	box-shadow: var(--shadow-brand);
	transition:
		background var(--dur-fast) var(--ease-out),
		border-color var(--dur-fast) var(--ease-out),
		transform var(--dur-fast) var(--ease-out),
		box-shadow var(--dur-fast) var(--ease-out);
}

.kt-btn:hover {
	background: var(--blue-800);
	border-color: var(--blue-800);
	color: var(--white);
}

.kt-btn:active {
	transform: translateY(var(--press-shift));
	box-shadow: none;
}

.kt-btn[disabled],
.kt-btn.is-disabled {
	opacity: 0.45;
	cursor: not-allowed;
}

.kt-btn[disabled]:hover,
.kt-btn.is-disabled:hover {
	background: var(--blue-700);
	border-color: var(--blue-700);
}

.kt-btn[disabled]:active,
.kt-btn.is-disabled:active {
	transform: none;
}

/* Variants ---------------------------------------------------------------- */

.kt-btn--secondary {
	border-color: var(--cyan-400);
	background: var(--cyan-400);
	color: var(--blue-900);
	box-shadow: var(--shadow-sm);
}

.kt-btn--secondary:hover {
	border-color: var(--cyan-500);
	background: var(--cyan-500);
	color: var(--blue-900);
}

.kt-btn--secondary[disabled]:hover,
.kt-btn--secondary.is-disabled:hover {
	border-color: var(--cyan-400);
	background: var(--cyan-400);
}

.kt-btn--outline {
	border-color: var(--blue-700);
	background: transparent;
	color: var(--blue-700);
	box-shadow: none;
}

.kt-btn--outline:hover {
	border-color: var(--blue-700);
	background: var(--blue-100);
	color: var(--blue-700);
}

.kt-btn--ghost {
	border-color: transparent;
	background: transparent;
	color: var(--blue-700);
	box-shadow: none;
}

.kt-btn--ghost:hover {
	border-color: var(--blue-700);
	background: var(--blue-100);
	color: var(--blue-700);
}

.kt-btn--outline[disabled]:hover,
.kt-btn--outline.is-disabled:hover,
.kt-btn--ghost[disabled]:hover,
.kt-btn--ghost.is-disabled:hover {
	background: transparent;
}

/*
 * Sale. Reserved for sale and urgency, one coral element per screen. The hover
 * step is the design system's literal #F0655A: coral-500 has no darker rung on
 * the palette.
 */
/* Label is --blue-900 for the same contrast reason as the sale badge. */
.kt-btn--sale {
	border-color: var(--coral-500);
	background: var(--coral-500);
	color: var(--blue-900);
	box-shadow: var(--shadow-sm);
}

.kt-btn--sale:hover {
	border-color: #F0655A;
	background: #F0655A;
	color: var(--blue-900);
}

.kt-btn--sale[disabled]:hover,
.kt-btn--sale.is-disabled:hover {
	border-color: var(--coral-500);
	background: var(--coral-500);
}

/* Sizes ------------------------------------------------------------------- */

.kt-btn--sm {
	block-size: 36px;
	padding-inline: var(--space-4);
	font-size: var(--fs-sm);
}

.kt-btn--lg {
	block-size: 54px;
	padding-inline: 34px;
	font-size: var(--fs-lg);
}

.kt-btn--block {
	display: flex;
	inline-size: 100%;
}

/* --------------------------------------------------------------------------
 * IconButton
 *
 * DS IconButton.jsx: 44px square by default (the minimum touch target), pill
 * radius, a 2.5px transparent border so it lines up with .kt-btn, and an
 * optional count badge pinned to the leading top corner in coral with a 2px
 * white ring.
 * -------------------------------------------------------------------------- */

.kt-icon-btn {
	position: relative;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	border: var(--border-w-thick) solid transparent;
	border-radius: var(--radius-pill);
	background: transparent;
	inline-size: var(--control-h);
	block-size: var(--control-h);
	padding: 0;
	color: var(--blue-800);
	cursor: pointer;
	transition: var(--t-hover);
}

.kt-icon-btn:hover {
	background: var(--blue-100);
	color: var(--blue-800);
}

.kt-icon-btn--soft {
	background: var(--cyan-100);
}

.kt-icon-btn--soft:hover {
	background: var(--cyan-200);
}

.kt-icon-btn--filled {
	border-color: var(--blue-700);
	background: var(--blue-700);
	color: var(--white);
}

.kt-icon-btn--filled:hover {
	border-color: var(--blue-800);
	background: var(--blue-800);
	color: var(--white);
}

.kt-icon-btn__badge {
	position: absolute;
	inset-block-start: 2px;
	inset-inline-start: 2px;
	display: flex;
	align-items: center;
	justify-content: center;
	border: 2px solid var(--white);
	border-radius: var(--radius-pill);
	background: var(--coral-500);
	min-inline-size: 19px;
	block-size: 19px;
	padding-inline: 5px;
	color: var(--white);
	font-family: var(--font-body);
	font-size: var(--fs-micro);
	font-weight: var(--fw-bold);
	line-height: 1;
}

/* Hidden rather than shown as a zero — an empty cart says nothing. */
.kt-icon-btn__badge:empty,
.kt-icon-btn__badge[data-count="0"] {
	display: none;
}

/* ===== src/20-card.css ===== */

/*
 * Card, Badge, Tag.
 *
 * DS Card.jsx: 20px radius, 24px padding, --shadow-sm at rest. Four tones.
 * Interactive cards rise 3px and go to --shadow-lg on hover.
 */

.kt-card {
	border: var(--border-w) solid var(--border-subtle);
	border-radius: var(--radius-lg);
	background: var(--surface-card);
	padding: var(--space-6);
	box-shadow: var(--shadow-sm);
	transition:
		transform var(--dur-base) var(--ease-out),
		box-shadow var(--dur-base) var(--ease-out);
}

.kt-card--soft {
	border-color: var(--cyan-200);
	background: var(--cyan-100);
}

.kt-card--brand {
	border-color: var(--blue-700);
	background: var(--blue-700);
	color: var(--white);
}

.kt-card--brand :is(h1, h2, h3, h4) {
	color: var(--white);
}

.kt-card--outline {
	border-width: var(--border-w-thick);
	border-color: var(--blue-700);
	background: transparent;
}

.kt-card--interactive {
	display: block;
	cursor: pointer;
	text-decoration: none;
}

.kt-card--interactive:hover,
.kt-card--interactive:focus-visible {
	transform: translateY(-3px);
	box-shadow: var(--shadow-lg);
}

/* --------------------------------------------------------------------------
 * Badge
 *
 * DS Badge.jsx: pill, --font-body at bold, 4px/12px padding (2px/8px small),
 * eight tones. `sale` is coral on white; `new` is mint on white.
 * -------------------------------------------------------------------------- */

.kt-badge {
	display: inline-flex;
	align-items: center;
	gap: var(--space-1);
	border-radius: var(--radius-pill);
	background: var(--blue-100);
	padding: 4px var(--space-3);
	color: var(--blue-800);
	font-family: var(--font-body);
	font-size: var(--fs-xs);
	font-weight: var(--fw-bold);
	line-height: 1.5;
}

.kt-badge--sm {
	padding: 2px var(--space-2);
	font-size: var(--fs-micro);
}

.kt-badge--accent {
	background: var(--cyan-200);
	color: var(--cyan-700);
}

/*
 * Badge labels are --blue-900, not white.
 *
 * Measured: white on --coral-500 is 2.55:1 and white on --mint-500 is 1.86:1,
 * both far below the 4.5:1 WCAG 2.0 AA wants — and IS 5568 adopts. The design
 * system draws both as white-on-fill. Keeping the fill and darkening the label
 * preserves the intent (coral still means sale, one per screen) and lands at
 * 5.24:1 and 7.18:1.
 */
.kt-badge--sale {
	background: var(--coral-500);
	color: var(--blue-900);
}

.kt-badge--new {
	background: var(--mint-500);
	color: var(--blue-900);
}

.kt-badge--sun {
	background: var(--sun-500);
	color: var(--blue-900);
}

.kt-badge--neutral {
	background: var(--ink-100);
	color: var(--ink-700);
}

.kt-badge--success {
	background: var(--success-soft);
	color: var(--success);
}

.kt-badge--danger {
	background: var(--danger-soft);
	color: var(--danger);
}

/* --------------------------------------------------------------------------
 * Tag
 *
 * DS Tag.jsx: 34px pill, hairline border, --font-body at --fs-sm. Selection is
 * a solid blue-700 fill with a matching border — the design system's "thick blue
 * ring", never a tick overlay.
 * -------------------------------------------------------------------------- */

.kt-tag {
	display: inline-flex;
	align-items: center;
	gap: var(--space-2);
	border: var(--border-w) solid var(--border-default);
	border-radius: var(--radius-pill);
	background: var(--white);
	block-size: 34px;
	padding-inline: 14px;
	color: var(--blue-800);
	font-family: var(--font-body);
	font-size: var(--fs-sm);
	text-decoration: none;
	transition: var(--t-hover);
}

/* Only interactive tags react to the pointer. */
a.kt-tag,
button.kt-tag {
	cursor: pointer;
}

a.kt-tag:hover,
button.kt-tag:hover {
	background: var(--blue-100);
	color: var(--blue-800);
}

.kt-tag.is-selected,
.kt-tag[aria-pressed="true"] {
	border-color: var(--blue-700);
	background: var(--blue-700);
	color: var(--white);
}

.kt-tag__remove {
	border: none;
	background: transparent;
	padding: 0;
	color: inherit;
	font-size: 15px;
	line-height: 1;
	opacity: 0.7;
	cursor: pointer;
}

.kt-tag__remove:hover {
	opacity: 1;
}

/* ===== src/30-typography.css ===== */

/*
 * Typographic helpers.
 *
 * The design system's base.css already sets h1-h4, p and a. These are the
 * repeating text patterns the screens need on top of that.
 */

/*
 * Hand-written accent. The design system caps this at six words and restricts
 * it to eyebrow lines and stickers — never body, never a UI label.
 */
/*
 * Eyebrow text uses --blue-600, not the design system's --cyan-700.
 *
 * Measured with axe: #2A93B5 on white is 3.53:1, and WCAG 2.0 AA — which IS 5568
 * adopts — wants 4.5:1 for text this size (21px normal is 15.8pt, so it is not
 * "large text" and the 3:1 allowance does not apply). --cyan-700 is already the
 * darkest cyan in the token set, so there is no compliant cyan; --blue-600 is the
 * nearest token that passes, at 6.4:1. Icons keep --cyan-700: as non-text content
 * they only need 3:1, which 3.53 clears.
 */
.kt-eyebrow {
	display: block;
	color: var(--blue-600);
	font-family: var(--font-hand);
	font-size: var(--fs-h3);
	line-height: var(--lh-snug);
}

.kt-section-head {
	display: flex;
	flex-wrap: wrap;
	align-items: baseline;
	justify-content: space-between;
	gap: var(--space-3);
	margin-block-end: var(--space-6);
}

.kt-section-title {
	margin: 0;
	font-family: var(--font-core);
	font-size: var(--fs-h2);
}

.kt-section-link {
	color: var(--text-link);
	font-family: var(--font-core);
	font-size: var(--fs-sm);
	white-space: nowrap;
}

.kt-lead {
	color: var(--text-body);
	font-size: var(--fs-lg);
	line-height: var(--lh-body);
}

.kt-muted {
	color: var(--text-muted);
}

/* Long-form content: About, policies, blog posts, the sizes page. */
.kt-prose {
	max-inline-size: 68ch;
	line-height: var(--lh-body);
}

.kt-prose > :first-child {
	margin-block-start: 0;
}

.kt-prose :is(h2, h3, h4) {
	margin-block: var(--space-8) var(--space-3);
}

.kt-prose ul,
.kt-prose ol {
	margin-block: 0 var(--space-4);
	padding-inline-start: var(--space-5);
}

.kt-prose li {
	margin-block-end: var(--space-2);
}

.kt-prose img {
	border-radius: var(--radius-md);
}

.kt-prose table {
	inline-size: 100%;
	border-collapse: collapse;
	font-size: var(--fs-sm);
}

.kt-prose :is(th, td) {
	border-block-end: var(--border-w) solid var(--border-subtle);
	padding: var(--space-3);
	text-align: start;
}

.kt-prose th {
	color: var(--text-heading);
	font-family: var(--font-core);
	font-weight: var(--fw-regular);
}

/* Wide content must scroll inside itself, never widen the page. */
.kt-scroll-x {
	overflow-x: auto;
}

/* ===== src/40-forms.css ===== */

/*
 * Input, Select, Checkbox, Radio, Switch, QuantityStepper.
 *
 * DS forms/*.jsx: a field is --field-h (46px) tall, 14px inline padding, a
 * hairline --border-default, --radius-md. Focus turns the border --blue-600 and
 * adds --ring-focus. Error turns it --danger. The label sits above at --fs-sm
 * medium; the hint or error message sits below at --fs-xs.
 */

.kt-field {
	display: flex;
	flex-direction: column;
	gap: var(--space-2);
	inline-size: 100%;
}

.kt-field__label {
	color: var(--text-heading);
	font-family: var(--font-body);
	font-size: var(--fs-sm);
	font-weight: var(--fw-medium);
}

/* The bordered box. Wraps the control so a prefix or suffix can sit inside it. */
.kt-field__control {
	display: flex;
	align-items: center;
	gap: var(--space-2);
	border: var(--border-w) solid var(--border-default);
	border-radius: var(--radius-md);
	background: var(--white);
	block-size: var(--field-h);
	padding-inline: 14px;
	transition: var(--t-hover);
}

.kt-field__control:focus-within {
	border-color: var(--blue-600);
	box-shadow: var(--ring-focus);
}

.kt-field__affix {
	display: flex;
	color: var(--ink-400);
}

.kt-field__hint {
	color: var(--text-muted);
	font-size: var(--fs-xs);
}

.kt-field.is-error .kt-field__control {
	border-color: var(--danger);
}

.kt-field.is-error .kt-field__hint {
	color: var(--danger);
}

/*
 * The control itself. Bare so it can be an <input> inside .kt-field__control,
 * and self-bordered when it stands alone — which is how WooCommerce emits most
 * of its fields.
 */
.kt-field__control > input,
.kt-field__control > textarea {
	flex: 1;
	border: none;
	outline: none;
	background: transparent;
	min-inline-size: 0;
	padding: 0;
	color: var(--text-body);
	font-family: var(--font-body);
	font-size: var(--fs-body);
}

.kt-input,
.kt-textarea,
.kt-select {
	display: block;
	border: var(--border-w) solid var(--border-default);
	border-radius: var(--radius-md);
	background: var(--white);
	inline-size: 100%;
	block-size: var(--field-h);
	padding-inline: 14px;
	color: var(--text-body);
	font-family: var(--font-body);
	font-size: var(--fs-body);
	transition: var(--t-hover);
}

.kt-textarea {
	block-size: auto;
	min-block-size: 120px;
	padding-block: var(--space-3);
	line-height: var(--lh-body);
	resize: vertical;
}

.kt-input:focus,
.kt-textarea:focus,
.kt-select:focus {
	outline: none;
	border-color: var(--blue-600);
	box-shadow: var(--ring-focus);
}

.kt-input::placeholder,
.kt-textarea::placeholder {
	color: var(--ink-400);
}

/*
 * Select. The design system draws the arrow as a bare U+25BC, which contradicts
 * its own rule that the Rating star and Checkbox tick are the only permitted
 * typographic marks — so the arrow comes from the icon sprite instead, at the
 * same stroke weight as every other glyph. It sits on the leading edge, which is
 * the left in RTL, matching the prototype's insetInlineStart.
 */
.kt-select-wrap {
	position: relative;
	display: block;
}

.kt-select {
	appearance: none;
	padding-inline-start: 40px;
	cursor: pointer;
}

.kt-select-wrap__arrow {
	position: absolute;
	inset-block-start: 50%;
	inset-inline-start: 14px;
	translate: 0 -50%;
	color: var(--ink-400);
	pointer-events: none;
}

/* --------------------------------------------------------------------------
 * Checkbox and Radio
 *
 * DS: the native control is visually hidden and a 22px box is drawn beside the
 * label. 2.5px border, blue-700 when checked. The checkbox tick is a typographic
 * mark by design; the radio uses a 10px dot.
 * -------------------------------------------------------------------------- */

.kt-check,
.kt-radio {
	display: flex;
	gap: var(--space-3);
	color: var(--text-body);
	font-family: var(--font-body);
	font-size: var(--fs-body);
	cursor: pointer;
}

.kt-check {
	align-items: center;
}

.kt-radio {
	align-items: flex-start;
}

.kt-check > input,
.kt-radio > input,
.kt-switch > input {
	position: absolute;
	opacity: 0;
	inline-size: 0;
	block-size: 0;
}

.kt-check__box,
.kt-radio__dot {
	display: flex;
	flex: 0 0 auto;
	align-items: center;
	justify-content: center;
	border: var(--border-w-thick) solid var(--border-default);
	background: var(--white);
	inline-size: 22px;
	block-size: 22px;
	transition: var(--t-hover);
}

.kt-check__box {
	border-radius: var(--radius-xs);
	color: var(--white);
	font-size: 13px;
	line-height: 1;
}

.kt-check__box::after {
	content: "";
}

.kt-check > input:checked ~ .kt-check__box {
	border-color: var(--blue-700);
	background: var(--blue-700);
}

.kt-check > input:checked ~ .kt-check__box::after {
	content: "✓";
}

.kt-radio__dot {
	border-radius: var(--radius-pill);
	margin-block-start: 2px;
}

.kt-radio__dot::after {
	content: "";
	border-radius: var(--radius-pill);
	background: transparent;
	inline-size: 10px;
	block-size: 10px;
	transition: var(--t-hover);
}

.kt-radio > input:checked ~ .kt-radio__dot {
	border-color: var(--blue-700);
}

.kt-radio > input:checked ~ .kt-radio__dot::after {
	background: var(--blue-700);
}

.kt-check > input:focus-visible ~ .kt-check__box,
.kt-radio > input:focus-visible ~ .kt-radio__dot,
.kt-switch > input:focus-visible ~ .kt-switch__track {
	box-shadow: var(--ring-focus);
}

.kt-check > input:disabled ~ *,
.kt-radio > input:disabled ~ * {
	opacity: 0.5;
}

.kt-check:has( > input:disabled ),
.kt-radio:has( > input:disabled ) {
	cursor: not-allowed;
}

.kt-radio__text {
	display: flex;
	flex-direction: column;
	gap: 2px;
}

.kt-radio__description {
	color: var(--text-muted);
	font-size: var(--fs-sm);
}

.kt-check__count {
	color: var(--text-muted);
	font-size: var(--fs-sm);
}

/* --------------------------------------------------------------------------
 * Switch
 *
 * DS Switch.jsx: 48x28 track, 22px knob, 3px inset. The knob is moved with
 * margin-inline-start rather than the prototype's hardcoded translateX(-20px),
 * which only reads correctly in RTL. --ease-bounce here is one of the two
 * deliberately playful moments in the system.
 * -------------------------------------------------------------------------- */

.kt-switch {
	display: inline-flex;
	align-items: center;
	gap: var(--space-3);
	color: var(--text-body);
	font-family: var(--font-body);
	font-size: var(--fs-body);
	cursor: pointer;
}

.kt-switch__track {
	display: flex;
	border-radius: var(--radius-pill);
	background: var(--ink-200);
	inline-size: 48px;
	block-size: 28px;
	padding: 3px;
	transition: background var(--dur-base) var(--ease-out);
}

.kt-switch__knob {
	border-radius: var(--radius-pill);
	background: var(--white);
	inline-size: 22px;
	block-size: 22px;
	box-shadow: var(--shadow-xs);
	transition: margin var(--dur-base) var(--ease-bounce);
}

.kt-switch > input:checked ~ .kt-switch__track {
	background: var(--blue-700);
}

.kt-switch > input:checked ~ .kt-switch__track .kt-switch__knob {
	margin-inline-start: auto;
}

.kt-switch > input:disabled ~ * {
	opacity: 0.5;
}

/* --------------------------------------------------------------------------
 * QuantityStepper
 *
 * DS QuantityStepper.jsx: 44px tall pill (36px small), hairline border, two
 * 44px buttons either side of the value. The prototype types "+" and "-" as
 * text; ours takes them from the sprite.
 * -------------------------------------------------------------------------- */

.kt-stepper {
	display: inline-flex;
	align-items: center;
	border: var(--border-w) solid var(--border-default);
	border-radius: var(--radius-pill);
	background: var(--white);
	block-size: var(--control-h);
}

.kt-stepper__btn {
	display: flex;
	align-items: center;
	justify-content: center;
	border: none;
	border-radius: var(--radius-pill);
	background: transparent;
	inline-size: var(--control-h);
	block-size: var(--control-h);
	padding: 0;
	color: var(--blue-800);
	cursor: pointer;
	transition: var(--t-hover);
}

.kt-stepper__btn:hover {
	background: var(--blue-100);
}

.kt-stepper__btn[disabled] {
	color: var(--ink-300);
	cursor: not-allowed;
}

.kt-stepper__btn[disabled]:hover {
	background: transparent;
}

.kt-stepper__value {
	border: none;
	background: transparent;
	min-inline-size: 32px;
	padding: 0;
	color: var(--text-heading);
	font-family: var(--font-body);
	font-weight: var(--fw-medium);
	text-align: center;
	-moz-appearance: textfield;
	appearance: textfield;
}

.kt-stepper__value::-webkit-outer-spin-button,
.kt-stepper__value::-webkit-inner-spin-button {
	margin: 0;
	appearance: none;
}

.kt-stepper--sm {
	block-size: 36px;
}

.kt-stepper--sm .kt-stepper__btn {
	inline-size: 36px;
	block-size: 36px;
}

/* ===== src/50-commerce.css ===== */

/*
 * Price, Rating, ColorSwatch, SizePicker, ProductCard, PromoBanner.
 */

/*
 * DS Price.jsx: --font-core, baseline-aligned, sale price in --sale with the
 * old price struck through in ink-400. Sizes lg/md/sm map to --fs-h2 /
 * --fs-lg / --fs-sm. Formatting (shekel sign before the number, he-IL grouping,
 * no trailing .00) is wc_price()'s job, not CSS.
 */
.kt-price {
	display: inline-flex;
	align-items: baseline;
	gap: var(--space-2);
	font-family: var(--font-core);
}

.kt-price__now {
	color: var(--text-heading);
	font-size: var(--fs-lg);
}

/* --ink-400 is 3.01:1 on white, below AA for text this size; --text-muted is 5.66:1. */
.kt-price__was {
	color: var(--text-muted);
	font-size: var(--fs-sm);
	text-decoration: line-through;
	text-decoration-color: var(--ink-300);
}

.kt-price--lg .kt-price__now {
	font-size: var(--fs-h2);
}

.kt-price--lg .kt-price__was {
	font-size: var(--fs-lg);
}

.kt-price--sm .kt-price__now {
	font-size: var(--fs-sm);
}

/*
 * The sale price is only coloured where it is large enough to carry it.
 *
 * --sale (#FF7A6B) is 2.55:1 on white: it fails AA at every size, and no red in
 * the token set reaches 4.5:1 (--danger is 4.18:1). So the small card price
 * stays --text-heading and the sale is signalled the way WCAG 1.4.1 asks for
 * anyway — by the struck-through original beside it and the SALE badge on the
 * card — while the single-product price, at --fs-h2 (27px, large text), can use
 * --danger, which clears the 3:1 large-text threshold at 4.18:1.
 */
.kt-price--lg.is-on-sale .kt-price__now {
	color: var(--danger);
}

/*
 * DS Rating.jsx. The star is one of the two typographic marks the system
 * permits. Stars run LTR so a partial rating fills from the same end regardless
 * of page direction.
 */
.kt-rating {
	display: inline-flex;
	align-items: center;
	gap: var(--space-2);
}

.kt-rating__stars {
	display: inline-flex;
	gap: 2px;
	direction: ltr;
	color: var(--ink-200);
	font-size: 16px;
	line-height: 1;
}

.kt-rating__star.is-filled {
	color: var(--sun-500);
}

.kt-rating__count {
	color: var(--text-muted);
	font-family: var(--font-body);
	font-size: var(--fs-xs);
}

/*
 * DS ColorSwatch.jsx: 30px button, 3px padding, 2.5px transparent border that
 * turns blue-700 when selected — the ring is outside the colour, so the colour
 * is never obscured. The inset hairline keeps white and pale swatches visible.
 */
.kt-swatch {
	border: var(--border-w-thick) solid transparent;
	border-radius: var(--radius-pill);
	background: transparent;
	inline-size: 30px;
	block-size: 30px;
	padding: 3px;
	cursor: pointer;
	transition: var(--t-hover);
}

.kt-swatch__dot {
	display: block;
	border-radius: var(--radius-pill);
	inline-size: 100%;
	block-size: 100%;
	background: var(--kt-swatch-color, var(--ink-200));
	box-shadow: inset 0 0 0 1px rgba(15, 26, 51, 0.12);
}

.kt-swatch.is-selected,
.kt-swatch[aria-pressed="true"] {
	border-color: var(--blue-700);
}

.kt-swatch--sm {
	inline-size: 22px;
	block-size: 22px;
	padding: 2px;
}

/*
 * DS SizePicker.jsx: 52x44 minimum, --radius-md, hairline border. Selected is a
 * blue-700 fill. Out of stock is struck through and greyed but still rendered —
 * the design system's honesty rule: never hide a size, show that it is gone.
 */
.kt-sizes {
	display: flex;
	flex-wrap: wrap;
	gap: var(--space-2);
}

.kt-size {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	border: var(--border-w) solid var(--border-default);
	border-radius: var(--radius-md);
	background: var(--white);
	min-inline-size: 52px;
	block-size: var(--control-h);
	padding-inline: var(--space-3);
	color: var(--text-heading);
	font-family: var(--font-body);
	font-size: var(--fs-sm);
	cursor: pointer;
	transition: var(--t-hover);
}

.kt-size:hover {
	border-color: var(--blue-700);
}

.kt-size.is-selected,
.kt-size[aria-pressed="true"] {
	border-color: var(--blue-700);
	background: var(--blue-700);
	color: var(--white);
}

.kt-size[disabled],
.kt-size.is-out-of-stock {
	border-color: var(--border-subtle);
	color: var(--ink-300);
	text-decoration: line-through;
	cursor: not-allowed;
}

.kt-size[disabled]:hover,
.kt-size.is-out-of-stock:hover {
	border-color: var(--border-subtle);
}

/* --------------------------------------------------------------------------
 * ProductCard
 *
 * DS ProductCard.jsx: 4:5 media in a --radius-lg frame on cyan-100, shadow-xs
 * at rest. The whole card lifts 4px and the media goes to --shadow-md on hover.
 * Badge pinned to the trailing top corner, wishlist to the leading top corner
 * in a 90%-white capsule — the one place the system allows transparency.
 * Where there is no photograph the frame says so rather than showing a stand-in.
 * -------------------------------------------------------------------------- */

.kt-product {
	display: flex;
	flex-direction: column;
	gap: var(--space-3);
	transition: transform var(--dur-base) var(--ease-out);
}

.kt-product:hover,
.kt-product:focus-within {
	transform: translateY(-4px);
}

.kt-product__media {
	position: relative;
	border-radius: var(--radius-lg);
	overflow: hidden;
	background: var(--cyan-100);
	aspect-ratio: 4 / 5;
	box-shadow: var(--shadow-xs);
	transition: box-shadow var(--dur-base) var(--ease-out);
}

.kt-product:hover .kt-product__media,
.kt-product:focus-within .kt-product__media {
	box-shadow: var(--shadow-md);
}

.kt-product__link {
	display: block;
	block-size: 100%;
}

.kt-product__media img {
	display: block;
	inline-size: 100%;
	block-size: 100%;
	object-fit: cover;
}

/*
 * Quick add.
 *
 * Revealed on hover and on keyboard focus. On a coarse pointer there is no hover
 * to reveal it with, so it is simply always there — a control that only appears
 * on hover is a control a touch user never gets.
 */
.kt-product__quickadd {
	position: absolute;
	inset-inline: var(--space-3);
	inset-block-end: var(--space-3);
	display: flex;
	justify-content: center;
}

/*
 * Hidden-until-hover only where there is both a desktop layout and a real hover.
 * Keyed to the breakpoint as well as the pointer because `hover` and `pointer`
 * are not reported reliably everywhere — a device that claims `hover: hover`
 * would otherwise hide the control from someone who can never trigger it. Below
 * 820px the button is simply always there.
 */
@media (min-width: 820px) and (hover: hover) {

	.kt-product__quickadd {
		opacity: 0;
		transform: translateY(6px);
		transition:
			opacity var(--dur-base) var(--ease-out),
			transform var(--dur-base) var(--ease-out);
	}

	.kt-product:hover .kt-product__quickadd,
	.kt-product:focus-within .kt-product__quickadd {
		opacity: 1;
		transform: none;
	}
}

/*
 * The card's own pill, not the generic Woo button. `.woocommerce a.button` in
 * 82-cart.css is one element more specific than a two-class selector, so the
 * card class is named as well — otherwise the generic 16px/--control-h button
 * wins here and "בחר אפשרויות" arrives oversized and unpadded.
 */
.kt-product .kt-product__quickadd .button {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: var(--space-2);
	border: var(--border-w-thick) solid var(--blue-700);
	border-radius: var(--radius-pill);
	background: var(--blue-700);
	inline-size: 100%;
	block-size: 40px;
	padding-inline: var(--space-4);
	color: var(--white);
	font-family: var(--font-core);
	font-size: var(--fs-sm);
	line-height: 1;
	white-space: nowrap;
	text-align: center;
	text-decoration: none;
	cursor: pointer;
	box-shadow: var(--shadow-brand);
	transition: var(--t-hover);
}

.kt-product .kt-product__quickadd .button:hover {
	border-color: var(--blue-800);
	background: var(--blue-800);
	color: var(--white);
}

/* WooCommerce marks a button mid-request and then done. */
.kt-product .kt-product__quickadd .button.loading {
	opacity: 0.7;
	cursor: progress;
}

.kt-product .kt-product__quickadd .button.added {
	border-color: var(--success);
	background: var(--success);
}

/* Woo appends its own "view cart" link; the toast already offers that. */
.kt-product__quickadd .added_to_cart {
	display: none;
}

/* A colour dot that swaps the photograph is a control, and reads as one. */
.kt-product__colors button.kt-swatch {
	cursor: pointer;
}

.kt-product__colors button.kt-swatch:hover {
	border-color: var(--blue-300);
}

.kt-product__media img.is-swapping {
	opacity: 0.35;
	transition: opacity var(--dur-fast) var(--ease-out);
}

/* Honest placeholder, not a stock stand-in. */
.kt-product__placeholder {
	position: absolute;
	inset: 0;
	display: flex;
	align-items: center;
	justify-content: center;
	color: var(--cyan-500);
	font-family: var(--font-body);
	font-size: var(--fs-xs);
}

.kt-product__badge {
	position: absolute;
	inset-block-start: var(--space-3);
	inset-inline-end: var(--space-3);
}

.kt-product__wishlist {
	position: absolute;
	inset-block-start: 10px;
	inset-inline-start: 10px;
	display: flex;
	align-items: center;
	justify-content: center;
	border: none;
	border-radius: var(--radius-pill);
	background: rgba(255, 255, 255, 0.9);
	inline-size: 36px;
	block-size: 36px;
	padding: 0;
	color: var(--ink-400);
	font-size: 16px;
	line-height: 1;
	cursor: pointer;
	box-shadow: var(--shadow-xs);
}

.kt-product__wishlist.is-active {
	color: var(--coral-500);
}

.kt-product__body {
	display: flex;
	flex-direction: column;
	gap: var(--space-1);
}

.kt-product__category {
	color: var(--text-muted);
	font-family: var(--font-body);
	font-size: var(--fs-xs);
}

.kt-product__title {
	margin: 0;
	color: var(--text-heading);
	font-family: var(--font-core);
	font-size: var(--fs-lg);
	font-weight: var(--fw-regular);
	line-height: var(--lh-snug);
}

.kt-product__title a {
	color: inherit;
	text-decoration: none;
}

.kt-product__colors {
	display: flex;
	gap: 4px;
	margin-block-start: var(--space-1);
}

/*
 * Product grid. The design system specifies repeat(auto-fill, minmax(230px,1fr))
 * at 24px on desktop, and 2-up at 12px on mobile — never 1-up, because parents
 * scan by silhouette.
 */
.kt-product-grid {
	display: grid;
	grid-template-columns: repeat(2, minmax(0, 1fr));
	gap: var(--space-3);
}

@media (min-width: 820px) {

	.kt-product-grid {
		grid-template-columns: repeat(auto-fill, minmax(230px, 1fr));
		gap: var(--gutter);
	}
}

/* --------------------------------------------------------------------------
 * PromoBanner
 *
 * DS PromoBanner.jsx. `strip` is the announcement bar: full bleed, square,
 * blue-900, 10px/24px, --fs-sm, one line that grows if it needs to.
 * -------------------------------------------------------------------------- */

.kt-promo {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: center;
	gap: var(--space-4);
	border-radius: var(--radius-xl);
	background: var(--blue-700);
	padding: var(--space-8) var(--space-10);
	color: var(--white);
	font-family: var(--font-body);
	font-size: var(--fs-body);
	text-align: center;
}

.kt-promo__title {
	font-family: var(--font-core);
	font-size: var(--fs-h3);
}

.kt-promo__text {
	opacity: 0.9;
}

.kt-promo--accent {
	background: var(--cyan-200);
	color: var(--blue-900);
}

.kt-promo--sun {
	background: var(--sun-300);
	color: var(--blue-900);
}

.kt-promo--strip {
	border-radius: 0;
	background: var(--blue-900);
	padding: 10px var(--gutter);
	font-size: var(--fs-sm);
}

.kt-promo--strip .kt-promo__title {
	font-size: var(--fs-sm);
}

.kt-promo--strip a {
	color: var(--cyan-300);
}

/* ===== src/60-merchandising.css ===== */

/*
 * CategoryCircle, BannerCard, EditorialTile, MarqueeHero.
 */

/*
 * DS CategoryCircle.jsx: 132px circle on a tint, shadow-xs at rest. On hover it
 * lifts 3px, takes --shadow-md and a 2.5px blue-700 ring. Mobile shrinks it to
 * 92px and the rail scrolls horizontally.
 */
.kt-circle {
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: var(--space-3);
	border: none;
	background: transparent;
	padding: 0;
	text-decoration: none;
	cursor: pointer;
}

.kt-circle__media {
	display: flex;
	align-items: center;
	justify-content: center;
	border: var(--border-w-thick) solid transparent;
	border-radius: var(--radius-pill);
	overflow: hidden;
	background: var(--kt-circle-tint, var(--cyan-100));
	inline-size: 92px;
	block-size: 92px;
	box-shadow: var(--shadow-xs);
	transition:
		transform var(--dur-base) var(--ease-out),
		box-shadow var(--dur-base) var(--ease-out),
		border-color var(--dur-fast) var(--ease-out);
}

@media (min-width: 820px) {

	.kt-circle__media {
		inline-size: 132px;
		block-size: 132px;
	}
}

.kt-circle__media img {
	inline-size: 100%;
	block-size: 100%;
	object-fit: cover;
}

.kt-circle:hover .kt-circle__media,
.kt-circle:focus-visible .kt-circle__media {
	transform: translateY(-3px);
	border-color: var(--blue-700);
	box-shadow: var(--shadow-md);
}

.kt-circle__label {
	color: var(--text-heading);
	font-family: var(--font-core);
	font-size: var(--fs-sm);
}

/* The rail. Scrolls horizontally on mobile, centres on desktop. */
.kt-circle-rail {
	display: flex;
	gap: var(--space-4);
	overflow-x: auto;
	scrollbar-width: none;
	scroll-snap-type: x proximity;
	padding-block-end: var(--space-2);
}

.kt-circle-rail::-webkit-scrollbar {
	display: none;
}

.kt-circle-rail > * {
	flex: 0 0 auto;
	scroll-snap-align: start;
}

@media (min-width: 820px) {

	.kt-circle-rail {
		justify-content: center;
		gap: var(--space-6);
		overflow-x: visible;
	}
}

/* --------------------------------------------------------------------------
 * BannerCard
 *
 * DS BannerCard.jsx: 420px tall (300px on mobile per the mobile rules), full
 * bleed photograph, --radius-lg. Text is display face over a hand-font eyebrow;
 * the pill CTAs are pinned to the bottom in a 94%-white capsule.
 *
 * The last round of feedback moved SALE and events banners to a two-column
 * layout — image at its full ratio, text in its own column — so the overlay
 * variant and the split variant both live here.
 * -------------------------------------------------------------------------- */

.kt-banner {
	position: relative;
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	border-radius: var(--radius-lg);
	overflow: hidden;
	background: var(--kt-banner-tint, var(--cyan-100));
	block-size: 300px;
	padding: var(--space-6);
	text-align: center;
}

@media (min-width: 820px) {

	.kt-banner {
		block-size: 420px;
		padding: var(--space-10);
	}
}

.kt-banner__media {
	position: absolute;
	inset: 0;
	inline-size: 100%;
	block-size: 100%;
	object-fit: cover;
}

.kt-banner__body {
	position: relative;
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: var(--space-2);
	color: var(--kt-banner-fg, var(--blue-900));
}

.kt-banner__eyebrow {
	font-family: var(--font-hand);
	font-size: 26px;
}

.kt-banner__title {
	margin: 0;
	color: inherit;
	font-family: var(--font-display);
	font-size: var(--fs-h1);
	line-height: var(--lh-tight);
}

@media (min-width: 820px) {

	.kt-banner__title {
		font-size: var(--fs-display-2);
	}
}

.kt-banner__subtitle {
	font-family: var(--font-core);
	font-size: var(--fs-h3);
}

.kt-banner__note {
	font-family: var(--font-body);
	font-size: var(--fs-sm);
	opacity: 0.8;
}

.kt-banner__actions {
	position: absolute;
	inset-block-end: var(--space-6);
	display: flex;
	gap: var(--space-3);
}

.kt-banner__cta {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	border: none;
	border-radius: var(--radius-pill);
	background: rgba(255, 255, 255, 0.94);
	min-inline-size: 118px;
	block-size: 42px;
	padding-inline: 22px;
	color: var(--blue-800);
	font-family: var(--font-core);
	font-size: var(--fs-body);
	text-decoration: none;
	cursor: pointer;
	box-shadow: var(--shadow-sm);
	transition: var(--t-hover);
}

.kt-banner__cta:hover {
	background: var(--white);
	color: var(--blue-900);
}

/*
 * Split variant. The image keeps its own ratio in one column and the text sits
 * in the other, so nothing is cropped and no text sits on a busy photograph.
 */
.kt-banner--split {
	display: grid;
	grid-template-columns: 1fr;
	block-size: auto;
	padding: 0;
	text-align: start;
}

@media (min-width: 820px) {

	.kt-banner--split {
		grid-template-columns: 1fr 1fr;
		align-items: stretch;
	}
}

.kt-banner--split .kt-banner__media {
	position: static;
	block-size: 100%;
	aspect-ratio: 4 / 3;
}

.kt-banner--split .kt-banner__body {
	align-items: flex-start;
	gap: var(--space-3);
	padding: var(--space-6);
}

@media (min-width: 820px) {

	.kt-banner--split .kt-banner__body {
		justify-content: center;
		padding: var(--space-10);
	}
}

.kt-banner--split .kt-banner__actions {
	position: static;
	margin-block-start: var(--space-2);
}

/* --------------------------------------------------------------------------
 * EditorialTile
 *
 * DS EditorialTile.jsx: 3/4 portrait, caption in a 94%-white capsule inset 16px
 * from the bottom. The photograph scales 1.03 on hover; the capsule does not
 * move, because the text must stay put while the image breathes.
 * -------------------------------------------------------------------------- */

.kt-tile {
	position: relative;
	display: block;
	border-radius: var(--radius-lg);
	overflow: hidden;
	background: var(--kt-tile-tint, var(--cyan-100));
	aspect-ratio: 3 / 4;
	text-decoration: none;
	box-shadow: var(--shadow-xs);
	transition: box-shadow var(--dur-base) var(--ease-out);
}

.kt-tile:hover,
.kt-tile:focus-visible {
	box-shadow: var(--shadow-md);
}

.kt-tile img {
	inline-size: 100%;
	block-size: 100%;
	object-fit: cover;
	transition: transform var(--dur-slow) var(--ease-out);
}

.kt-tile:hover img,
.kt-tile:focus-visible img {
	transform: scale(1.03);
}

.kt-tile__placeholder {
	position: absolute;
	inset: 0;
	display: flex;
	align-items: center;
	justify-content: center;
	color: var(--cyan-600);
	font-size: var(--fs-xs);
}

.kt-tile__caption {
	position: absolute;
	inset-inline: var(--space-4);
	inset-block-end: var(--space-4);
	display: flex;
	flex-direction: column;
	gap: 2px;
	border-radius: var(--radius-md);
	background: rgba(255, 255, 255, 0.94);
	padding: var(--space-3) var(--space-4);
	box-shadow: var(--shadow-xs);
}

.kt-tile__label {
	color: var(--text-heading);
	font-family: var(--font-core);
	font-size: var(--fs-lg);
}

.kt-tile__cta {
	color: var(--text-link);
	font-family: var(--font-body);
	font-size: var(--fs-xs);
	letter-spacing: var(--ls-wide);
}

.kt-tile-grid {
	display: grid;
	grid-template-columns: repeat(2, minmax(0, 1fr));
	gap: var(--space-3);
}

@media (min-width: 820px) {

	.kt-tile-grid {
		grid-template-columns: repeat(4, minmax(0, 1fr));
		gap: var(--gutter);
	}
}

/* --------------------------------------------------------------------------
 * MarqueeHero
 *
 * DS MarqueeHero.jsx: 560px tall, full-bleed photograph, an oversized display
 * word band scrolling across the lower third, and the headline in a white
 * capsule beside the image rather than typed over it. 420px on mobile, where
 * the capsule goes full width with 16px side margins.
 *
 * The marquee runs LTR so the words travel the same way at any page direction,
 * and it stops entirely under prefers-reduced-motion (see 00-base.css).
 * -------------------------------------------------------------------------- */

.kt-hero {
	position: relative;
	overflow: hidden;
	background: var(--kt-hero-tint, var(--cyan-100));
	block-size: 420px;
}

@media (min-width: 820px) {

	.kt-hero {
		block-size: 560px;
	}
}

.kt-hero__media {
	position: absolute;
	inset: 0;
	inline-size: 100%;
	block-size: 100%;
	object-fit: cover;
}

.kt-hero__marquee {
	position: absolute;
	inset-inline: 0;
	inset-block-end: 12%;
	overflow: hidden;
	direction: ltr;
}

/*
 * The marquee is the page's only continuous animation, and it was making the
 * whole home page stutter under scroll.
 *
 * It moves a 200%-wide row of Suez One words that each carry a text-shadow.
 * Without a compositing hint the browser repaints that text every frame, on the
 * main thread, competing with scrolling. translateZ(0) plus will-change promotes
 * the track to its own layer so the animation is a GPU transform and touches no
 * paint at all, and `contain: paint` on the hero stops any of it invalidating the
 * rest of the page.
 *
 * app.js additionally pauses it whenever the hero is off screen, so scrolling the
 * rest of the page costs nothing. `will-change` is only worth having while the
 * thing actually animates, which is why it is paired with the running state.
 */
.kt-hero {
	contain: paint;
}

.kt-hero__track {
	display: flex;
	inline-size: 200%;
	transform: translateZ(0);
	backface-visibility: hidden;
	animation: kt-marquee var(--kt-marquee-speed, 26s) linear infinite;
}

.kt-hero__track:not(.is-paused) {
	will-change: transform;
}

.kt-hero__track.is-paused {
	animation-play-state: paused;
}

.kt-hero__word {
	padding-inline: var(--space-6);
	color: var(--white);
	font-family: var(--font-display);
	font-size: 26px;
	line-height: 1;
	white-space: nowrap;
	text-shadow: 0 2px 18px rgba(15, 26, 51, 0.25);
}

@media (min-width: 820px) {

	.kt-hero__word {
		font-size: 44px;
	}
}

@keyframes kt-marquee {

	from {
		transform: translate3d(0, 0, 0);
	}

	to {
		transform: translate3d(-50%, 0, 0);
	}
}

/*
 * The headline capsule. A solid shape beside the photograph, never a scrim
 * gradient over it — the design system's "protection" rule.
 */
.kt-hero__capsule {
	position: absolute;
	inset-inline: var(--space-4);
	inset-block-end: var(--space-6);
	border-radius: var(--radius-lg);
	background: var(--white);
	padding: var(--space-6);
	box-shadow: var(--shadow-md);
}

@media (min-width: 820px) {

	.kt-hero__capsule {
		inset-inline-start: var(--space-12);
		inset-inline-end: auto;
		inset-block: 50% auto;
		translate: 0 -50%;
		border-radius: var(--radius-xl);
		max-inline-size: 420px;
		padding: var(--space-10);
	}
}

/* See the contrast note in src/30-typography.css. */
.kt-hero__eyebrow {
	display: block;
	margin-block-end: var(--space-2);
	color: var(--blue-600);
	font-family: var(--font-hand);
	font-size: var(--fs-h3);
}

.kt-hero__title {
	margin: 0 0 var(--space-3);
	font-family: var(--font-display);
	font-size: var(--fs-h1);
	line-height: var(--lh-tight);
}

@media (min-width: 820px) {

	.kt-hero__title {
		font-size: var(--fs-display-2);
	}
}

.kt-hero__sub {
	margin: 0 0 var(--space-5);
	color: var(--text-body);
	font-size: var(--fs-body);
}

/* ===== src/70-navigation.css ===== */

/*
 * Breadcrumb, Tabs, Pagination.
 *
 * NavBar and NavDrawer are Phase 3 and live in their own part.
 */

.kt-breadcrumb {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: var(--space-2);
	color: var(--text-muted);
	font-family: var(--font-body);
	font-size: var(--fs-sm);
}

.kt-breadcrumb a {
	color: var(--text-link);
}

.kt-breadcrumb__sep {
	color: var(--ink-300);
}

.kt-breadcrumb__current {
	color: var(--text-heading);
}

/*
 * DS Tabs.jsx: 12px/18px cells in --font-core, the active one marked by an
 * inset 3px cyan-500 underline rather than a border swap, so nothing shifts
 * when the selection moves.
 */
.kt-tabs {
	display: flex;
	gap: var(--space-2);
	border-block-end: var(--border-w) solid var(--border-subtle);
	overflow-x: auto;
	scrollbar-width: none;
}

.kt-tabs::-webkit-scrollbar {
	display: none;
}

.kt-tab {
	flex: 0 0 auto;
	border: none;
	background: transparent;
	padding: var(--space-3) 18px;
	color: var(--text-muted);
	font-family: var(--font-core);
	font-size: var(--fs-body);
	text-decoration: none;
	cursor: pointer;
	transition: var(--t-hover);
}

.kt-tab:hover {
	color: var(--blue-700);
}

.kt-tab.is-active,
.kt-tab[aria-selected="true"] {
	box-shadow: inset 0 -3px 0 var(--cyan-500);
	color: var(--blue-800);
}

/*
 * DS Pagination.jsx: 40px pill cells, hairline border, the current page filled
 * blue-700. The prototype types the arrows as guillemets; ours come from the
 * sprite and mirror with direction.
 */
.kt-pagination {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: var(--space-2);
}

.kt-pagination .page-numbers {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	border: var(--border-w) solid var(--border-subtle);
	border-radius: var(--radius-pill);
	background: transparent;
	min-inline-size: 40px;
	block-size: 40px;
	padding-inline: var(--space-3);
	color: var(--text-body);
	font-family: var(--font-body);
	font-size: var(--fs-sm);
	text-decoration: none;
	cursor: pointer;
	transition: var(--t-hover);
}

.kt-pagination .page-numbers:hover {
	border-color: var(--blue-700);
	color: var(--blue-700);
}

.kt-pagination .page-numbers.current {
	border-color: var(--blue-700);
	background: var(--blue-700);
	color: var(--white);
}

.kt-pagination .page-numbers.dots {
	border-color: transparent;
	color: var(--ink-300);
	cursor: default;
}

.kt-pagination .page-numbers[disabled],
.kt-pagination .page-numbers.is-disabled {
	color: var(--ink-300);
	cursor: not-allowed;
}

/* ===== src/72-header.css ===== */

/*
 * Announcement strip, header and mobile drawer.
 *
 * The prototype draws two separate headers behind an isDesktop/isMobile switch.
 * A real site cannot detect the breakpoint before paint, so this is one DOM with
 * the two layouts selected by media query.
 *
 *   desktop at rest   170px lockup centred over a 64px nav row; icons at 24px
 *   desktop scrolled  lockup 68px pinned to the leading edge, row 76px, icons 16px
 *   mobile            64px bar: burger, 58px lockup, search + cart
 *
 * .is-scrolled is set by app.js from an IntersectionObserver sentinel — a class
 * toggle only, no layout arithmetic in JS.
 */

.kt-announcement {
	min-block-size: 42px;
	padding-block: 10px;
}

/*
 * The Alpine x-data wrapper must not generate a box. A sticky element can only
 * travel within its parent's box, so wrapping the header in a plain div pins it
 * to the wrapper's own height — which is the header's height — and it scrolls
 * away like a static element. display:contents removes the box while keeping the
 * element in the DOM for Alpine.
 */
.kt-header-area {
	display: contents;
}

/*
 * Only the row is sticky. The header itself is not.
 *
 * It used to be, and collapsing it on scroll was the cause of the home page's
 * scroll glitch: a sticky element is still in normal flow, so dropping the 170px
 * lockup took the header from 255px to 65px and the whole document from 5439px
 * to 5249px. Everything below lurched up 190px in one frame — measured, the hero
 * moved -142px where it should have moved -8px — and then kept shifting for
 * another 200ms while the row's height transition ran.
 *
 * Now nothing changes height at all. The lockup band is ordinary content and
 * scrolls away by itself; the row beneath it sticks to the top when it gets
 * there. .is-scrolled only fades the compact lockup in and deepens the shadow,
 * neither of which touches layout.
 */
/*
 * <header> generates no box either, for the same reason the Alpine wrapper does
 * not: a sticky child can only travel within its parent's box. With <header> as
 * a normal element the row could move 190px — the header's own height minus its
 * own — and then scrolled away. Measured: rowTop reached -968px. Both the brand
 * band and the row carry their own background, so nothing is lost by removing
 * this box, and the banner landmark survives (verified with axe and by querying
 * the accessibility tree).
 */
.kt-header {
	display: contents;
}

.kt-header__row {
	position: sticky;
	inset-block-start: 0;
	z-index: 60;
	border-block-end: var(--border-w) solid var(--cyan-200);
	background: var(--white);
	box-shadow: var(--shadow-xs);
	transition: box-shadow var(--dur-base) var(--ease-out);
}

.kt-header__row.is-stuck,
.kt-header.is-scrolled .kt-header__row {
	box-shadow: var(--shadow-sm);
}

/* The scroll sentinel. Sits above the header and never moves. */
.kt-header-sentinel {
	display: block;
	block-size: 1px;
	margin-block-end: -1px;
}

.kt-header__brand {
	display: none;
}

.kt-header__logo {
	display: block;
	inline-size: auto;
}

.kt-logo-link {
	display: block;
	text-decoration: none;
}

/* --- Mobile: a 64px bar, always -------------------------------------------- */

.kt-header__row {
	display: grid;
	grid-template-columns: auto 1fr auto;
	align-items: center;
	block-size: 64px;
	padding-inline: var(--space-2);
}

.kt-header__logo-link--compact {
	display: flex;
	justify-content: center;
}

.kt-header__logo--compact {
	block-size: 58px;
}

.kt-header__logo--full {
	block-size: 170px;
}

.kt-header__actions {
	display: flex;
	justify-self: end;
}

.kt-nav,
.kt-header__account {
	display: none;
}

/* --- Desktop --------------------------------------------------------------- */

@media (min-width: 820px) {

	.kt-header__burger {
		display: none;
	}

	.kt-header__brand {
		display: flex;
		justify-content: center;
		padding: var(--space-5) var(--gutter) 0;
	}

	/*
	 * A single fixed height in both states. The prototype grows the row from 64px
	 * to 76px on scroll; 12px is not worth reflowing the document for, and the
	 * row has to be 76px anyway to hold the 68px compact lockup.
	 */
	.kt-header__row {
		position: sticky;
		display: grid;
		grid-template-columns: 1fr auto 1fr;
		align-items: center;
		block-size: 76px;
		padding-inline: var(--gutter);
	}

	.kt-header__logo-link--compact {
		justify-self: start;
		/*
		 * Present in both states so the row's grid never changes shape; only its
		 * opacity does, which the compositor handles without touching layout.
		 */
		display: block;
		opacity: 0;
		visibility: hidden;
		transition:
			opacity var(--dur-base) var(--ease-out),
			visibility var(--dur-base);
	}

	.kt-header__logo--compact {
		block-size: 68px;
	}

	.kt-header.is-scrolled .kt-header__logo-link--compact {
		opacity: 1;
		visibility: visible;
	}

	.kt-nav {
		display: block;
		justify-self: center;
	}

	.kt-header__account {
		display: inline-flex;
	}

	.kt-header__actions {
		justify-self: end;
		gap: var(--space-1);
	}
}

/* --------------------------------------------------------------------------
 * Category strip
 * -------------------------------------------------------------------------- */

.kt-nav__list,
.kt-nav__sub {
	margin: 0;
	list-style: none;
	padding: 0;
}

.kt-nav__list {
	display: flex;
	align-items: center;
	gap: var(--space-1);
}

.kt-nav__item {
	position: relative;
}

.kt-nav__link {
	display: flex;
	align-items: center;
	border-radius: var(--radius-pill);
	padding: var(--space-2) var(--space-4);
	color: var(--blue-800);
	font-family: var(--font-core);
	font-size: var(--fs-body);
	white-space: nowrap;
	text-decoration: none;
	transition: var(--t-hover);
}

.kt-nav__link:hover {
	background: var(--cyan-100);
	color: var(--blue-800);
}

.kt-nav__item.is-current > .kt-nav__link {
	background: var(--blue-700);
	color: var(--white);
}

/*
 * Second level as a hover panel. :focus-within carries the same behaviour for
 * keyboard users, so no JS and no aria-expanded to keep in sync.
 */
@media (min-width: 820px) {

	.kt-nav__sub {
		position: absolute;
		inset-block-start: calc(100% + var(--space-2));
		inset-inline-start: 0;
		z-index: 70;
		display: flex;
		visibility: hidden;
		flex-direction: column;
		gap: 2px;
		border: var(--border-w) solid var(--cyan-200);
		border-radius: var(--radius-lg);
		background: var(--white);
		min-inline-size: 216px;
		padding: var(--space-3);
		box-shadow: var(--shadow-md);
		opacity: 0;
		transform: translateY(-4px);
		transition:
			opacity var(--dur-fast) var(--ease-out),
			transform var(--dur-fast) var(--ease-out),
			visibility var(--dur-fast);
	}

	.kt-nav__item:hover > .kt-nav__sub,
	.kt-nav__item:focus-within > .kt-nav__sub {
		visibility: visible;
		opacity: 1;
		transform: translateY(0);
	}
}

.kt-nav__sublink {
	display: block;
	border-radius: var(--radius-md);
	padding: 9px var(--space-3);
	color: var(--text-body);
	font-family: var(--font-core);
	font-size: var(--fs-sm);
	white-space: nowrap;
	text-decoration: none;
	transition: var(--t-hover);
}

.kt-nav__sublink:hover {
	background: var(--cyan-100);
	color: var(--blue-800);
}

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

.kt-header__search {
	border-block-start: var(--border-w) solid var(--cyan-200);
	background: var(--cyan-100);
	padding-block: var(--space-4);
}

.kt-search-form {
	display: flex;
	gap: var(--space-3);
}

.kt-search-form .kt-field__control {
	flex: 1;
	background: var(--white);
}

/* --------------------------------------------------------------------------
 * Drawer
 *
 * 86vw capped at 340px, in from the start edge, 52px rows with the children
 * indented on a cyan ground.
 * -------------------------------------------------------------------------- */

.kt-drawer {
	position: fixed;
	inset: 0;
	z-index: 200;
}

.kt-drawer__scrim {
	position: absolute;
	inset: 0;
	background: rgba(15, 26, 51, 0.45);
	backdrop-filter: blur(3px);
}

.kt-drawer__panel {
	position: absolute;
	inset-block: 0;
	inset-inline-start: 0;
	display: flex;
	overflow-y: auto;
	flex-direction: column;
	background: var(--white);
	inline-size: min(86vw, 340px);
	padding-block: var(--space-4) var(--space-10);
	box-shadow: var(--shadow-lg);
	animation: kt-drawer-in var(--dur-slow) var(--ease-out);
	will-change: translate;
}

@keyframes kt-drawer-in {

	from {
		translate: -100% 0;
	}

	to {
		translate: 0 0;
	}
}

/* The panel enters from the start edge, which is the right in RTL. */
[dir="rtl"] .kt-drawer__panel {
	animation-name: kt-drawer-in-rtl;
}

@keyframes kt-drawer-in-rtl {

	from {
		translate: 100% 0;
	}

	to {
		translate: 0 0;
	}
}

.kt-drawer__head {
	display: flex;
	align-items: center;
	justify-content: space-between;
	padding: 0 var(--space-4) var(--space-4);
}

.kt-drawer__logo {
	display: block;
	block-size: 44px;
	inline-size: auto;
}

.kt-drawer__nav {
	flex: 1;
}

.kt-drawer__nav .kt-nav__list {
	display: block;
}

.kt-drawer__nav .kt-nav__item {
	border-block-start: var(--border-w) solid var(--border-subtle);
}

.kt-drawer__nav .kt-nav__link {
	border-radius: 0;
	block-size: 52px;
	padding-inline: var(--space-4);
	font-size: var(--fs-lg);
}

.kt-drawer__nav .kt-nav__sub {
	display: block;
}

.kt-drawer__nav .kt-nav__sublink {
	display: flex;
	align-items: center;
	border-radius: 0;
	background: var(--cyan-100);
	block-size: 48px;
	padding-inline: var(--space-8);
}

.kt-drawer__foot {
	display: flex;
	flex-direction: column;
	border-block-start: var(--border-w) solid var(--border-subtle);
	margin-block-start: var(--space-4);
}

.kt-drawer__footlink {
	display: flex;
	align-items: center;
	block-size: 52px;
	padding-inline: var(--space-4);
	color: var(--blue-800);
	font-family: var(--font-core);
	font-size: var(--fs-body);
	text-decoration: none;
}

.kt-drawer__footlink:hover {
	background: var(--cyan-100);
}

/* Scroll lock while the drawer is open. */
.kt-no-scroll {
	overflow: hidden;
}

@media (min-width: 820px) {

	.kt-drawer {
		display: none !important;
	}
}

/* Alpine has not booted yet — keep x-show elements from flashing. */
[x-cloak] {
	display: none !important;
}

/* --------------------------------------------------------------------------
 * Live search results
 * -------------------------------------------------------------------------- */

.kt-search-live {
	margin-block-start: var(--space-3);
}

.kt-search-live[hidden] {
	display: none;
}

.kt-search-live__status {
	color: var(--text-muted);
	font-size: var(--fs-sm);
}

.kt-search-live__status:empty {
	display: none;
}

.kt-search-live__list {
	display: grid;
	grid-template-columns: minmax(0, 1fr);
	gap: var(--space-1);
	margin: var(--space-2) 0 0;
	list-style: none;
	padding: 0;
}

@media (min-width: 820px) {

	.kt-search-live__list {
		grid-template-columns: repeat(2, minmax(0, 1fr));
		gap: var(--space-2);
	}
}

.kt-search-result-item a {
	display: flex;
	align-items: center;
	gap: var(--space-3);
	border: var(--border-w) solid transparent;
	border-radius: var(--radius-md);
	background: var(--white);
	padding: var(--space-2);
	text-decoration: none;
	transition: var(--t-hover);
}

.kt-search-result-item a:hover,
.kt-search-result-item a:focus-visible,
.kt-search-result-item.is-active a {
	border-color: var(--cyan-300);
	background: var(--white);
	box-shadow: var(--shadow-sm);
}

.kt-search-result-item img,
.kt-search-result-item .kt-search-result-item__blank {
	flex: 0 0 auto;
	border-radius: var(--radius-sm);
	inline-size: 48px;
	block-size: 60px;
	object-fit: cover;
	background: var(--cyan-100);
}

.kt-search-result-item__text {
	display: flex;
	flex-direction: column;
	gap: 2px;
	min-inline-size: 0;
}

.kt-search-result-item__title {
	overflow: hidden;
	color: var(--text-heading);
	font-family: var(--font-core);
	font-size: var(--fs-sm);
	white-space: nowrap;
	text-overflow: ellipsis;
}

.kt-search-result-item__meta {
	color: var(--text-muted);
	font-size: var(--fs-xs);
}

.kt-search-result-item__price {
	color: var(--text-heading);
	font-family: var(--font-core);
	font-size: var(--fs-sm);
}

.kt-search-result-item__was {
	margin-inline-start: var(--space-2);
	color: var(--text-muted);
	font-size: var(--fs-xs);
	text-decoration: line-through;
}

.kt-search-live__all {
	display: inline-block;
	margin-block-start: var(--space-3);
	font-family: var(--font-core);
	font-size: var(--fs-sm);
}

/* ===== src/74-footer.css ===== */

/*
 * Site footer.
 *
 * Deep blue-900 ground — the one place the design system uses it as a field.
 * Four columns at 1.4fr 1fr 1fr 1.4fr on desktop, two on mobile.
 */

.kt-footer {
	background: var(--blue-900);
	margin-block-start: var(--space-20);
	padding-block: var(--space-16) var(--space-8);
	color: var(--white);
}

/*
 * The prototype fixes this at 1.4fr 1fr 1fr 1.4fr. Flex instead of grid, because
 * a column only renders when its menu exists — a fixed four-column track leaves
 * dead space and the wrong widths the moment the shop has no footer menu
 * assigned. The ratios below reproduce the prototype when all four are present.
 */
.kt-footer__cols {
	display: flex;
	flex-wrap: wrap;
	gap: var(--space-8);
}

.kt-footer__cols > * {
	flex: 1 1 160px;
}

@media (min-width: 820px) {

	.kt-footer__cols {
		gap: var(--space-10);
	}
}

.kt-footer__brand {
	display: flex;
	flex: 1 1 100%;
	flex-direction: column;
	gap: var(--space-3);
}

@media (min-width: 820px) {

	.kt-footer__brand {
		flex: 1.4 1 260px;
	}

	.kt-footer__cols > .kt-footer__col:last-child {
		flex: 1.4 1 240px;
	}
}

/* The nazar mark on a white disc — the brand's only illustration. */
.kt-footer__mark {
	display: flex;
	align-items: center;
	justify-content: center;
	border-radius: var(--radius-pill);
	background: var(--white);
	inline-size: 76px;
	block-size: 76px;
}

.kt-footer__name {
	font-family: var(--font-core);
	font-size: var(--fs-h3);
}

.kt-footer__tagline {
	margin: 0;
	max-inline-size: 260px;
	color: rgba(255, 255, 255, 0.7);
	font-size: var(--fs-sm);
}

.kt-footer__social {
	display: flex;
	flex-wrap: wrap;
	gap: var(--space-3);
	margin: 0;
	list-style: none;
	padding: 0;
}

.kt-footer__col {
	display: flex;
	flex-direction: column;
	gap: var(--space-2);
}

.kt-footer__coltitle {
	margin: 0 0 var(--space-1);
	color: var(--white);
	font-family: var(--font-core);
	font-size: var(--fs-body);
	font-weight: var(--fw-regular);
}

.kt-footer__list {
	display: flex;
	flex-direction: column;
	gap: var(--space-2);
	margin: 0;
	list-style: none;
	padding: 0;
}

.kt-footer a {
	color: rgba(255, 255, 255, 0.75);
	font-size: var(--fs-sm);
	text-decoration: none;
	transition: var(--t-hover);
}

.kt-footer a:hover {
	color: var(--white);
	text-decoration: underline;
}

.kt-footer__store {
	display: flex;
	flex-direction: column;
	gap: var(--space-2);
	color: rgba(255, 255, 255, 0.7);
	font-size: var(--fs-sm);
	font-style: normal;
	line-height: var(--lh-body);
}

.kt-footer__storeline {
	display: flex;
	align-items: flex-start;
	gap: var(--space-2);
}

.kt-footer__storeline .kt-icon {
	margin-block-start: 3px;
	color: var(--cyan-400);
}

.kt-footer__bar {
	display: flex;
	flex-wrap: wrap;
	justify-content: space-between;
	gap: var(--space-2);
	border-block-start: 1px solid rgba(255, 255, 255, 0.15);
	margin-block-start: var(--space-8);
	padding-block-start: var(--space-5);
	color: rgba(255, 255, 255, 0.6);
	font-size: var(--fs-xs);
}

/* ===== src/76-shop.css ===== */

/*
 * Product archive: hero, filter rail, sort row, grid, pagination.
 */

.kt-shop {
	padding-block: var(--space-6) var(--space-12);
}

.kt-shop__hero {
	display: flex;
	flex-direction: column;
	gap: var(--space-2);
	border-radius: var(--radius-xl);
	margin-block: var(--space-5) var(--space-8);
	padding: var(--space-6);
}

@media (min-width: 820px) {

	.kt-shop__hero {
		padding: var(--space-8);
	}
}

.kt-shop__eyebrow {
	color: var(--cyan-700);
	font-family: var(--font-core);
	font-size: 24px;
}

.kt-shop__title {
	margin: 0;
	font-family: var(--font-core);
	font-size: var(--fs-h1);
}

.kt-shop__intro {
	max-inline-size: 620px;
	color: var(--text-body);
}

.kt-shop__intro p:last-child {
	margin-block-end: 0;
}

/*
 * The archive is one grid: filter rail beside the results. WooCommerce emits
 * the loop between our two wrappers, so the rail and the results column are
 * siblings here.
 */
.woocommerce-products-header,
.woocommerce-notices-wrapper:empty {
	display: none;
}

.kt-shop__main {
	min-inline-size: 0;
}

@media (min-width: 820px) {

	.kt-shop__filters,
	.kt-shop__main {
		display: block;
	}

	.kt-shop .products,
	.kt-shop__sortrow,
	.kt-shop__main {
		grid-column: 2;
	}
}

/* --------------------------------------------------------------------------
 * Filter rail
 *
 * A column on desktop. On mobile the same markup becomes the sheet dialog
 * described in the design system's mobile rules — up from the bottom, 90vh.
 * -------------------------------------------------------------------------- */

.kt-shop__filters {
	position: fixed;
	inset: 0;
	z-index: 90;
	display: none;
	flex-direction: column;
	background: var(--white);
}

.kt-shop__filters.is-open {
	display: flex;
}

.kt-shop__filters-head {
	display: flex;
	align-items: center;
	justify-content: space-between;
	border-block-end: var(--border-w) solid var(--border-subtle);
	padding: var(--space-4);
}

.kt-shop__filters-title {
	margin: 0;
	font-family: var(--font-core);
	font-size: var(--fs-h3);
}

.kt-shop__filters-body {
	display: flex;
	flex: 1;
	overflow-y: auto;
	flex-direction: column;
	gap: var(--space-6);
	padding: var(--space-5) var(--space-4);
}

.kt-shop__filters-foot {
	border-block-start: var(--border-w) solid var(--border-subtle);
	padding: var(--space-4);
}

@media (min-width: 820px) {

	/*
	 * Back into the document as the rail. `inset` must be cleared explicitly:
	 * the mobile sheet above sets `inset: 0`, and leaving `bottom: 0` in place
	 * gives a sticky element two competing constraints, which lifts it out of
	 * its grid row and over the hero.
	 */
	.kt-shop__filters {
		position: sticky;
		inset: var(--space-6) auto auto auto;
		z-index: auto;
		display: flex;
		background: transparent;
	}

	.kt-shop__filters-head,
	.kt-shop__filters-foot {
		display: none;
	}

	.kt-shop__filters-body {
		overflow: visible;
		padding: 0;
	}
}

.kt-filter-group {
	display: flex;
	flex-direction: column;
	gap: var(--space-3);
	border-block-end: var(--border-w) solid var(--border-subtle);
	padding-block-end: var(--space-5);
}

.kt-filter-group:last-child {
	border-block-end: none;
	padding-block-end: 0;
}

.kt-filter-group__title {
	margin: 0;
	color: var(--text-heading);
	font-family: var(--font-core);
	font-size: var(--fs-lg);
	font-weight: var(--fw-regular);
}

.kt-filter-group__colors {
	display: flex;
	flex-wrap: wrap;
	gap: var(--space-2);
}

/* --------------------------------------------------------------------------
 * Sort row
 * -------------------------------------------------------------------------- */

.kt-shop__sortrow {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: space-between;
	gap: var(--space-4);
	margin-block-end: var(--space-5);
}

.kt-shop__chips {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: var(--space-2);
}

.kt-shop__count,
.kt-shop__clear {
	color: var(--text-muted);
	font-size: var(--fs-sm);
}

.kt-shop__sort {
	display: flex;
	align-items: center;
	gap: var(--space-3);
}

/* WooCommerce's ordering form, restyled rather than replaced. */
.woocommerce-ordering select {
	appearance: none;
	border: var(--border-w) solid var(--border-default);
	border-radius: var(--radius-md);
	background: var(--white);
	block-size: var(--field-h);
	inline-size: 220px;
	padding-inline: var(--space-4);
	color: var(--text-body);
	font-family: var(--font-body);
	font-size: var(--fs-body);
	cursor: pointer;
}

.woocommerce-ordering select:focus {
	outline: none;
	border-color: var(--blue-600);
	box-shadow: var(--ring-focus);
}

@media (min-width: 820px) {

	.kt-shop__filter-toggle {
		display: none;
	}
}

@media (max-width: 819px) {

	.woocommerce-ordering select {
		inline-size: auto;
		max-inline-size: 190px;
	}
}

/* --------------------------------------------------------------------------
 * Grid and pagination
 * -------------------------------------------------------------------------- */

.kt-shop ul.products {
	display: grid;
	grid-template-columns: repeat(2, minmax(0, 1fr));
	gap: var(--space-3);
	margin: 0;
	list-style: none;
	padding: 0;
}

@media (min-width: 820px) {

	.kt-shop ul.products {
		grid-template-columns: repeat(auto-fill, minmax(230px, 1fr));
		gap: var(--gutter);
	}
}

.woocommerce-pagination {
	display: flex;
	justify-content: center;
	margin-block-start: var(--space-12);
}

.woocommerce-pagination ul.page-numbers {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: var(--space-2);
	margin: 0;
	border: none;
	list-style: none;
	padding: 0;
}

.woocommerce-pagination li {
	border: none;
	margin: 0;
}

.woocommerce-pagination .page-numbers {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	border: var(--border-w) solid var(--border-subtle);
	border-radius: var(--radius-pill);
	background: transparent;
	min-inline-size: 40px;
	block-size: 40px;
	padding-inline: var(--space-3);
	color: var(--text-body);
	font-family: var(--font-body);
	font-size: var(--fs-sm);
	text-decoration: none;
	transition: var(--t-hover);
}

.woocommerce-pagination .page-numbers:hover {
	border-color: var(--blue-700);
	color: var(--blue-700);
}

.woocommerce-pagination .page-numbers.current {
	border-color: var(--blue-700);
	background: var(--blue-700);
	color: var(--white);
}

.woocommerce-pagination .page-numbers.dots {
	border-color: transparent;
	color: var(--ink-300);
}

/* --------------------------------------------------------------------------
 * The archive's two-column frame
 * -------------------------------------------------------------------------- */

@media (min-width: 820px) {

	.kt-shop .woocommerce-notices-wrapper,
	.kt-shop > .kt-breadcrumb,
	.kt-shop > .kt-shop__hero {
		grid-column: 1 / -1;
	}

	body.archive .kt-shop,
	body.post-type-archive-product .kt-shop {
		display: grid;
		grid-template-columns: 240px minmax(0, 1fr);
		gap: var(--space-10);
		align-items: start;
	}
}

/* ===== src/78-product.css ===== */

/*
 * Single product.
 *
 * WooCommerce's own DOM is kept: div.product wraps the gallery and .summary, so
 * the two-column layout is a grid on div.product and needs no template override.
 * The selector names the div on purpose — an archive's cards are li.product and
 * share the class, and would otherwise take the single page's two-column grid.
 */

.kt-shop div.product {
	display: grid;
	grid-template-columns: minmax(0, 1fr);
	gap: var(--space-6);
	align-items: start;
	margin-block-start: var(--space-6);
}

@media (min-width: 820px) {

	.kt-shop div.product {
		grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
		gap: var(--space-10);
	}
}

/* Gallery ----------------------------------------------------------------- */

.woocommerce-product-gallery {
	display: flex;
	flex-direction: column;
	gap: var(--space-3);
	min-inline-size: 0;
}

.woocommerce-product-gallery__wrapper {
	margin: 0;
}

.woocommerce-product-gallery__image img {
	display: block;
	border-radius: var(--radius-lg);
	inline-size: 100%;
	aspect-ratio: 4 / 5;
	object-fit: cover;
	box-shadow: var(--shadow-xs);
}

.flex-control-thumbs {
	display: grid;
	grid-template-columns: repeat(4, minmax(0, 1fr));
	gap: var(--space-3);
	margin: 0;
	list-style: none;
	padding: 0;
}

.flex-control-thumbs img {
	display: block;
	border: var(--border-w) solid var(--cyan-200);
	border-radius: var(--radius-md);
	inline-size: 100%;
	aspect-ratio: 1;
	object-fit: cover;
	cursor: pointer;
	transition: var(--t-hover);
}

.flex-control-thumbs .flex-active,
.flex-control-thumbs img:hover {
	border-color: var(--blue-700);
}

/* The zoom lens and lightbox trigger must not cover the whole frame. */
.woocommerce-product-gallery__trigger {
	position: absolute;
	inset-block-start: var(--space-3);
	inset-inline-start: var(--space-3);
	z-index: 5;
	display: flex;
	align-items: center;
	justify-content: center;
	border: none;
	border-radius: var(--radius-pill);
	background: rgba(255, 255, 255, 0.9);
	inline-size: 36px;
	block-size: 36px;
	color: var(--blue-800);
	text-decoration: none;
	box-shadow: var(--shadow-xs);
}

/* Summary ----------------------------------------------------------------- */

.kt-shop .summary {
	display: flex;
	flex-direction: column;
	gap: var(--space-4);
	min-inline-size: 0;
	margin: 0;
}

.kt-product-sku {
	color: var(--text-muted);
	font-size: var(--fs-xs);
}

/* The same badge the card wears, above the SKU. Replaces WooCommerce's .onsale. */
.kt-shop .summary .kt-product-badge {
	align-self: flex-start;
}

.kt-shop .product_title {
	margin: 0;
	font-family: var(--font-core);
	font-size: var(--fs-h1);
}

.kt-shop .summary .price {
	margin: 0;
	color: var(--text-heading);
	font-family: var(--font-core);
	font-size: var(--fs-h2);
}

.kt-shop .summary .price del {
	color: var(--ink-400);
	font-size: var(--fs-lg);
}

/* 27px is large text, so --danger's 4.18:1 clears the 3:1 threshold. */
.kt-shop .summary .price ins {
	color: var(--danger);
	text-decoration: none;
}

.woocommerce-product-details__short-description {
	max-inline-size: 520px;
	color: var(--text-body);
}

.woocommerce-product-details__short-description p:last-child {
	margin-block-end: 0;
}

/* Variation form ---------------------------------------------------------- */

.variations {
	display: flex;
	flex-direction: column;
	gap: var(--space-4);
	margin: 0;
	border: none;
	inline-size: 100%;
}

.variations tbody,
.variations tr,
.variations th,
.variations td {
	display: block;
	border: none;
	padding: 0;
	text-align: start;
}

.variations tr {
	display: flex;
	flex-direction: column;
	gap: var(--space-2);
}

.variations .label label {
	margin: 0;
	color: var(--text-heading);
	font-family: var(--font-core);
	font-size: var(--fs-body);
	font-weight: var(--fw-regular);
}

.kt-swatches {
	display: flex;
	flex-wrap: wrap;
	gap: var(--space-2);
}

.kt-swatches--color .kt-swatch {
	inline-size: 34px;
	block-size: 34px;
}

/* The chosen colour's name, on its own line under the dots. */
.kt-swatches__name {
	flex-basis: 100%;
	color: var(--text-muted);
	font-size: var(--fs-sm);
}

.kt-swatches__name:empty {
	display: none;
}

/*
 * WooCommerce's own <select> stays in the DOM and stays functional — its change
 * event is what updates the price, gallery and stock message — but it is taken
 * out of view. Not display:none: a hidden select cannot be focused, and Woo
 * calls .focus() on it in some flows.
 */
.kt-swatches__select {
	position: absolute;
	overflow: hidden;
	clip-path: inset(50%);
	inline-size: 1px;
	block-size: 1px;
}

.kt-swatch.is-out-of-stock {
	opacity: 0.45;
	cursor: not-allowed;
}

.kt-swatch.is-out-of-stock .kt-swatch__dot {
	box-shadow: inset 0 0 0 1px rgba(15, 26, 51, 0.12);
}

.reset_variations {
	color: var(--text-link);
	font-size: var(--fs-sm);
}

.woocommerce-variation-price {
	margin-block-end: var(--space-3);
}

.woocommerce-variation-availability p {
	margin: 0;
	color: var(--text-muted);
	font-size: var(--fs-sm);
}

/* Add to cart ------------------------------------------------------------- */

.kt-shop form.cart {
	display: flex;
	flex-direction: column;
	gap: var(--space-4);
	margin: 0;
}

.kt-shop form.cart .quantity {
	display: inline-flex;
	align-items: center;
	border: var(--border-w) solid var(--border-default);
	border-radius: var(--radius-pill);
	background: var(--white);
	block-size: var(--control-h);
	padding-inline: var(--space-2);
}

.kt-shop form.cart .quantity input.qty {
	border: none;
	background: transparent;
	inline-size: 56px;
	padding: 0;
	color: var(--text-heading);
	font-family: var(--font-body);
	font-weight: var(--fw-medium);
	text-align: center;
	appearance: textfield;
}

.kt-shop form.cart .quantity input.qty::-webkit-outer-spin-button,
.kt-shop form.cart .quantity input.qty::-webkit-inner-spin-button {
	margin: 0;
	appearance: none;
}

.kt-shop .summary .single_add_to_cart_button {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: var(--space-2);
	border: var(--border-w-thick) solid var(--blue-700);
	border-radius: var(--radius-pill);
	background: var(--blue-700);
	block-size: 54px;
	min-inline-size: 200px;
	padding-inline: 34px;
	color: var(--white);
	font-family: var(--font-core);
	font-size: var(--fs-lg);
	cursor: pointer;
	box-shadow: var(--shadow-brand);
	transition: var(--t-hover);
}

.kt-shop .summary .single_add_to_cart_button:hover {
	border-color: var(--blue-800);
	background: var(--blue-800);
}

.kt-shop .summary .single_add_to_cart_button:disabled {
	opacity: 0.45;
	cursor: not-allowed;
}

.kt-shop .woocommerce-variation-add-to-cart,
.kt-shop form.cart:not(.variations_form) {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: var(--space-3);
}

/* Facts ------------------------------------------------------------------- */

.kt-product-facts {
	display: flex;
	flex-direction: column;
	gap: var(--space-3);
	border-block-start: var(--border-w) solid var(--border-subtle);
	margin: var(--space-2) 0 0;
	list-style: none;
	padding-block-start: var(--space-5);
	padding-inline: 0;
}

.kt-product-facts__item {
	display: flex;
	align-items: center;
	gap: var(--space-3);
	color: var(--text-body);
	font-size: var(--fs-sm);
}

.kt-product-facts__item .kt-icon {
	color: var(--cyan-700);
}

/* Related ----------------------------------------------------------------- */

.related.products {
	grid-column: 1 / -1;
	margin-block-start: var(--space-16);
}

.related.products > h2 {
	margin-block-end: var(--space-5);
	font-family: var(--font-core);
}

/* --------------------------------------------------------------------------
 * Mobile action bar
 *
 * The design pins the primary action to the bottom on the product and cart
 * screens, and asks for 92px of bottom padding so nothing hides under it.
 * -------------------------------------------------------------------------- */

.kt-actionbar {
	position: fixed;
	inset-inline: 0;
	inset-block-end: 0;
	z-index: 80;
	display: flex;
	align-items: center;
	gap: var(--space-3);
	border-block-start: var(--border-w) solid var(--cyan-200);
	background: var(--white);
	padding: var(--space-3) var(--space-4);
	box-shadow: var(--shadow-lg);
}

.kt-actionbar__label {
	display: flex;
	flex-direction: column;
	white-space: nowrap;
}

.kt-actionbar__label small {
	color: var(--text-muted);
	font-size: var(--fs-xs);
}

.kt-actionbar .kt-btn {
	flex: 1;
}

@media (min-width: 820px) {

	.kt-actionbar {
		display: none;
	}
}

@media (max-width: 819px) {

	body.single-product,
	body.woocommerce-cart {
		padding-block-end: 92px;
	}
}

/* ===== src/80-feedback.css ===== */

/*
 * Dialog, Toast, Tooltip, EmptyState.
 */

/*
 * DS Dialog.jsx. The scrim is the one place in the system that uses
 * transparency and blur: rgba(15,26,51,.45) + blur(3px). Panel is --radius-xl
 * with --shadow-lg and 32px padding.
 */
.kt-dialog {
	position: fixed;
	inset: 0;
	z-index: 60;
	display: flex;
	align-items: center;
	justify-content: center;
	padding: var(--space-6);
}

.kt-dialog[hidden] {
	display: none;
}

.kt-dialog__scrim {
	position: absolute;
	inset: 0;
	background: rgba(15, 26, 51, 0.45);
	backdrop-filter: blur(3px);
}

.kt-dialog__panel {
	position: relative;
	border-radius: var(--radius-xl);
	background: var(--surface-card);
	inline-size: 100%;
	max-inline-size: 460px;
	max-block-size: calc(100vh - var(--space-12));
	overflow-y: auto;
	padding: var(--space-8);
	box-shadow: var(--shadow-lg);
}

.kt-dialog__head {
	display: flex;
	align-items: flex-start;
	gap: var(--space-4);
	margin-block-end: var(--space-4);
}

.kt-dialog__title {
	flex: 1;
	margin: 0;
	color: var(--text-heading);
	font-family: var(--font-core);
	font-size: var(--fs-h3);
	font-weight: var(--fw-regular);
}

.kt-dialog__close {
	display: flex;
	align-items: center;
	justify-content: center;
	border: none;
	border-radius: var(--radius-pill);
	background: transparent;
	inline-size: var(--control-h);
	block-size: var(--control-h);
	padding: 0;
	color: var(--ink-400);
	cursor: pointer;
	transition: var(--t-hover);
}

.kt-dialog__close:hover {
	background: var(--blue-100);
	color: var(--blue-800);
}

.kt-dialog__foot {
	display: flex;
	gap: var(--space-3);
	margin-block-start: var(--space-6);
}

/*
 * The mobile filter dialog slides up to full height rather than sitting in the
 * middle of the screen — the design system's mobile rule for the filter rail.
 */
@media (max-width: 819px) {

	.kt-dialog--sheet {
		align-items: flex-end;
		padding: 0;
	}

	.kt-dialog--sheet .kt-dialog__panel {
		border-end-end-radius: 0;
		border-end-start-radius: 0;
		max-inline-size: none;
		block-size: 90vh;
		max-block-size: 90vh;
	}
}

/* --------------------------------------------------------------------------
 * Toast
 *
 * DS Toast.jsx. Fired on the add-to-cart confirmation, which is one of the two
 * moments allowed --ease-bounce. Entrance pairs the fade with a 4px translate,
 * per the motion rules; nothing scales up from zero.
 * -------------------------------------------------------------------------- */

.kt-toast-region {
	position: fixed;
	inset-block-end: var(--space-6);
	inset-inline-end: var(--space-6);
	z-index: 90;
	display: flex;
	flex-direction: column;
	gap: var(--space-3);
	pointer-events: none;
}

/* Clear of the mobile action bar and the WhatsApp button. */
@media (max-width: 819px) {

	body.single-product .kt-toast-region,
	body.woocommerce-cart .kt-toast-region {
		inset-block-end: 104px;
	}
}

.kt-toast--leaving {
	animation: kt-toast-out var(--dur-base) var(--ease-out) forwards;
}

@keyframes kt-toast-out {

	to {
		opacity: 0;
		transform: translateY(4px);
	}
}

/* A toast that links somewhere puts the action on its own line. */
.kt-toast__action {
	margin-block-start: var(--space-2);
	color: var(--text-link);
	font-family: var(--font-core);
	font-size: var(--fs-sm);
}

.kt-toast-region > * {
	pointer-events: auto;
}

.kt-toast {
	display: flex;
	align-items: flex-start;
	gap: var(--space-3);
	border: var(--border-w) solid var(--success);
	border-radius: var(--radius-lg);
	background: var(--success-soft);
	min-inline-size: 280px;
	max-inline-size: 420px;
	padding: var(--space-4) var(--space-5);
	font-family: var(--font-body);
	box-shadow: var(--shadow-md);
	animation: kt-toast-in var(--dur-slow) var(--ease-bounce);
}

.kt-toast__icon {
	display: flex;
	margin-block-start: 2px;
	color: var(--success);
}

.kt-toast__body {
	flex: 1;
}

.kt-toast__title {
	color: var(--text-heading);
	font-family: var(--font-core);
	font-size: var(--fs-body);
}

.kt-toast__text {
	color: var(--text-body);
	font-size: var(--fs-sm);
}

.kt-toast__close {
	border: none;
	background: transparent;
	padding: 0;
	color: var(--ink-400);
	font-size: 16px;
	line-height: 1;
	cursor: pointer;
}

.kt-toast--info {
	border-color: var(--cyan-600);
	background: var(--cyan-100);
}

.kt-toast--info .kt-toast__icon {
	color: var(--cyan-700);
}

.kt-toast--warning {
	border-color: var(--warning);
	background: var(--warning-soft);
}

.kt-toast--warning .kt-toast__icon {
	color: var(--warning);
}

.kt-toast--danger {
	border-color: var(--danger);
	background: var(--danger-soft);
}

.kt-toast--danger .kt-toast__icon {
	color: var(--danger);
}

@keyframes kt-toast-in {

	from {
		opacity: 0;
		transform: translateY(4px);
	}

	to {
		opacity: 1;
		transform: translateY(0);
	}
}

@media (max-width: 819px) {

	.kt-toast-region {
		inset-inline: var(--space-4);
		inset-block-end: var(--space-4);
	}

	.kt-toast {
		min-inline-size: 0;
		max-inline-size: none;
	}
}

/* --------------------------------------------------------------------------
 * Tooltip
 *
 * DS Tooltip.jsx centres the bubble with insetInlineStart:50% and
 * translateX(50%), which only lands correctly in RTL. Centring here is done
 * with inset-inline: 0 and margin-inline: auto, which needs no direction at all.
 * -------------------------------------------------------------------------- */

.kt-tooltip {
	position: relative;
	display: inline-flex;
}

.kt-tooltip__bubble {
	position: absolute;
	inset-inline: 0;
	inset-block-end: calc(100% + 8px);
	z-index: 40;
	margin-inline: auto;
	border-radius: var(--radius-sm);
	background: var(--blue-900);
	inline-size: max-content;
	max-inline-size: 240px;
	padding: 6px 10px;
	color: var(--white);
	font-family: var(--font-body);
	font-size: var(--fs-xs);
	box-shadow: var(--shadow-sm);
	opacity: 0;
	transform: translateY(4px);
	pointer-events: none;
	transition:
		opacity var(--dur-fast) var(--ease-out),
		transform var(--dur-fast) var(--ease-out);
}

.kt-tooltip:hover .kt-tooltip__bubble,
.kt-tooltip:focus-within .kt-tooltip__bubble {
	opacity: 1;
	transform: translateY(0);
}

.kt-tooltip__bubble--bottom {
	inset-block: calc(100% + 8px) auto;
}

/* --------------------------------------------------------------------------
 * EmptyState
 *
 * DS EmptyState.jsx: centred, 64px/24px padding, the nazar mark as art at 50%
 * opacity. Used by the empty cart, no search results and 404.
 * -------------------------------------------------------------------------- */

.kt-empty {
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: var(--space-4);
	padding: var(--space-16) var(--space-6);
	text-align: center;
}

.kt-empty__art {
	margin-block-end: var(--space-2);
	opacity: 0.5;
}

.kt-empty__title {
	margin: 0;
	color: var(--text-heading);
	font-family: var(--font-core);
	font-size: var(--fs-h3);
	font-weight: var(--fw-regular);
}

.kt-empty__text {
	margin: 0;
	max-inline-size: 380px;
	color: var(--text-muted);
	font-family: var(--font-body);
}

/* ===== src/81-popup.css ===== */

/*
 * Popup.
 *
 * The DS Dialog, with a picture above the words: same scrim, same --radius-xl
 * panel on --shadow-lg, same close control in the corner. It differs from the
 * dialogs the shopper opens themselves in one way only — nobody asked for it —
 * so the close button is a full 44px target from the first frame, the scrim
 * closes it, and Escape closes it.
 *
 * The panel arrives with the system's rise: opacity plus a 6px translate over
 * --dur-slow, never a scale from zero. 84-motion.css turns that off for anyone
 * who asks for less motion.
 */

.kt-popup {
	z-index: 120;
}

.kt-popup__panel {
	max-inline-size: 420px;
	padding: 0;
	overflow: hidden;
	animation: kt-popup-in var(--dur-slow) var(--ease-out);
}

@keyframes kt-popup-in {

	from {
		opacity: 0;
		transform: translateY(6px);
	}

	to {
		opacity: 1;
		transform: none;
	}
}

/*
 * The close control sits over the picture, so it carries its own surface — the
 * one place besides the wishlist capsule where the system allows transparency.
 */
.kt-popup__close {
	position: absolute;
	inset-block-start: var(--space-3);
	inset-inline-end: var(--space-3);
	z-index: 1;
	border-radius: var(--radius-pill);
	background: rgba(255, 255, 255, 0.9);
	color: var(--ink-500);
	box-shadow: var(--shadow-xs);
}

.kt-popup__close:hover {
	background: var(--white);
	color: var(--blue-800);
}

/* The picture can carry its own destination — an ad's landing page, the club. */
.kt-popup__imagelink {
	display: block;
}

.kt-popup__imagelink:focus-visible {
	outline: none;
	box-shadow: inset 0 0 0 3px var(--blue-600);
}

.kt-popup__media img {
	display: block;
	inline-size: 100%;
	block-size: auto;
	aspect-ratio: 4 / 3;
	object-fit: cover;
}

/*
 * An image-only popup is a finished banner the shop uploaded, not a crop the design
 * controls. Let it keep its own proportions — the 4:3 above would centre-crop a wide
 * banner and throw away the artwork on both sides. The panel shrinks to the picture,
 * and the close button lifts off it so it stays visible over a dark image.
 */
.kt-popup--image-only .kt-popup__media img {
	aspect-ratio: auto;
	object-fit: contain;
}

.kt-popup--image-only .kt-popup__body {
	display: none;
}

.kt-popup--image-only .kt-popup__panel {
	max-inline-size: min(1200px, calc(100vw - 2 * var(--space-4)));
	padding: 0;
	overflow: hidden;
}

/*
 * A wide banner must not outgrow the viewport's height either: cap the picture
 * to what fits, keep its proportions, and let the panel shrink to it.
 */
.kt-popup--image-only .kt-popup__media img {
	max-block-size: calc(100vh - 2 * var(--space-8));
	inline-size: auto;
	max-inline-size: 100%;
	margin-inline: auto;
}

.kt-popup--image-only .kt-popup__close {
	background: var(--white);
	box-shadow: var(--shadow-sm);
}

.kt-popup__body {
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	gap: var(--space-3);
	padding: var(--space-6);

	/* Room for the close control where there is no picture for it to sit on. */
	padding-inline-end: calc(var(--space-6) + var(--control-h));
}

.kt-popup__media + .kt-popup__body {
	padding-inline-end: var(--space-6);
}

.kt-popup__title {
	font-size: var(--fs-h3);
}

.kt-popup__text {
	margin: 0;
	color: var(--text-body);
}

.kt-popup__cta {
	margin-block-start: var(--space-2);
}

@media (max-width: 819px) {

	.kt-popup {
		padding: var(--space-4);
	}

	.kt-popup__body {
		padding: var(--space-5);
	}
}

/* ===== src/82-cart.css ===== */

/*
 * Cart, checkout and account.
 */

.woocommerce-cart .kt-shop,
.woocommerce-checkout .kt-shop,
.woocommerce-account .kt-shop {
	padding-block: var(--space-8) var(--space-16);
}

.woocommerce-cart .entry-title,
.woocommerce-checkout .entry-title,
.woocommerce-account .entry-title {
	margin-block: var(--space-4) var(--space-6);
	font-family: var(--font-core);
	font-size: var(--fs-h1);
}

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

/*
 * Commerce pages are full width. page.php gives them .kt-page-content instead of
 * .kt-prose, whose 68ch measure is right for reading and wrong for a cart.
 */
.kt-page-content {
	max-inline-size: none;
}

/*
 * Two columns only while there is something in the cart. The empty state is a
 * notice and a "back to shop" button, and gridding those put the button alone in
 * the 380px summary track with nothing beside it.
 */
@media (min-width: 820px) {

	.woocommerce-cart .woocommerce:has(.woocommerce-cart-form) {
		display: grid;
		grid-template-columns: minmax(0, 1fr) 380px;
		gap: var(--space-10);
		align-items: start;
	}

	.woocommerce-cart .woocommerce > .woocommerce-notices-wrapper,
	.woocommerce-cart .woocommerce > .cart-empty,
	.woocommerce-cart .woocommerce > .return-to-shop {
		grid-column: 1 / -1;
	}
}

.woocommerce-cart .cart-empty {
	margin: 0 0 var(--space-5);
}

.woocommerce-cart .return-to-shop {
	margin: 0;
}

.kt-cart__lines {
	display: flex;
	flex-direction: column;
	gap: var(--space-4);
}

.kt-cart__line {
	display: grid;
	grid-template-columns: 84px minmax(0, 1fr);
	gap: var(--space-4);
	align-items: center;
	border: var(--border-w) solid var(--border-subtle);
	border-radius: var(--radius-lg);
	background: var(--white);
	padding: var(--space-4);
	box-shadow: var(--shadow-xs);
}

@media (min-width: 560px) {

	.kt-cart__line {
		grid-template-columns: 110px minmax(0, 1fr) auto;
		gap: var(--space-5);
	}
}

.kt-cart__media img {
	display: block;
	border-radius: var(--radius-md);
	inline-size: 100%;
	aspect-ratio: 4 / 5;
	object-fit: cover;
}

.kt-cart__details {
	display: flex;
	flex-direction: column;
	gap: var(--space-2);
	min-inline-size: 0;
}

.kt-cart__title {
	color: var(--text-heading);
	font-family: var(--font-core);
	font-size: var(--fs-lg);
}

.kt-cart__title a {
	color: inherit;
	text-decoration: none;
}

/* WooCommerce's variation meta list: "מידה: 10-11". */
.kt-cart__details .variation {
	display: flex;
	flex-wrap: wrap;
	gap: var(--space-1) var(--space-3);
	margin: 0;
	color: var(--text-muted);
	font-size: var(--fs-sm);
}

.kt-cart__details .variation dt,
.kt-cart__details .variation dd {
	margin: 0;
}

.kt-cart__details .variation dd p {
	margin: 0;
}

.kt-cart__qty .quantity {
	display: inline-flex;
	align-items: center;
	border: var(--border-w) solid var(--border-default);
	border-radius: var(--radius-pill);
	background: var(--white);
	block-size: 40px;
	padding-inline: var(--space-2);
}

.kt-cart__qty input.qty {
	border: none;
	background: transparent;
	inline-size: 48px;
	padding: 0;
	color: var(--text-heading);
	font-family: var(--font-body);
	font-weight: var(--fw-medium);
	text-align: center;
	appearance: textfield;
}

.kt-cart__qty input.qty::-webkit-outer-spin-button,
.kt-cart__qty input.qty::-webkit-inner-spin-button {
	margin: 0;
	appearance: none;
}

.kt-cart__end {
	display: flex;
	flex-direction: column;
	align-items: flex-end;
	gap: var(--space-3);
	grid-column: 2;
	font-family: var(--font-core);
	font-size: var(--fs-lg);
	color: var(--text-heading);
}

@media (min-width: 560px) {

	.kt-cart__end {
		grid-column: auto;
	}
}

.kt-cart__remove {
	color: var(--text-muted);
	font-family: var(--font-body);
	font-size: var(--fs-sm);
	text-decoration: none;
}

.kt-cart__remove:hover {
	color: var(--danger);
}

.kt-cart__actions {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: var(--space-3);
	margin-block-start: var(--space-5);
}

.kt-cart__coupon {
	display: flex;
	flex: 1 1 280px;
	gap: var(--space-2);
}

.kt-cart__coupon .kt-field__control {
	flex: 1;
}

.kt-cart__coupon input {
	flex: 1;
	border: none;
	outline: none;
	background: transparent;
	min-inline-size: 0;
	color: var(--text-body);
	font-family: var(--font-body);
	font-size: var(--fs-body);
}

.kt-cart__continue {
	display: inline-flex;
	align-items: center;
	gap: var(--space-2);
	margin-block-start: var(--space-5);
	font-size: var(--fs-body);
	text-decoration: none;
}

/* Summary card ------------------------------------------------------------ */

.kt-summary {
	display: flex;
	flex-direction: column;
	gap: var(--space-4);
	border: var(--border-w) solid var(--cyan-200);
	border-radius: var(--radius-lg);
	background: var(--cyan-100);
	padding: var(--space-6);
}

@media (min-width: 820px) {

	.kt-summary {
		position: sticky;
		inset-block-start: var(--space-6);
	}
}

.kt-summary__title {
	margin: 0;
	color: var(--text-heading);
	font-family: var(--font-core);
	font-size: var(--fs-h3);
	font-weight: var(--fw-regular);
}

.kt-summary__row,
.kt-summary tr {
	display: flex;
	justify-content: space-between;
	gap: var(--space-3);
	color: var(--text-body);
	font-size: var(--fs-sm);
}

/* The guest's one-line invitation to the member discount. */
.kt-summary__club {
	display: flex;
	align-items: flex-start;
	gap: var(--space-2);
	margin: 0;
	color: var(--text-body);
	font-size: var(--fs-sm);
}

.kt-summary__club .kt-icon {
	flex: 0 0 auto;
	margin-block-start: 2px;
	color: var(--cyan-700);
}

.kt-summary__total {
	display: flex;
	align-items: baseline;
	justify-content: space-between;
	border-block-start: var(--border-w) solid var(--cyan-300);
	padding-block-start: var(--space-4);
	color: var(--text-heading);
	font-family: var(--font-core);
	font-size: var(--fs-lg);
}

.kt-summary__total .woocommerce-Price-amount {
	font-size: var(--fs-h2);
}

.kt-summary ul#shipping_method {
	display: flex;
	flex-direction: column;
	gap: var(--space-2);
	margin: 0;
	list-style: none;
	padding: 0;
	text-align: start;
}

.kt-summary .woocommerce-shipping-destination,
.kt-summary .shipping-calculator-button {
	font-size: var(--fs-xs);
}

.kt-summary__cta .kt-btn,
.kt-summary__cta .checkout-button {
	display: flex;
	align-items: center;
	justify-content: center;
	border: var(--border-w-thick) solid var(--blue-700);
	border-radius: var(--radius-pill);
	background: var(--blue-700);
	inline-size: 100%;
	block-size: 54px;
	color: var(--white);
	font-family: var(--font-core);
	font-size: var(--fs-lg);
	text-decoration: none;
	box-shadow: var(--shadow-brand);
	transition: var(--t-hover);
}

.kt-summary__cta .checkout-button:hover {
	border-color: var(--blue-800);
	background: var(--blue-800);
	color: var(--white);
}

/* --------------------------------------------------------------------------
 * Checkout
 *
 * No template override. WooCommerce's checkout.js replaces
 * `.woocommerce-checkout-payment` and `.woocommerce-checkout-review-order-table`
 * by selector on every order-review refresh, so any wrapper placed around them
 * would be destroyed. display:contents on their parents instead lets the three
 * design sections and the sticky order card be built purely by grid placement,
 * leaving WooCommerce's DOM — and iCredit's expectations of it — untouched.
 * -------------------------------------------------------------------------- */

@media (min-width: 820px) {

	.woocommerce-checkout form.checkout {
		display: grid;
		grid-template-columns: minmax(0, 1fr) 360px;
		gap: var(--space-10) var(--space-10);
		align-items: start;
	}

	.woocommerce-checkout #customer_details,
	.woocommerce-checkout #order_review {
		display: contents;
	}

	.woocommerce-checkout .col-1,
	.woocommerce-checkout .col-2,
	.woocommerce-checkout .woocommerce-checkout-payment {
		grid-column: 1;
	}

	.woocommerce-checkout #order_review_heading,
	.woocommerce-checkout .woocommerce-checkout-review-order-table {
		grid-column: 2;
	}

	.woocommerce-checkout #order_review_heading {
		grid-row: 1;
		margin: 0;
	}

	.woocommerce-checkout .woocommerce-checkout-review-order-table {
		position: sticky;
		inset-block-start: var(--space-6);
		grid-row: 2 / span 3;
	}
}

.woocommerce-checkout .col-1,
.woocommerce-checkout .col-2,
.woocommerce-checkout .woocommerce-checkout-payment {
	display: flex;
	flex-direction: column;
	gap: var(--space-4);
}

.woocommerce-checkout h3 {
	margin: 0;
	font-family: var(--font-core);
	font-size: var(--fs-h3);
}

.woocommerce-checkout .form-row {
	display: flex;
	flex-direction: column;
	gap: var(--space-2);
	margin: 0;
	padding: 0;
}

.woocommerce-checkout .form-row label {
	color: var(--text-heading);
	font-family: var(--font-body);
	font-size: var(--fs-sm);
	font-weight: var(--fw-medium);
}

.woocommerce-checkout .form-row .required {
	border: none;
	color: var(--danger);
	text-decoration: none;
}

/*
 * Field styling covers every WooCommerce form, not just checkout: login,
 * registration, lost password, address edit and the account details form all
 * emit .input-text and would otherwise arrive as browser defaults now that
 * woocommerce-general.css is dequeued.
 */
.woocommerce .input-text,
.woocommerce form select,
.woocommerce .select2-container .select2-selection,
.woocommerce-checkout .input-text,
.woocommerce-checkout select,
.woocommerce-checkout .select2-container .select2-selection {
	border: var(--border-w) solid var(--border-default);
	border-radius: var(--radius-md);
	background: var(--white);
	inline-size: 100%;
	block-size: var(--field-h);
	padding-inline: 14px;
	color: var(--text-body);
	font-family: var(--font-body);
	font-size: var(--fs-body);
}

/*
 * A WooCommerce input placed inside the theme's bordered control — the cart's
 * coupon field — must not bring its own border along, or it draws two.
 */
.woocommerce .kt-field__control > .input-text {
	border: none;
	border-radius: 0;
	background: transparent;
	block-size: auto;
	padding: 0;
	box-shadow: none;
}

/*
 * WooCommerce's script wraps every password field and appends a show/hide
 * toggle whose only face is an icon from the dequeued stylesheet — it arrived
 * as a bare 12px pill under the field. The eye is not in the theme's sprite, so
 * the toggle goes rather than being redrawn.
 */
.woocommerce .password-input {
	display: block;
	position: relative;
}

.woocommerce .show-password-input {
	display: none;
}

.woocommerce textarea.input-text,
.woocommerce-checkout textarea.input-text {
	block-size: auto;
	min-block-size: 110px;
	padding-block: var(--space-3);
}

.woocommerce .input-text:focus,
.woocommerce form select:focus,
.woocommerce-checkout .input-text:focus,
.woocommerce-checkout select:focus {
	outline: none;
	border-color: var(--blue-600);
	box-shadow: var(--ring-focus);
}

/* Two-up rows, as the design lays the customer details out. */
@media (min-width: 560px) {

	.woocommerce-checkout .col-1 .woocommerce-billing-fields__field-wrapper,
	.woocommerce-checkout .col-2 .woocommerce-shipping-fields__field-wrapper {
		display: grid;
		grid-template-columns: repeat(2, minmax(0, 1fr));
		gap: var(--space-4);
	}

	.woocommerce-checkout .form-row-wide {
		grid-column: 1 / -1;
	}
}

.woocommerce-checkout ul#shipping_method {
	display: flex;
	flex-direction: column;
	gap: var(--space-3);
	margin: 0;
	list-style: none;
	padding: 0;
}

.woocommerce-checkout ul#shipping_method li {
	border: var(--border-w) solid var(--border-default);
	border-radius: var(--radius-md);
	padding: var(--space-4);
}

.woocommerce-checkout-review-order-table {
	display: flex;
	flex-direction: column;
	gap: var(--space-3);
	border: var(--border-w) solid var(--cyan-200);
	border-radius: var(--radius-lg);
	background: var(--cyan-100);
	padding: var(--space-6);
}

.woocommerce-checkout-review-order-table thead {
	display: none;
}

.woocommerce-checkout-review-order-table tbody,
.woocommerce-checkout-review-order-table tfoot {
	display: flex;
	flex-direction: column;
	gap: var(--space-3);
}

.woocommerce-checkout-review-order-table tr {
	display: flex;
	justify-content: space-between;
	gap: var(--space-3);
	font-size: var(--fs-sm);
}

.woocommerce-checkout-review-order-table td,
.woocommerce-checkout-review-order-table th {
	border: none;
	padding: 0;
	text-align: start;
}

.woocommerce-checkout-review-order-table .order-total {
	border-block-start: var(--border-w) solid var(--cyan-300);
	padding-block-start: var(--space-4);
	color: var(--text-heading);
	font-family: var(--font-core);
	font-size: var(--fs-lg);
}

.woocommerce-checkout-payment {
	border: var(--border-w) solid var(--border-subtle);
	border-radius: var(--radius-lg);
	background: var(--white);
	padding: var(--space-6);
}

.woocommerce-checkout-payment ul.payment_methods {
	display: flex;
	flex-direction: column;
	gap: var(--space-3);
	margin: 0 0 var(--space-4);
	list-style: none;
	padding: 0;
}

.woocommerce-checkout-payment .payment_box {
	border-radius: var(--radius-md);
	background: var(--cyan-100);
	margin-block-start: var(--space-2);
	padding: var(--space-4);
	font-size: var(--fs-sm);
}

.woocommerce-checkout-payment #place_order {
	display: flex;
	align-items: center;
	justify-content: center;
	border: var(--border-w-thick) solid var(--blue-700);
	border-radius: var(--radius-pill);
	background: var(--blue-700);
	inline-size: 100%;
	block-size: 54px;
	color: var(--white);
	font-family: var(--font-core);
	font-size: var(--fs-lg);
	cursor: pointer;
	box-shadow: var(--shadow-brand);
	transition: var(--t-hover);
}

.woocommerce-checkout-payment #place_order:hover {
	border-color: var(--blue-800);
	background: var(--blue-800);
}

/* --------------------------------------------------------------------------
 * My account
 * -------------------------------------------------------------------------- */

/*
 * Navigation beside content, but only for a signed-in customer — that is the
 * only time WooCommerce prints the navigation column. Signed out, the same
 * wrapper holds the login and registration forms, and gridding it squeezed both
 * into the 220px track meant for the menu.
 */
@media (min-width: 820px) {

	.woocommerce-account.logged-in .woocommerce {
		display: grid;
		grid-template-columns: 220px minmax(0, 1fr);
		gap: var(--space-10);
		align-items: start;
	}

	.woocommerce-account.logged-in .woocommerce > .woocommerce-notices-wrapper {
		grid-column: 1 / -1;
	}
}

.woocommerce-MyAccount-navigation ul {
	display: flex;
	flex-direction: column;
	gap: var(--space-1);
	margin: 0;
	list-style: none;
	padding: 0;
}

.woocommerce-MyAccount-navigation a {
	display: block;
	border-radius: var(--radius-pill);
	padding: 10px var(--space-4);
	color: var(--text-body);
	font-family: var(--font-core);
	font-size: var(--fs-body);
	text-decoration: none;
	transition: var(--t-hover);
}

.woocommerce-MyAccount-navigation a:hover {
	background: var(--cyan-100);
	color: var(--blue-800);
}

.woocommerce-MyAccount-navigation .is-active a {
	background: var(--blue-700);
	color: var(--white);
}

.woocommerce-MyAccount-content {
	min-inline-size: 0;
}

.woocommerce-orders-table,
.woocommerce-table--order-details {
	inline-size: 100%;
	border-collapse: collapse;
	font-size: var(--fs-sm);
}

.woocommerce-orders-table th,
.woocommerce-orders-table td,
.woocommerce-table--order-details th,
.woocommerce-table--order-details td {
	border-block-end: var(--border-w) solid var(--border-subtle);
	padding: var(--space-3);
	text-align: start;
}

.woocommerce-orders-table th {
	color: var(--text-heading);
	font-family: var(--font-core);
	font-weight: var(--fw-regular);
}

/* --------------------------------------------------------------------------
 * WooCommerce notices
 * -------------------------------------------------------------------------- */

.woocommerce-message,
.woocommerce-info,
.woocommerce-error {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: var(--space-3);
	border: var(--border-w) solid var(--success);
	border-radius: var(--radius-lg);
	background: var(--success-soft);
	margin-block-end: var(--space-5);
	list-style: none;
	padding: var(--space-4) var(--space-5);
	font-family: var(--font-body);
	font-size: var(--fs-sm);
}

.woocommerce-info {
	border-color: var(--cyan-600);
	background: var(--cyan-100);
}

.woocommerce-error {
	flex-direction: column;
	align-items: flex-start;
	border-color: var(--danger);
	background: var(--danger-soft);
}

.woocommerce-message .button,
.woocommerce-info .button {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	border: var(--border-w-thick) solid var(--blue-700);
	border-radius: var(--radius-pill);
	background: transparent;
	block-size: 36px;
	margin-inline-start: auto;
	padding-inline: var(--space-4);
	color: var(--blue-700);
	font-family: var(--font-core);
	font-size: var(--fs-sm);
	text-decoration: none;
}

/* --------------------------------------------------------------------------
 * Generic WooCommerce buttons
 *
 * woocommerce-general.css is dequeued, so anything WooCommerce renders as
 * .button — "return to shop" on the empty cart, "view cart" in a notice, the
 * order-again action in the account — needs the theme's button here rather than
 * arriving unstyled.
 * -------------------------------------------------------------------------- */

.woocommerce a.button,
.woocommerce button.button,
.woocommerce input.button,
.woocommerce #respond input#submit {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: var(--space-2);
	border: var(--border-w-thick) solid var(--blue-700);
	border-radius: var(--radius-pill);
	background: var(--blue-700);
	block-size: var(--control-h);
	padding-inline: var(--space-6);
	color: var(--white);
	font-family: var(--font-core);
	font-size: var(--fs-body);
	line-height: 1;
	text-decoration: none;
	cursor: pointer;
	box-shadow: var(--shadow-brand);
	transition: var(--t-hover);
}

.woocommerce a.button:hover,
.woocommerce button.button:hover,
.woocommerce input.button:hover,
.woocommerce #respond input#submit:hover {
	border-color: var(--blue-800);
	background: var(--blue-800);
	color: var(--white);
}

.woocommerce a.button:active,
.woocommerce button.button:active,
.woocommerce input.button:active {
	transform: translateY(var(--press-shift));
	box-shadow: none;
}

.woocommerce a.button.disabled,
.woocommerce button.button:disabled,
.woocommerce input.button:disabled {
	opacity: 0.45;
	cursor: not-allowed;
}

/* WooCommerce's own quantity label is redundant beside our stepper. */
.woocommerce .quantity .screen-reader-text {
	position: absolute;
}

/* The star rating font is gone with woocommerce-general; nothing renders one. */
.woocommerce .star-rating {
	display: none;
}

/* Account forms: login, register, lost password, edit address. */
.woocommerce form.login,
.woocommerce form.register,
.woocommerce form.woocommerce-ResetPassword,
.woocommerce form.woocommerce-EditAccountForm,
.woocommerce form.edit-account {
	display: flex;
	flex-direction: column;
	gap: var(--space-4);
	border: var(--border-w) solid var(--border-subtle);
	border-radius: var(--radius-lg);
	background: var(--white);
	max-inline-size: 460px;
	padding: var(--space-6);
	box-shadow: var(--shadow-sm);
}

.woocommerce form .form-row {
	display: flex;
	flex-direction: column;
	gap: var(--space-2);
	margin: 0;
	padding: 0;
}

.woocommerce form .form-row label {
	color: var(--text-heading);
	font-family: var(--font-body);
	font-size: var(--fs-sm);
	font-weight: var(--fw-medium);
}

.woocommerce-form-login__rememberme {
	display: inline-flex;
	align-items: center;
	gap: var(--space-2);
}

.woocommerce-privacy-policy-text,
.woocommerce-form-login__submit + .lost_password,
.woocommerce-LostPassword {
	font-size: var(--fs-sm);
}

/*
 * Signed out, the account page is one centred login card. Registration lives on
 * the club page (woocommerce/myaccount/form-login.php), which the card links to.
 */
.woocommerce-account:not(.logged-in) .kt-page-title {
	text-align: center;
}

.kt-login {
	display: flex;
	flex-direction: column;
	gap: var(--space-5);
	max-inline-size: 460px;
	margin-inline: auto;
}

.kt-login__title {
	margin: 0;
	font-family: var(--font-core);
	font-size: var(--fs-h3);
	text-align: center;
}

.kt-login .woocommerce-form-login__submit {
	inline-size: 100%;
}

.kt-login__join {
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: var(--space-3);
	margin: 0;
	color: var(--text-muted);
	font-size: var(--fs-sm);
	text-align: center;
}

.u-columns.col2-set {
	display: grid;
	grid-template-columns: minmax(0, 1fr);
	gap: var(--space-8);
	max-inline-size: 960px;
}

/* Side by side, each form takes its whole column rather than the 460px cap. */
.u-columns.col2-set form.login,
.u-columns.col2-set form.register {
	max-inline-size: none;
}

.u-columns.col2-set h2 {
	margin: 0 0 var(--space-4);
	font-family: var(--font-core);
	font-size: var(--fs-h3);
}

.woocommerce-form-login__submit,
.woocommerce-form-register__submit {
	align-self: flex-start;
}

@media (min-width: 820px) {

	.u-columns.col2-set {
		grid-template-columns: repeat(2, minmax(0, 1fr));
	}
}

/* ===== src/84-motion.css ===== */

/*
 * Motion.
 *
 * The design system's rules: 120ms for hover, 200ms for a state change, 340ms
 * for an entrance; --ease-out by default and --ease-bounce reserved for the two
 * playful moments (the switch knob and the add-to-cart confirmation). Fades are
 * always paired with a 3-4px translate. Nothing scales up from zero and nothing
 * spins.
 *
 * Everything here is switched off wholesale by the prefers-reduced-motion block
 * in src/00-base.css.
 */

/* --------------------------------------------------------------------------
 * Scroll reveal
 *
 * Sections fade in with a 12px rise as they arrive. Applied by app.js only when
 * IntersectionObserver exists, so without JS everything is simply visible —
 * content is never hidden by a script that might not run.
 * -------------------------------------------------------------------------- */

.kt-js .kt-reveal {
	opacity: 0;
	transform: translateY(12px);
	transition:
		opacity var(--dur-slow) var(--ease-out),
		transform var(--dur-slow) var(--ease-out);
}

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

/* Children stagger slightly, so a grid arrives as a wave rather than a slab. */
.kt-js .kt-reveal--stagger > * {
	opacity: 0;
	transform: translateY(12px);
	transition:
		opacity var(--dur-slow) var(--ease-out),
		transform var(--dur-slow) var(--ease-out);
}

.kt-js .kt-reveal--stagger.is-visible > * {
	opacity: 1;
	transform: none;
}

.kt-js .kt-reveal--stagger.is-visible > :nth-child(2) { transition-delay: 60ms; }
.kt-js .kt-reveal--stagger.is-visible > :nth-child(3) { transition-delay: 120ms; }
.kt-js .kt-reveal--stagger.is-visible > :nth-child(4) { transition-delay: 180ms; }
.kt-js .kt-reveal--stagger.is-visible > :nth-child(5) { transition-delay: 240ms; }
.kt-js .kt-reveal--stagger.is-visible > :nth-child(6) { transition-delay: 300ms; }

/* --------------------------------------------------------------------------
 * Cart badge
 *
 * One of the two moments the design system allows --ease-bounce. The count
 * changing is the only confirmation a customer gets on a listing page, so it has
 * to be noticed.
 * -------------------------------------------------------------------------- */

@keyframes kt-badge-pop {

	0% {
		transform: scale(1);
	}

	45% {
		transform: scale(1.45);
	}

	100% {
		transform: scale(1);
	}
}

.kt-cart-count.is-bumped {
	animation: kt-badge-pop var(--dur-slow) var(--ease-bounce);
}

/* --------------------------------------------------------------------------
 * Product media
 *
 * The card itself already lifts 4px. A slow, small zoom on the photograph adds
 * the sense of depth the design system asks for without the card moving twice.
 * -------------------------------------------------------------------------- */

.kt-product__media img {
	transition: transform var(--dur-slow) var(--ease-out);
}

.kt-product:hover .kt-product__media img,
.kt-product:focus-within .kt-product__media img {
	transform: scale(1.04);
}

/* --------------------------------------------------------------------------
 * Dialogs and sheets
 * -------------------------------------------------------------------------- */

@keyframes kt-fade-in {

	from {
		opacity: 0;
	}

	to {
		opacity: 1;
	}
}

@keyframes kt-rise-in {

	from {
		opacity: 0;
		transform: translateY(12px);
	}

	to {
		opacity: 1;
		transform: none;
	}
}

@keyframes kt-sheet-up {

	from {
		transform: translateY(100%);
	}

	to {
		transform: none;
	}
}

.kt-drawer__scrim,
.kt-dialog__scrim {
	animation: kt-fade-in var(--dur-base) var(--ease-out);
}

.kt-dialog__panel {
	animation: kt-rise-in var(--dur-base) var(--ease-out);
}

@media (max-width: 819px) {

	.kt-shop__filters.is-open {
		animation: kt-sheet-up var(--dur-slow) var(--ease-out);
	}
}

/* The header search panel drops in rather than appearing. */
.kt-header__search {
	animation: kt-rise-in var(--dur-base) var(--ease-out);
}

/* Anything that moves under the pointer should say so. */
.kt-btn,
.kt-icon-btn,
.kt-tag,
.kt-size,
.kt-swatch,
.kt-circle,
.kt-tile,
.kt-card--interactive,
.kt-product {
	-webkit-tap-highlight-color: transparent;
}

.kt-icon-btn:active,
.kt-size:active,
.kt-swatch:active,
.kt-banner__cta:active {
	transform: translateY(var(--press-shift));
}

/* ===== src/86-pages.css ===== */

/*
 * Home sections and content pages.
 */

.kt-page-title {
	margin-block: var(--space-4) var(--space-6);
	font-family: var(--font-core);
	font-size: var(--fs-h1);
}

/* --------------------------------------------------------------------------
 * Home
 * -------------------------------------------------------------------------- */

.kt-home-circles {
	padding-block: var(--space-6);
}

.kt-home-club__card {
	flex-wrap: wrap;
	gap: var(--space-4);
}

.kt-home-club__card .kt-promo__title {
	display: inline-flex;
	align-items: center;
	gap: var(--space-2);
}

.kt-home-banners .kt-banner + .kt-banner {
	margin-block-start: var(--space-6);
}

.kt-praise__gallery {
	display: grid;
	grid-template-columns: repeat(2, minmax(0, 1fr));
	gap: var(--space-3);
	margin-block-start: var(--space-6);
}

@media (min-width: 820px) {

	.kt-praise__gallery {
		grid-template-columns: repeat(4, minmax(0, 1fr));
		gap: var(--gutter);
	}
}

.kt-praise__gallery img {
	display: block;
	border-radius: var(--radius-lg);
	inline-size: 100%;
	aspect-ratio: 4 / 5;
	object-fit: cover;
	box-shadow: var(--shadow-xs);
}

/* --------------------------------------------------------------------------
 * About and contact
 * -------------------------------------------------------------------------- */

.kt-about,
.kt-contact-layout {
	display: grid;
	grid-template-columns: minmax(0, 1fr);
	gap: var(--space-8);
	align-items: start;
}

@media (min-width: 820px) {

	.kt-about,
	.kt-contact-layout {
		grid-template-columns: minmax(0, 1fr) 320px;
		gap: var(--space-10);
	}
}

.kt-about__card {
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	gap: var(--space-4);
}

.kt-about__mark {
	border-radius: var(--radius-pill);
	background: var(--white);
	padding: var(--space-2);
}

.kt-about__cardtitle {
	margin: 0;
	font-family: var(--font-core);
	font-size: var(--fs-h3);
}

/* The store block is styled for the dark footer; on a light card it needs ink. */
.kt-about__store {
	color: var(--text-body);
}

.kt-about__store a {
	color: var(--text-link);
	font-size: inherit;
}

.kt-about__store .kt-icon {
	color: var(--cyan-700);
}

.kt-contact-layout__aside {
	display: flex;
	flex-direction: column;
	gap: var(--space-4);
}

/*
 * Click-to-load map. Nothing is requested from Google until the visitor asks.
 */
.kt-contact-map {
	display: flex;
	flex-direction: column;
	gap: var(--space-2);
}

.kt-contact-map iframe {
	border: var(--border-w) solid var(--border-subtle);
	border-radius: var(--radius-lg);
	inline-size: 100%;
	block-size: 260px;
}

.kt-contact-map__load {
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	gap: var(--space-1);
	border: var(--border-w) dashed var(--border-default);
	border-radius: var(--radius-lg);
	background: var(--cyan-100);
	block-size: 260px;
	color: var(--blue-800);
	font-family: var(--font-core);
	cursor: pointer;
	transition: var(--t-hover);
}

.kt-contact-map__load:hover {
	border-color: var(--blue-700);
	background: var(--cyan-200);
}

.kt-contact-map__load small {
	color: var(--text-muted);
	font-family: var(--font-body);
	font-size: var(--fs-xs);
}

.kt-contact-map__link {
	font-size: var(--fs-sm);
}

.kt-contact__intro {
	margin-block-end: var(--space-6);
}

/* --------------------------------------------------------------------------
 * Sizes and club
 * -------------------------------------------------------------------------- */

.kt-sizes-block + .kt-sizes-block {
	margin-block-start: var(--space-10);
}

.kt-sizes-block .kt-section-title {
	margin-block-end: var(--space-4);
}

.kt-club {
	display: grid;
	grid-template-columns: minmax(0, 1fr);
	gap: var(--space-6);
	margin-block-start: var(--space-8);
}

@media (min-width: 820px) {

	.kt-club {
		grid-template-columns: repeat(2, minmax(0, 1fr));
	}
}

.kt-club__panel {
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	gap: var(--space-4);
}

.kt-club__title {
	margin: 0;
	font-family: var(--font-core);
	font-size: var(--fs-h3);
}

.kt-club__list {
	display: flex;
	flex-direction: column;
	gap: var(--space-3);
	margin: 0;
	list-style: none;
	padding: 0;
}

.kt-club__item {
	display: flex;
	align-items: center;
	gap: var(--space-3);
}

.kt-club__item .kt-icon {
	color: var(--cyan-700);
}

.kt-club__rate {
	margin: 0;
	font-family: var(--font-display);
	font-size: var(--fs-h2);
}

.kt-club__note {
	margin: 0;
	opacity: 0.85;
	font-size: var(--fs-sm);
}

.kt-club__text {
	margin: 0;
	color: var(--text-body);
}

.kt-club__join {
	align-items: stretch;
}

.kt-club__join .kt-club__title,
.kt-club__join .kt-club__text,
.kt-club__join .kt-club__status {
	align-self: flex-start;
}

.kt-club__status {
	padding-block: 6px;
	font-size: var(--fs-sm);
}

.kt-club__join .woocommerce-message,
.kt-club__join .woocommerce-info,
.kt-club__join .woocommerce-error {
	margin-block-end: 0;
}

/* The sign-up form the plugin renders. */
.kt-club__form {
	display: flex;
	flex-direction: column;
	gap: var(--space-4);
}

.kt-club__row {
	display: grid;
	grid-template-columns: minmax(0, 1fr);
	gap: var(--space-4);
}

@media (min-width: 560px) {

	.kt-club__row {
		grid-template-columns: repeat(2, minmax(0, 1fr));
	}
}

.kt-club__form .kt-btn {
	align-self: flex-start;
}

.kt-club__form .woocommerce-privacy-policy-text p {
	margin: 0;
	color: var(--text-muted);
	font-size: var(--fs-xs);
}

/* Honeypot: out of the layout and the accessibility tree, still a real field. */
.kt-club__trap {
	position: absolute;
	overflow: hidden;
	clip-path: inset(50%);
	inline-size: 1px;
	block-size: 1px;
}

.kt-club__login {
	margin: 0;
	color: var(--text-muted);
	font-size: var(--fs-sm);
}

/* --------------------------------------------------------------------------
 * Blog and search
 * -------------------------------------------------------------------------- */

.kt-post__head {
	margin-block-end: var(--space-5);
}

.kt-post__meta {
	color: var(--text-muted);
	font-size: var(--fs-sm);
}

.kt-post__media img {
	display: block;
	border-radius: var(--radius-lg);
	inline-size: 100%;
	margin-block-end: var(--space-6);
}

.kt-post__nav {
	display: flex;
	flex-wrap: wrap;
	justify-content: space-between;
	gap: var(--space-3);
	border-block-start: var(--border-w) solid var(--border-subtle);
	margin-block-start: var(--space-10);
	padding-block-start: var(--space-6);
}

.kt-search-results {
	display: flex;
	flex-direction: column;
	gap: var(--space-6);
	margin-block: var(--space-6);
}

.kt-search-result__title {
	margin: 0 0 var(--space-2);
	font-family: var(--font-core);
	font-size: var(--fs-h3);
}

.kt-search-result__title a {
	color: var(--text-heading);
	text-decoration: none;
}

.kt-search-result__title a:hover {
	color: var(--text-link);
}

.kt-search-result__excerpt p {
	margin: 0;
	color: var(--text-body);
}

/* Blog listing on index.php */
.kt-blog-grid {
	display: grid;
	grid-template-columns: minmax(0, 1fr);
	gap: var(--space-6);
}

@media (min-width: 820px) {

	.kt-blog-grid {
		grid-template-columns: repeat(3, minmax(0, 1fr));
		gap: var(--gutter);
	}
}

.kt-blog-card {
	display: flex;
	flex-direction: column;
	gap: var(--space-2);
	padding: var(--space-5);
}

.kt-blog-card__media img {
	display: block;
	border-radius: var(--radius-md);
	inline-size: 100%;
	aspect-ratio: 4 / 3;
	object-fit: cover;
	margin-block-end: var(--space-2);
}

.kt-blog-card__title {
	margin: 0;
	font-family: var(--font-core);
	font-size: var(--fs-lg);
}

.kt-blog-card__title a {
	color: var(--text-heading);
	text-decoration: none;
}

.kt-blog-card__excerpt p {
	margin: 0;
	color: var(--text-body);
	font-size: var(--fs-sm);
}

/* ===== src/88-plugin.css ===== */

/*
 * Front-end styling for what the Ktanim Core plugin renders.
 *
 * The plugin owns the data and the markup's structure; the look stays here, so
 * the two can be versioned separately.
 */

/* --------------------------------------------------------------------------
 * Floating WhatsApp button
 *
 * The design puts it in the corner at 54px, above the mobile action bar. The
 * Accessibility OneTap plugin owns the other corner button — rule 11 says the
 * theme must not fight it, so nothing here touches its positioning.
 * -------------------------------------------------------------------------- */

.ktanim-whatsapp {
	position: fixed;
	inset-inline-start: var(--space-4);
	inset-block-end: var(--space-6);
	z-index: 70;
	display: flex;
	align-items: center;
	justify-content: center;
	border-radius: var(--radius-pill);
	background: #25D366;
	inline-size: 54px;
	block-size: 54px;
	color: var(--white);
	box-shadow: var(--shadow-md);
	transition: var(--t-hover);
}

.ktanim-whatsapp:hover {
	color: var(--white);
	transform: translateY(-3px);
	box-shadow: var(--shadow-lg);
}

/* Clear of the sticky action bar on product and cart screens. */
@media (max-width: 819px) {

	body.single-product .ktanim-whatsapp,
	body.woocommerce-cart .ktanim-whatsapp {
		inset-block-end: 104px;
	}
}

@media (min-width: 820px) {

	.ktanim-whatsapp--mobile {
		display: none;
	}
}

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

.kt-contact {
	max-inline-size: 560px;
}

.kt-contact__form {
	display: flex;
	flex-direction: column;
	gap: var(--space-4);
	border: var(--border-w) solid var(--border-subtle);
	border-radius: var(--radius-lg);
	background: var(--white);
	padding: var(--space-6);
	box-shadow: var(--shadow-sm);
}

.kt-contact__form .kt-btn {
	align-self: flex-start;
}

/*
 * The honeypot. Taken out of the layout and out of the accessibility tree, but
 * still a real, fillable field — a bot that fills every input gives itself away.
 * Not display:none, which some bots specifically skip.
 */
.kt-contact__trap {
	position: absolute;
	overflow: hidden;
	clip-path: inset(50%);
	inline-size: 1px;
	block-size: 1px;
}

.kt-contact .kt-toast {
	margin-block-end: var(--space-4);
}

/* --------------------------------------------------------------------------
 * Testimonials
 * -------------------------------------------------------------------------- */

.kt-testimonials {
	display: grid;
	grid-template-columns: minmax(0, 1fr);
	gap: var(--space-4);
}

@media (min-width: 820px) {

	.kt-testimonials {
		grid-template-columns: repeat(3, minmax(0, 1fr));
		gap: var(--gutter);
	}
}

.kt-testimonial {
	display: flex;
	flex-direction: column;
	gap: var(--space-3);
	margin: 0;
}

.kt-testimonial__text {
	margin: 0;
	color: var(--text-body);
	line-height: var(--lh-body);
}

/*
 * The shop can give a testimonial a face. Where there is none the caption is
 * just the name, exactly as before, so a half-filled section stays even.
 */
.kt-testimonial__by {
	display: flex;
	align-items: center;
	gap: var(--space-3);
	margin-block-start: auto;
}

.kt-testimonial__avatar {
	inline-size: 40px;
	block-size: 40px;
	border-radius: var(--radius-pill);
	object-fit: cover;
}

.kt-testimonial__name {
	color: var(--text-heading);
	font-family: var(--font-core);
	font-size: var(--fs-sm);
}

/* --------------------------------------------------------------------------
 * Size chart
 * -------------------------------------------------------------------------- */

.kt-size-chart {
	inline-size: 100%;
	border-collapse: collapse;
	font-size: var(--fs-sm);
}

.kt-size-chart :is(th, td) {
	border-block-end: var(--border-w) solid var(--border-subtle);
	padding: var(--space-3);
	text-align: start;
	white-space: nowrap;
}

.kt-size-chart th {
	background: var(--cyan-100);
	color: var(--text-heading);
	font-family: var(--font-core);
	font-weight: var(--fw-regular);
}

.kt-size-chart tbody tr:nth-child(even) {
	background: var(--ink-050);
}


/* -------------------------------------------------------------------------- *
 * Rating, reviews, contact actions
 * -------------------------------------------------------------------------- */

.kt-site-main:focus {
	outline: none;
}

.kt-contact__actions {
	display: flex;
	flex-wrap: wrap;
	gap: var(--space-3);
	margin-block-start: var(--space-4);
}

.kt-rating {
	display: inline-flex;
	align-items: center;
	gap: var(--space-2);
	color: inherit;
	font-size: var(--fs-sm);
	text-decoration: none;
}

.kt-rating__stars {
	position: relative;
	display: inline-block;
	color: #d8d3cc;
	letter-spacing: 0.12em;
	line-height: 1;
}

.kt-rating__stars::before {
	content: "★★★★★";
	position: absolute;
	inset-block-start: 0;
	inset-inline-start: 0;
	inline-size: var(--kt-rating, 0%);
	overflow: hidden;
	white-space: nowrap;
	color: #e0a526;
}

.kt-product-reviews {
	margin-block: var(--space-8, 3rem);
}

.kt-product-reviews .commentlist {
	display: grid;
	gap: var(--space-4);
	margin: 0;
	padding: 0;
	list-style: none;
}

.kt-product-reviews .star-rating {
	position: relative;
	display: block;
	inline-size: 5.6em;
	block-size: 1.2em;
	overflow: hidden;
	line-height: 1.2;
}

.kt-product-reviews .star-rating::before {
	content: "★★★★★";
	position: absolute;
	inset-block-start: 0;
	inset-inline-start: 0;
	color: #d8d3cc;
	letter-spacing: 0.12em;
}

.kt-product-reviews .star-rating span {
	position: absolute;
	inset-block-start: 0;
	inset-inline-start: 0;
	block-size: 100%;
	overflow: hidden;
	white-space: nowrap;
	font-size: 0;
}

.kt-product-reviews .star-rating span::before {
	content: "★★★★★";
	position: absolute;
	inset-block-start: 0;
	inset-inline-start: 0;
	color: #e0a526;
	font-size: 1rem;
	letter-spacing: 0.12em;
}

.kt-product-reviews p.stars a {
	position: relative;
	display: inline-block;
	inline-size: 1.4em;
	block-size: 1.4em;
	overflow: hidden;
	color: #e0a526;
	text-indent: -999em;
	white-space: nowrap;
}

.kt-product-reviews p.stars a::before {
	content: "☆";
	position: absolute;
	inset: 0;
	font-size: 1.4em;
	line-height: 1;
	text-align: center;
	text-indent: 0;
}

.kt-product-reviews p.stars:hover a::before,
.kt-product-reviews p.stars.selected a::before {
	content: "★";
}

.kt-product-reviews p.stars a:hover ~ a::before,
.kt-product-reviews p.stars.selected a.active ~ a::before {
	content: "☆";
}

/* Out of stock: a diagonal strike across the colour, a struck-through size. */
.kt-swatch.is-out-of-stock,
.kt-swatch.is-unavailable {
	position: relative;
	opacity: 0.55;
}

.kt-swatch.is-out-of-stock::after,
.kt-swatch.is-unavailable::after {
	content: "";
	position: absolute;
	inset-block-start: 50%;
	inset-inline: -2px;
	block-size: 2px;
	background: var(--ink-900, #0f1a33);
	box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.85);
	transform: rotate(-45deg);
	pointer-events: none;
}

.kt-size.is-out-of-stock,
.kt-size.is-unavailable {
	position: relative;
	opacity: 0.55;
	text-decoration: line-through;
	overflow: hidden;
}

.kt-size.is-out-of-stock::after,
.kt-size.is-unavailable::after {
	content: "";
	position: absolute;
	inset-block-start: 50%;
	inset-inline: 0;
	block-size: 1px;
	background: currentColor;
	transform: rotate(-30deg);
	pointer-events: none;
}

/* Promotion box ----------------------------------------------------------- */
.kt-promo {
	margin-block: var(--space-4, 1rem);
	padding: var(--space-3, 0.75rem) var(--space-4, 1rem);
	border: 1px dashed var(--ink-300, #b8c0d0);
	border-radius: var(--radius-md, 10px);
	background: var(--surface-subtle, rgba(31, 79, 168, 0.05));
	font-size: var(--fs-sm, 0.9rem);
}

.kt-promo__title {
	margin: 0;
	font-weight: 600;
}

.kt-promo__terms {
	margin-block-start: var(--space-2, 0.5rem);
}

.kt-promo__terms summary {
	cursor: pointer;
	color: var(--text-link, #1f4fa8);
}

.kt-promo__terms-body {
	margin-block-start: var(--space-2, 0.5rem);
	color: var(--text-muted, #5a6478);
	line-height: 1.6;
}

/* Product-card photo slider ------------------------------------------------ */
.kt-slider__btn {
	position: absolute;
	inset-block-start: 50%;
	z-index: 2;
	display: flex;
	align-items: center;
	justify-content: center;
	inline-size: 32px;
	block-size: 32px;
	margin-block-start: -16px;
	padding: 0;
	border: 0;
	border-radius: 50%;
	background: rgba(255, 255, 255, 0.9);
	color: var(--ink-900, #0f1a33);
	font-size: 22px;
	line-height: 1;
	cursor: pointer;
	opacity: 0;
	box-shadow: var(--shadow-xs, 0 1px 3px rgba(0, 0, 0, 0.15));
	transition: opacity var(--dur-fast, 0.15s) ease;
}

.kt-slider__btn--prev {
	inset-inline-start: 8px;
}

.kt-slider__btn--next {
	inset-inline-end: 8px;
}

.kt-product__media.has-slider:hover .kt-slider__btn,
.kt-slider__btn:focus-visible {
	opacity: 1;
}

.kt-slider__dots {
	position: absolute;
	inset-block-start: 8px;
	inset-inline: 0;
	z-index: 2;
	display: flex;
	justify-content: center;
	gap: 5px;
	pointer-events: none;
}

.kt-slider__dots i {
	inline-size: 6px;
	block-size: 6px;
	border-radius: 50%;
	background: rgba(255, 255, 255, 0.65);
	box-shadow: 0 0 0 1px rgba(15, 26, 51, 0.2);
}

.kt-slider__dots i.is-on {
	background: #fff;
	box-shadow: 0 0 0 1px rgba(15, 26, 51, 0.55);
}

@media (hover: none) {
	.kt-slider__btn {
		display: none;
	}
}
