/* ══════════════════════════════════════════════════════════════════════════
   VISARO — Shop

   Kein zweites Designsystem. Typografie, Abstände, Buttons, Formularfelder,
   Motion und Fokus kommen aus dem bestehenden System; hier stehen nur die
   Bausteine, die es im Corporate-Bereich nicht gibt: Shop-Header,
   Produktraster, Filter, Warenkorb, Kasse, Konto.

   Shopwelt-Akzent: `[data-world]` am Header setzt `--vis-world-accent`.
   Dadurch kann eine Welt später anders aussehen, ohne dass hier eine zweite
   Regelmenge entsteht.
   ══════════════════════════════════════════════════════════════════════════ */

/* ══ 1 — Shopwelt-Akzent ═════════════════════════════════════════════════

   Zwei Rollen, nicht eine. `--vis-world-accent` trägt Text und Flächen und
   muss deshalb kontrastsicher sein; `--vis-world-signal` ist der hellere
   Marken-Ton für dünne Akzente auf dunklem Grund, wo der kontrastsichere
   zu dunkel wäre. Beide Werte stehen ausschließlich in tokens.css (E20).

   Gesetzt wird an zwei Stellen: am Shopkopf über `data-world` — dort
   genügt es für Kopf und Warenkorbzähler — und am `body`, damit Knöpfe,
   Links und Abschnitte der ganzen Seite denselben Akzent tragen.         */

[data-world="feuerwehr"],
.visaro-world-feuerwehr {
	--vis-world-accent:      var(--vis-world-feuerwehr-strong);
	--vis-world-accent-text: var(--vis-world-feuerwehr-strong);
	--vis-world-signal:      var(--vis-world-feuerwehr);
}

[data-world="verein"],
.visaro-world-vereine {
	--vis-world-accent:      var(--vis-world-verein);
	--vis-world-accent-text: var(--vis-purple-600);
	--vis-world-signal:      var(--vis-purple-400);
}

[data-world="sport"],
.visaro-world-sport {
	--vis-world-accent:      var(--vis-world-sport);
	--vis-world-accent-text: var(--vis-world-sport);
	--vis-world-signal:      var(--vis-world-sport);
}

[data-world="textil"],
.visaro-world-textil {
	--vis-world-accent:      var(--vis-world-textil);
	--vis-world-accent-text: var(--vis-purple-600);
	--vis-world-signal:      var(--vis-purple-400);
}

/* In einer Shopwelt folgen Knöpfe, Links und Fokusringe dem Weltakzent.
   Der VISARO Purple bleibt für übergeordnete VISARO-Hinweise — etwa den
   Rückweg zur Corporate-Seite. */
.visaro-world .visaro-main {
	--vis-accent:      var(--vis-world-accent, var(--vis-purple-500));
	--vis-accent-text: var(--vis-world-accent-text, var(--vis-purple-600));
}

/* ══ 2 — Shop-Header ═════════════════════════════════════════════════════ */

.vis-shophead {
	position: sticky;
	inset-block-start: 0;
	z-index: var(--vis-z-header);

	background: var(--vis-white);
	border-block-end: var(--vis-border-width) solid var(--vis-border);
}

/* Die schmale Zeile darüber: Herkunft links, Rückweg rechts. Sie ist
   bewusst leise — wer im Shop ist, will einkaufen. */
.vis-shophead__top {
	background: var(--vis-ink-950);
	color: var(--vis-ink-300);
}

.vis-shophead__top-inner {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: var(--vis-space-4);

	max-width: var(--vis-container-wide);
	margin-inline: auto;
	padding-inline: var(--vis-gutter);
	min-block-size: var(--vis-shophead-top);
}

.vis-shophead__origin {
	margin: 0;
	font-family: var(--vis-font-mono);
	font-size: var(--vis-fs-label);
	letter-spacing: var(--vis-ls-label);
	text-transform: uppercase;
}

.vis-shophead__back {
	display: inline-flex;
	align-items: center;
	gap: var(--vis-space-2);

	color: var(--vis-ink-300);
	font-size: var(--vis-fs-caption);
	text-decoration: none;

	transition: color var(--vis-duration-ui) var(--vis-ease-out);
}

.vis-shophead__back .vis-icon {
	inline-size: var(--vis-space-4);
	block-size: var(--vis-space-4);
	transition: transform var(--vis-duration-ui) var(--vis-ease-out);
}

.vis-shophead__back:hover { color: var(--vis-white); }
.vis-shophead__back:hover .vis-icon { transform: translateX(var(--vis-nudge)); }

.vis-shophead__inner {
	display: grid;
	grid-template-columns: auto minmax(0, 1fr) auto;
	align-items: center;
	gap: var(--vis-space-8);

	max-width: var(--vis-container-wide);
	margin-inline: auto;
	padding-inline: var(--vis-gutter);
	min-block-size: var(--vis-shophead-height);
}

/* ── Marke ─────────────────────────────────────────────────────────────── */

.vis-shophead__brand {
	display: inline-flex;
	align-items: center;
	gap: var(--vis-space-3);

	color: inherit;
	text-decoration: none;
}

.vis-shophead__name {
	font-size: var(--vis-fs-h4);
	font-weight: var(--vis-fw-bold);
	letter-spacing: var(--vis-ls-heading);
	white-space: nowrap;
}

/* ── Kategorien ────────────────────────────────────────────────────────── */

.vis-shophead__list {
	display: flex;
	flex-wrap: wrap;
	gap: var(--vis-space-1);
	margin: 0;
	padding: 0;
	list-style: none;

	/* Die Navigation füllt die Kopfhöhe (align-self: stretch, unten); die
	   einfache Liste muss sich darin selbst mittig stellen, sonst klebt sie
	   oben — gemessen 12 px über der Mitte der Aktionen. */
	block-size: 100%;
	align-items: center;
}

.vis-shophead__link {
	display: inline-flex;
	align-items: center;
	min-block-size: var(--vis-tap-target-min);
	padding-inline: var(--vis-space-3);
	border-radius: var(--vis-radius-sm);

	color: var(--vis-text-2);
	font-size: var(--vis-fs-body-s);
	font-weight: var(--vis-fw-medium);
	text-decoration: none;
	white-space: nowrap;

	transition:
		background-color var(--vis-duration-ui) var(--vis-ease-out),
		color var(--vis-duration-ui) var(--vis-ease-out);
}

.vis-shophead__link:hover {
	background: var(--vis-bg-subtle);
	color: var(--vis-text);
}

/* Getönte Pille für die aktive Kategorie — dieselbe Sprache wie im
   Corporate Header (E25), nur mit dem Akzent der Shopwelt. */
.vis-shophead__link.is-current {
	background: var(--vis-bg-subtle);
	/* Weltfarbe bleibt erkennbar, wird aber mit Navy abgedunkelt: Helle
	   Akzente (Purple, Signalrot) erreichen als Schrift sonst kein AA. */
	color: color-mix(in srgb, var(--vis-world-accent, var(--vis-accent)) 68%, var(--vis-ink-950));
}

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

/* ── Aktionen ──────────────────────────────────────────────────────────── */

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

.vis-shophead__icon {
	position: relative;
	display: inline-flex;
	align-items: center;
	justify-content: center;

	inline-size: var(--vis-tap-target-min);
	block-size: var(--vis-tap-target-min);
	border: 0;
	border-radius: var(--vis-radius-sm);
	background: transparent;

	color: var(--vis-text);
	cursor: pointer;

	transition: background-color var(--vis-duration-ui) var(--vis-ease-out);
}

.vis-shophead__icon:hover { background: var(--vis-bg-subtle); }

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

.vis-shophead__count {
	position: absolute;
	inset-block-start: var(--vis-space-1);
	inset-inline-end: var(--vis-space-1);

	min-inline-size: var(--vis-space-5);
	block-size: var(--vis-space-5);
	padding-inline: var(--vis-space-1);
	border-radius: var(--vis-radius-full);

	display: inline-flex;
	align-items: center;
	justify-content: center;

	background: var(--vis-world-accent, var(--vis-accent));
	color: var(--vis-white);
	font-family: var(--vis-font-mono);
	font-size: var(--vis-fs-label);
	font-variant-numeric: tabular-nums;
	line-height: 1;
}

/* ── Suche ─────────────────────────────────────────────────────────────── */

.vis-shophead__search { position: relative; }

.vis-shophead__searchbox {
	position: absolute;
	inset-block-start: calc(100% + var(--vis-space-2));
	inset-inline-end: 0;
	z-index: var(--vis-z-raised);

	inline-size: min(360px, calc(100vw - var(--vis-space-8)));
	padding: var(--vis-space-4);

	background: var(--vis-white);
	border: var(--vis-border-width) solid var(--vis-border);
	box-shadow: var(--vis-shadow-menu);
}

/* Ohne JavaScript bleibt das Feld sichtbar und benutzbar. Erst das Skript
   klappt es ein — Fortschritt, der nichts kaputt macht, wenn er ausbleibt. */
.js .vis-shophead__search:not(.is-open) .vis-shophead__searchbox { display: none; }

.vis-shopsearch {
	display: grid;
	grid-template-columns: minmax(0, 1fr) auto;
	gap: var(--vis-space-2);
}

.vis-shopsearch__submit {
	display: inline-flex;
	align-items: center;
	justify-content: center;

	inline-size: var(--vis-input-height);
	block-size: var(--vis-input-height);
	border: 0;
	border-radius: var(--vis-radius-sm);

	background: var(--vis-ink-950);
	color: var(--vis-white);
	cursor: pointer;

	transition: background-color var(--vis-duration-ui) var(--vis-ease-out);
}

.vis-shopsearch__submit:hover { background: var(--vis-accent); }

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

/* ── Mobile ────────────────────────────────────────────────────────────── */

.vis-shophead__mobile { display: none; }

@media (max-width: 1023.98px) {
	.vis-shophead__brand,
	.vis-shophead__nav,
	.vis-shophead__actions { display: none; }

	.vis-shophead__inner {
		grid-template-columns: minmax(0, 1fr);
		gap: 0;
	}

	.vis-shophead__mobile {
		display: grid;
		grid-template-columns: var(--vis-tap-target-min) minmax(0, 1fr) var(--vis-tap-target-min);
		align-items: center;
		gap: var(--vis-space-3);
		min-block-size: var(--vis-shophead-height);
	}

	.vis-shophead__mobile-brand {
		display: inline-flex;
		align-items: center;
		gap: var(--vis-space-2);

		justify-self: center;
		color: inherit;
		text-decoration: none;
		min-inline-size: 0;
	}

	/* Auch mobil das vollständige Logo, nur kleiner. Ein halbes Zeichen
	   ist auch auf 375 px ein halbes Zeichen. */
	.vis-shophead__mobile-brand .vis-shophead__logo { block-size: var(--vis-space-5); }

	.vis-shophead__mobile-brand .vis-shophead__name {
		display: block;
		overflow: hidden;
		text-overflow: ellipsis;
		font-size: var(--vis-fs-body);
	}

	.vis-shophead__mobile-end { justify-self: end; }
}

/* ══ 3 — Shop-Drawer ═════════════════════════════════════════════════════ */

.vis-shopdrawer {
	position: fixed;
	inset: 0;
	z-index: var(--vis-z-drawer);
}

.vis-shopdrawer__scrim {
	position: absolute;
	inset: 0;
	background: var(--vis-ink-950);
	opacity: 0;
	transition: opacity var(--vis-duration-content) var(--vis-ease-out);
}

.vis-shopdrawer.is-open .vis-shopdrawer__scrim { opacity: 0.6; }

.vis-shopdrawer__panel {
	position: absolute;
	inset-block: 0;
	inset-inline-start: 0;

	display: flex;
	flex-direction: column;
	inline-size: min(var(--vis-drawer-width), 88vw);

	background: var(--vis-white);
	transform: translateX(-100%);
	transition: transform var(--vis-duration-content) var(--vis-ease-out);
}

.vis-shopdrawer.is-open .vis-shopdrawer__panel { transform: none; }

.vis-shopdrawer__head {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: var(--vis-space-4);

	padding: var(--vis-space-4) var(--vis-space-5);
	border-block-end: var(--vis-border-width) solid var(--vis-border);
}

.vis-shopdrawer__title {
	margin: 0;
	font-family: var(--vis-font-mono);
	font-size: var(--vis-fs-label);
	letter-spacing: var(--vis-ls-label);
	text-transform: uppercase;
}

.vis-shopdrawer__close {
	display: inline-flex;
	align-items: center;
	justify-content: center;

	inline-size: var(--vis-tap-target-min);
	block-size: var(--vis-tap-target-min);
	border: 0;
	background: transparent;
	color: var(--vis-text);
	cursor: pointer;
}

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

.vis-shopdrawer__body {
	flex: 1 1 auto;
	overflow-y: auto;
	padding: var(--vis-space-5);
}

/* Die Suche steht zuerst: Auf dem Handy sucht man häufiger, als man sich
   durch Kategorien tippt. */
.vis-shopdrawer__search { margin-block-end: var(--vis-space-6); }

.vis-shopdrawer__list {
	margin: 0;
	padding: 0;
	list-style: none;
}

.vis-shopdrawer__item {
	display: flex;
	align-items: center;
	gap: var(--vis-space-3);
	justify-content: space-between;

	min-block-size: var(--vis-drawer-row);
	padding-inline: var(--vis-space-2);
	border-block-start: var(--vis-border-width) solid var(--vis-border);

	color: var(--vis-text);
	font-size: var(--vis-fs-body);
	text-decoration: none;
}

.vis-shopdrawer__item .vis-icon {
	inline-size: var(--vis-space-5);
	block-size: var(--vis-space-5);
	color: var(--vis-text-3);
}

.vis-shopdrawer__item.is-current { color: var(--vis-world-accent, var(--vis-accent)); }

.vis-shopdrawer__item:focus-visible {
	outline: var(--vis-focus-width) solid var(--vis-accent);
	outline-offset: calc(var(--vis-focus-offset) * -1);
}

.vis-shopdrawer__count {
	color: var(--vis-text-3);
	font-family: var(--vis-font-mono);
	font-size: var(--vis-fs-label);
	font-variant-numeric: tabular-nums;
}

.vis-shopdrawer__empty {
	margin: 0;
	color: var(--vis-text-2);
	font-size: var(--vis-fs-body-s);
}

.vis-shopdrawer__foot {
	padding: var(--vis-space-4) var(--vis-space-5);
	border-block-start: var(--vis-border-width) solid var(--vis-border);
	background: var(--vis-bg-subtle);
}

@media (min-width: 1024px) {
	.vis-shopdrawer { display: none; }
}

/* ══ 4 — Kopf der Liste ══════════════════════════════════════════════════ */

.vis-shophero {
	padding-block: var(--vis-section-m) var(--vis-space-10);
	background: var(--vis-bg);
}

.vis-shophero__inner,
.vis-catalog__inner,
.vis-pdp__wrap,
.vis-shopfoot__inner {
	max-width: var(--vis-container-wide);
	margin-inline: auto;
	padding-inline: var(--vis-gutter);
}

.vis-shophero__title {
	margin: var(--vis-space-5) 0 0;
	max-inline-size: 20ch;

	font-size: var(--vis-fs-display-l);
	font-weight: var(--vis-fw-bold);
	line-height: var(--vis-lh-display);
	letter-spacing: var(--vis-ls-display);
	text-wrap: balance;
}

.vis-shophero__text {
	margin-block-start: var(--vis-space-5);
	max-inline-size: 62ch;
	color: var(--vis-text-2);
	font-size: var(--vis-fs-body-l);
}

.vis-shophero__subs {
	display: flex;
	flex-wrap: wrap;
	gap: var(--vis-space-3);
	margin-block-start: var(--vis-space-8);
}

/* ══ 5 — Leiste und aktive Filter ════════════════════════════════════════ */

.vis-catalog {
	padding-block-end: var(--vis-section-l);
	background: var(--vis-bg);
}

.vis-catalog__bar {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: space-between;
	gap: var(--vis-space-4);

	padding-block: var(--vis-space-5);
	border-block: var(--vis-border-width) solid var(--vis-border);
}

.vis-catalog__count {
	margin: 0;
	color: var(--vis-text-2);
	font-size: var(--vis-fs-body-s);
}

.vis-catalog__count strong {
	color: var(--vis-text);
	font-variant-numeric: tabular-nums;
}

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

.vis-catalog__filter-open { position: relative; }

/* Ohne Skript gibt es keinen Drawer und damit nichts zu öffnen. `display`
   aus `.vis-btn` schlägt sonst das `hidden`-Attribut. */
.vis-catalog__filter-open[hidden] { display: none; }

.vis-catalog__filter-badge {
	display: inline-flex;
	align-items: center;
	justify-content: center;

	min-inline-size: var(--vis-space-5);
	block-size: var(--vis-space-5);
	border-radius: var(--vis-radius-full);

	background: var(--vis-accent-fill);
	color: var(--vis-white);
	font-family: var(--vis-font-mono);
	font-size: var(--vis-fs-label);
	line-height: 1;
}

@media (min-width: 1024px) {
	.vis-catalog__filter-open { display: none; }
}

/* WooCommerce' Sortierung: eigenes Select, gleiche Optik wie alle anderen
   Formularfelder. */
.woocommerce-ordering select {
	block-size: var(--vis-control-height-sm);
	padding-inline: var(--vis-space-3);
	border: var(--vis-border-width) solid var(--vis-border);
	border-radius: var(--vis-radius-sm);
	background: var(--vis-white);
	color: var(--vis-text);
	font-family: inherit;
	font-size: var(--vis-fs-body-s);
}

.woocommerce-ordering select:focus-visible {
	outline: var(--vis-focus-width) solid var(--vis-accent);
	outline-offset: var(--vis-focus-offset);
}

/* Unter 1024 wird getippt: Knopf und Sortierung auf volle Tippzielhöhe,
   die Sortierung in Fließtextgröße. Unter 16 px zoomt iOS beim Antippen
   in die Seite und bleibt danach dort stehen. */
@media (max-width: 1023.98px) {
	.vis-catalog__filter-open { min-block-size: var(--vis-tap-target-min); }

	.woocommerce-ordering select {
		block-size: var(--vis-tap-target-min);
		font-size: var(--vis-fs-body);
	}
}

.vis-catalog__active {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: var(--vis-space-3);
	padding-block: var(--vis-space-5);
}

.vis-catalog__active-label {
	color: var(--vis-text-3);
	font-family: var(--vis-font-mono);
	font-size: var(--vis-fs-label);
	letter-spacing: var(--vis-ls-label);
	text-transform: uppercase;
}

.vis-chip--remove .vis-icon {
	inline-size: var(--vis-space-4);
	block-size: var(--vis-space-4);
}

.vis-catalog__reset {
	color: var(--vis-text-2);
	font-size: var(--vis-fs-body-s);
	text-decoration: underline;
	text-underline-offset: var(--vis-space-1);
}

.vis-catalog__reset:hover { color: var(--vis-accent); }

/* ══ 6 — Layout aus Filtern und Raster ═══════════════════════════════════ */

.vis-catalog__layout {
	display: grid;
	gap: var(--vis-space-10);
	padding-block-start: var(--vis-space-8);
}

@media (min-width: 1024px) {
	.vis-catalog__layout {
		grid-template-columns: var(--vis-filters-width) minmax(0, 1fr);
		gap: var(--vis-space-12);
		align-items: start;
	}
}

.vis-catalog__main { min-inline-size: 0; }

/* ══ 7 — Filter ══════════════════════════════════════════════════════════

   Ab 1024 eine Seitenspalte, darunter ein Drawer — dasselbe Markup. Eine
   zweite Filterliste nur fürs Handy wäre eine zweite Wahrheit darüber, was
   filterbar ist.

   Den Drawer gibt es nur mit `is-enhanced`, gesetzt von `shop-archive.js`.
   Ohne Skript stehen die Filter auch unter 1024 offen über dem Raster —
   jede Option ist ein Link und funktioniert auch so.                       */

@media (max-width: 1023.98px) {
	/* Beim Schließen wird die Wurzel erst nach dem Ausfahren unsichtbar,
	   beim Öffnen sofort sichtbar. Bis dahin nimmt sie keinen Klick mehr an:
	   ein Tippen auf das ausfahrende Panel löste sonst einen Filter aus. */
	.vis-filters.is-enhanced {
		position: fixed;
		inset: 0;
		z-index: var(--vis-z-drawer);
		visibility: hidden;
		pointer-events: none;
		transition: visibility 0s linear var(--vis-duration-content);
	}

	.vis-filters.is-enhanced.is-open {
		visibility: visible;
		pointer-events: auto;
		transition-delay: 0s;
	}

	.is-enhanced .vis-filters__scrim {
		position: absolute;
		inset: 0;
		background: var(--vis-ink-950);
		opacity: 0;
		transition: opacity var(--vis-duration-content) var(--vis-ease-out);
	}

	.is-enhanced.is-open .vis-filters__scrim { opacity: 0.6; }

	.is-enhanced .vis-filters__panel {
		position: absolute;
		inset-block: 0;
		inset-inline-end: 0;

		display: flex;
		flex-direction: column;
		inline-size: min(var(--vis-drawer-width), 88vw);

		background: var(--vis-white);
		transform: translateX(100%);
		transition: transform var(--vis-duration-content) var(--vis-ease-out);
	}

	.is-enhanced.is-open .vis-filters__panel { transform: none; }

	.is-enhanced .vis-filters__body {
		flex: 1 1 auto;
		overflow-y: auto;
		overscroll-behavior: contain;
		padding: var(--vis-space-5);
	}

	.is-enhanced .vis-filters__head {
		display: flex;
		align-items: center;
		justify-content: space-between;
		padding: var(--vis-space-4) var(--vis-space-5);
		border-block-end: var(--vis-border-width) solid var(--vis-border);
	}

	.is-enhanced .vis-filters__foot {
		display: grid;
		grid-template-columns: repeat(2, minmax(0, 1fr));
		gap: var(--vis-space-3);
		padding: var(--vis-space-4) var(--vis-space-5);
		border-block-start: var(--vis-border-width) solid var(--vis-border);
	}

	/* Ohne Skript: dieselbe Liste wie in der Seitenspalte. Schließen und
	   „Anzeigen" hätten nichts zu tun, die aktiven Filter stehen schon
	   darüber in der Leiste. */
	.vis-filters:not(.is-enhanced) .vis-filters__scrim,
	.vis-filters:not(.is-enhanced) .vis-filters__close,
	.vis-filters:not(.is-enhanced) .vis-filters__apply,
	.vis-filters:not(.is-enhanced) .vis-filters__active { display: none; }

	.vis-filters:not(.is-enhanced) .vis-filters__head { padding-block-end: var(--vis-space-4); }
	.vis-filters:not(.is-enhanced) .vis-filters__foot { margin-block-start: var(--vis-space-6); }
}

@media (min-width: 1024px) {
	.vis-filters__scrim,
	.vis-filters__close,
	.vis-filters__apply { display: none; }

	/* Die Überschrift bleibt: Ohne sie beginnt die Seitenspalte mit dem
	   Wort „Kategorie", und man liest erst beim dritten Eintrag, dass hier
	   gefiltert wird. */
	.vis-filters__head { padding: 0 0 var(--vis-space-4); border: 0; }

	.vis-filters {
		position: sticky;
		inset-block-start: calc(var(--vis-shophead-height) + var(--vis-space-6));
	}

	.vis-filters__foot { margin-block-start: var(--vis-space-6); }
}

.vis-filters__title {
	margin: 0;
	font-family: var(--vis-font-mono);
	font-size: var(--vis-fs-label);
	letter-spacing: var(--vis-ls-label);
	text-transform: uppercase;
}

.vis-filters__close {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	inline-size: var(--vis-tap-target-min);
	block-size: var(--vis-tap-target-min);
	border: 0;
	background: transparent;
	color: var(--vis-text);
	cursor: pointer;
}

.vis-filters__group {
	border-block-start: var(--vis-border-width) solid var(--vis-border);
}

.vis-filters__group:last-of-type {
	border-block-end: var(--vis-border-width) solid var(--vis-border);
}

.vis-filters__group-head {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: var(--vis-space-4);

	min-block-size: var(--vis-tap-target-min);
	cursor: pointer;
	list-style: none;

	font-size: var(--vis-fs-body-s);
	font-weight: var(--vis-fw-medium);
}

.vis-filters__group-head::-webkit-details-marker { display: none; }

.vis-filters__group-head:focus-visible {
	outline: var(--vis-focus-width) solid var(--vis-accent);
	outline-offset: var(--vis-focus-offset);
}

.vis-filters__chevron {
	display: inline-flex;
	color: var(--vis-text-3);
	transition: transform var(--vis-duration-ui) var(--vis-ease-out);
}

.vis-filters__group[open] .vis-filters__chevron { transform: rotate(180deg); }

.vis-filters__list {
	margin: 0 0 var(--vis-space-4);
	padding: 0;
	list-style: none;
}

.vis-filters__option {
	display: grid;
	grid-template-columns: auto minmax(0, 1fr) auto;
	align-items: center;
	gap: var(--vis-space-3);

	min-block-size: var(--vis-tap-target-min);
	padding-inline: var(--vis-space-1);

	color: var(--vis-text-2);
	font-size: var(--vis-fs-body-s);
	text-decoration: none;

	transition: color var(--vis-duration-ui) var(--vis-ease-out);
}

.vis-filters__option:hover { color: var(--vis-text); }

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

/* Das Kästchen ist Dekoration — die Information steckt in aria-current und
   im Text. Niemand muss die Farbe sehen, um den Zustand zu erkennen. */
.vis-filters__box {
	display: inline-flex;
	align-items: center;
	justify-content: center;

	inline-size: var(--vis-space-5);
	block-size: var(--vis-space-5);

	border: var(--vis-border-width-strong) solid var(--vis-border-strong);
	border-radius: var(--vis-radius-xs);
	color: transparent;
}

.vis-filters__box .vis-icon {
	inline-size: var(--vis-space-4);
	block-size: var(--vis-space-4);
}

.vis-filters__option.is-active {
	color: var(--vis-text);
	font-weight: var(--vis-fw-medium);
}

.vis-filters__option.is-active .vis-filters__box {
	border-color: var(--vis-accent);
	background: var(--vis-accent);
	color: var(--vis-white);
}

.vis-filters__count {
	color: var(--vis-text-3);
	font-family: var(--vis-font-mono);
	font-size: var(--vis-fs-label);
	font-variant-numeric: tabular-nums;
}

/* ══ 8 — Produktraster und Produktkarte ══════════════════════════════════ */

ul.products {
	display: grid;
	gap: var(--vis-space-8) var(--vis-space-5);
	margin: 0;
	padding: 0;
	list-style: none;

	/* Feste Spaltenzahl statt `auto-fill`. `minmax()` rechnet mit der
	   Containerbreite und kippte auf dem Handy bei 375 px auf eine einzige
	   Spalte — vier Artikel wurden zu einer langen Reise. Die Zahl gehört
	   zur Gestaltung, nicht zur Rechenkunst. */
	grid-template-columns: repeat(2, minmax(0, 1fr));
}

@media (min-width: 768px) {
	ul.products {
		gap: var(--vis-space-10) var(--vis-space-6);
		grid-template-columns: repeat(3, minmax(0, 1fr));
	}
}

@media (min-width: 1280px) {
	ul.products { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}

.vis-product { min-inline-size: 0; }

.vis-product__inner {
	position: relative;
	display: grid;
	gap: var(--vis-space-4);
	block-size: 100%;
	align-content: start;
}

/* ── Produktbild ──────────────────────────────────────────────────────────

   **Das ganze Produkt muss zu sehen sein.** Bis hierher stand `cover` plus
   ein Hover-Zoom auf 1,04 — beides schneidet. Bei einem Shirt fielen damit
   Ärmel und Saum weg, bei einer Jacke der Kragen, und weil jedes Foto
   anders beschnitten geliefert wird, schnitt es bei jedem Produkt woanders.
   Nebeneinander sah das aus wie vier verschiedene Zoomstufen.

   `contain` plus ein gemeinsamer Innenabstand kehrt das um: Jedes Motiv
   liegt vollständig in derselben Fläche und wirkt dadurch optisch gleich
   groß — der Standard in Mode- und Workwear-Shops, und der einzige, bei
   dem ein Kunde sieht, was er kauft.                                       */

.vis-product__media {
	position: relative;
	display: block;
	overflow: hidden;

	aspect-ratio: var(--vis-product-ratio);
	background: var(--vis-bg-subtle);
}

.vis-product__image {
	inline-size: 100%;
	block-size: 100%;
	display: block;

	object-fit: contain;
	padding: var(--vis-media-pad);
	box-sizing: border-box;
}

/* Die zweite Ansicht beim Überfahren — bei Bekleidung in der Regel der
   Rücken, und dort steht der Ortsname. Als Hintergrundbild statt als
   zweitem `<img>`: Es lädt nur, wo eine Oberfläche es auch verwendet, und
   auf Touch wird es nie angefordert. Kein Skript, ein Übergang.

   `contain` auch hier, und `content-box` als Ursprung, damit die zweite
   Ansicht denselben Rand hat wie die erste. Sonst springt das Produkt beim
   Überfahren eine Spur größer — genau der Effekt, den wir gerade
   abgeschafft haben. */
.vis-product__media::after {
	content: "";
	position: absolute;
	inset: 0;
	padding: var(--vis-media-pad);

	background-image: var(--vis-product-alt, none);
	background-repeat: no-repeat;
	background-size: contain;
	background-position: center;
	background-origin: content-box;

	opacity: 0;
	transition: opacity var(--vis-duration-content) var(--vis-ease-out);
	pointer-events: none;
}

@media (hover: hover) and (pointer: fine) {
	.vis-product__inner:hover .vis-product__media::after { opacity: 1; }
	.vis-product__inner:hover .vis-product__media--alternate .vis-product__image { opacity: 0; }
	.vis-product__media--alternate::after { transition: none; }
}

.vis-product__placeholder {
	display: flex;
	align-items: center;
	justify-content: center;

	inline-size: 100%;
	block-size: 100%;
	padding: var(--vis-space-5);

	color: var(--vis-text-3);
	font-family: var(--vis-font-mono);
	font-size: var(--vis-fs-label);
	letter-spacing: var(--vis-ls-label);
	text-align: center;
}

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

	padding: var(--vis-space-1) var(--vis-space-3);
	background: var(--vis-ink-950);
	color: var(--vis-white);

	font-family: var(--vis-font-mono);
	font-size: var(--vis-fs-label);
	letter-spacing: var(--vis-ls-label);
	text-transform: uppercase;
}

.vis-product__badge--out { background: var(--vis-ink-500); }

/* Der Textteil: Kategorie, Titel, Preis — in dieser Reihenfolge und ohne
   Zwischenraum, der sich dehnt. Der Preis gehört zum Produkt. */
.vis-product__body {
	display: grid;
	gap: var(--vis-space-2);
}

.vis-product__cat {
	margin: 0;
	color: var(--vis-text-3);
	font-family: var(--vis-font-mono);
	font-size: var(--vis-fs-label);
	letter-spacing: var(--vis-ls-label);
	text-transform: uppercase;
}

.vis-product__title {
	margin: 0;
	font-size: var(--vis-fs-body);
	font-weight: var(--vis-fw-medium);
	line-height: var(--vis-lh-snug);
}

.vis-product__link {
	color: inherit;
	text-decoration: none;
}

.vis-product__link::after {
	content: "";
	position: absolute;
	inset: 0;
}

.vis-product__link:focus-visible { outline: none; }

.vis-product__inner:has(.vis-product__link:focus-visible) .vis-product__media {
	outline: var(--vis-focus-width) solid var(--vis-accent);
	outline-offset: var(--vis-focus-offset);
}

/* Preis direkt unter dem Titel, in derselben Textgröße, nur kräftiger.
   Eine eigene große Preiszeile zieht die Karte auseinander. */
.vis-product__price {
	margin: 0;
	color: var(--vis-text);
	font-size: var(--vis-fs-body);
	font-weight: var(--vis-fw-bold);
	font-variant-numeric: tabular-nums;
	line-height: var(--vis-lh-snug);
}

.vis-product__price del {
	margin-inline-end: var(--vis-space-2);
	color: var(--vis-text-3);
	font-weight: var(--vis-fw-regular);
	text-decoration: line-through;
}

.vis-product__price ins {
	text-decoration: none;
	color: var(--vis-accent-text);
}

.vis-product__price .woocommerce-Price-currencySymbol { font-weight: var(--vis-fw-regular); }

.vis-product__foot {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: var(--vis-space-3);
	margin-block-start: var(--vis-space-1);
}

.vis-product__hint {
	color: var(--vis-text-3);
	font-size: var(--vis-fs-caption);
}

.vis-product__arrow {
	display: inline-flex;
	margin-inline-start: auto;
	color: var(--vis-text-3);

	transition:
		color var(--vis-duration-ui) var(--vis-ease-out),
		transform var(--vis-duration-ui) var(--vis-ease-out);
}

.vis-product__arrow .vis-icon {
	inline-size: var(--vis-space-5);
	block-size: var(--vis-space-5);
}

.vis-product__inner:hover .vis-product__arrow,
.vis-product__inner:has(.vis-product__link:focus-visible) .vis-product__arrow {
	color: var(--vis-world-accent, var(--vis-accent));
	transform: translateX(var(--vis-nudge));
}

/* ══ 9 — Leerzustand und Blätterung ══════════════════════════════════════ */

.vis-catalog__empty {
	display: grid;
	gap: var(--vis-space-5);
	justify-items: start;
	max-inline-size: 54ch;
	padding-block: var(--vis-section-s);
}

.vis-catalog__empty-title {
	margin: 0;
	font-size: var(--vis-fs-h2);
	font-weight: var(--vis-fw-bold);
	letter-spacing: var(--vis-ls-heading);
}

.vis-catalog__empty-text {
	margin: 0;
	color: var(--vis-text-2);
	font-size: var(--vis-fs-body-l);
}

.woocommerce-pagination {
	margin-block-start: var(--vis-section-s);
	padding-block-start: var(--vis-space-8);
	border-block-start: var(--vis-border-width) solid var(--vis-border);
}

.woocommerce-pagination ul {
	display: flex;
	flex-wrap: wrap;
	gap: var(--vis-space-2);
	margin: 0;
	padding: 0;
	list-style: none;
}

.woocommerce-pagination a,
.woocommerce-pagination span {
	display: inline-flex;
	align-items: center;
	justify-content: center;

	min-inline-size: var(--vis-tap-target-min);
	block-size: var(--vis-tap-target-min);
	padding-inline: var(--vis-space-3);
	border: var(--vis-border-width) solid var(--vis-border);
	border-radius: var(--vis-radius-sm);

	color: var(--vis-text-2);
	font-size: var(--vis-fs-body-s);
	font-variant-numeric: tabular-nums;
	text-decoration: none;
}

.woocommerce-pagination a:hover { border-color: var(--vis-accent); color: var(--vis-text); }

.woocommerce-pagination .current {
	background: var(--vis-ink-950);
	border-color: var(--vis-ink-950);
	color: var(--vis-white);
}

/* ══ 10 — Meldungen ══════════════════════════════════════════════════════ */

.vis-notice {
	display: grid;
	grid-template-columns: auto minmax(0, 1fr);
	gap: var(--vis-space-3);
	align-items: start;

	margin-block-end: var(--vis-space-5);
	padding: var(--vis-space-4) var(--vis-space-5);

	font-size: var(--vis-fs-body-s);
	line-height: var(--vis-lh-body);
}

.vis-notice__icon { display: inline-flex; }

.vis-notice--success { background: var(--vis-ok-bg); color: var(--vis-ok-text); }
.vis-notice--error   { background: var(--vis-err-bg); color: var(--vis-err-text); }
.vis-notice--info    { background: var(--vis-info-bg); color: var(--vis-info-text); }

.vis-notice a { color: inherit; }

/* ══ 11 — Mengenfeld ═════════════════════════════════════════════════════ */

.vis-qty {
	display: inline-grid;
	grid-template-columns: auto minmax(0, 1fr) auto;
	align-items: center;

	border: var(--vis-border-width) solid var(--vis-border);
	border-radius: var(--vis-radius-sm);
	overflow: hidden;
	background: var(--vis-white);
}

.vis-qty__btn {
	display: inline-flex;
	align-items: center;
	justify-content: center;

	inline-size: var(--vis-qty-height);
	block-size: var(--vis-qty-height);
	border: 0;
	background: transparent;
	color: var(--vis-text);
	cursor: pointer;

	transition: background-color var(--vis-duration-ui) var(--vis-ease-out);
}

.vis-qty__btn:hover { background: var(--vis-bg-subtle); }

.vis-qty__btn:focus-visible {
	outline: var(--vis-focus-width) solid var(--vis-accent);
	outline-offset: calc(var(--vis-focus-offset) * -1);
}

.vis-qty__input {
	inline-size: var(--vis-space-12);
	block-size: var(--vis-qty-height);
	border: 0;
	background: transparent;

	color: var(--vis-text);
	font-family: inherit;
	font-size: var(--vis-fs-body-s);
	font-variant-numeric: tabular-nums;
	text-align: center;
	appearance: textfield;
}

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

.vis-qty__input:focus-visible {
	outline: var(--vis-focus-width) solid var(--vis-accent);
	outline-offset: calc(var(--vis-focus-offset) * -1);
}

/* ══ 12 — Produktseite ═══════════════════════════════════════════════════ */

.vis-pdp__wrap { padding-block: var(--vis-section-m) var(--vis-section-l); }

.vis-pdp__inner {
	display: grid;
	gap: var(--vis-space-10);
}

@media (min-width: 1024px) {
	.vis-pdp__inner {
		grid-template-columns: minmax(0, 1.1fr) minmax(0, 0.9fr);
		gap: var(--vis-space-16);
		align-items: start;
	}

	/* Die rechte Spalte bleibt stehen, solange die Galerie länger ist. Bei
	   fünf Fotos scrollt man sonst an der einzigen Handlung vorbei. */
	.vis-pdp__summary {
		position: sticky;
		inset-block-start: calc(var(--vis-shophead-height) + var(--vis-space-8));
	}
}

.vis-pdp__cat {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: var(--vis-space-3);
	margin: 0;

	color: var(--vis-text-3);
	font-family: var(--vis-font-mono);
	font-size: var(--vis-fs-label);
	letter-spacing: var(--vis-ls-label);
	text-transform: uppercase;
}

.vis-pdp__cat a { color: inherit; text-decoration: none; }
.vis-pdp__cat a:hover { color: var(--vis-accent); }

.vis-pdp__world { color: var(--vis-world-accent, var(--vis-accent)); }

.vis-pdp__title {
	margin: var(--vis-space-4) 0 0;
	max-inline-size: 22ch;

	font-size: var(--vis-fs-h1);
	font-weight: var(--vis-fw-bold);
	line-height: var(--vis-lh-heading);
	letter-spacing: var(--vis-ls-display);
	text-wrap: balance;
}

.vis-pdp__lead {
	margin-block-start: var(--vis-space-5);
	max-inline-size: 54ch;
	color: var(--vis-text-2);
	font-size: var(--vis-fs-body-l);
	line-height: var(--vis-lh-body);
}

.vis-pdp__price {
	margin-block-start: var(--vis-space-6);
	font-size: var(--vis-fs-h3);
	font-weight: var(--vis-fw-bold);
	font-variant-numeric: tabular-nums;
}

.vis-pdp__price del { color: var(--vis-text-3); font-weight: var(--vis-fw-regular); }
.vis-pdp__price ins { text-decoration: none; color: var(--vis-accent-text); }

.vis-pdp__price .woocommerce-Price-currencySymbol { font-weight: var(--vis-fw-regular); }

/* ── Varianten und Warenkorb ───────────────────────────────────────────── */

.vis-pdp .variations {
	inline-size: 100%;
	margin-block: var(--vis-space-6);
	border-collapse: collapse;
}

.vis-pdp .variations th,
.vis-pdp .variations td {
	display: block;
	padding: 0;
	text-align: start;
}

.vis-pdp .variations th {
	margin-block-end: var(--vis-space-2);
	color: var(--vis-text-2);
	font-family: var(--vis-font-mono);
	font-size: var(--vis-fs-label);
	font-weight: var(--vis-fw-medium);
	letter-spacing: var(--vis-ls-label);
	text-transform: uppercase;
}

.vis-pdp .variations td { margin-block-end: var(--vis-space-5); }

.vis-pdp .variations select {
	inline-size: 100%;
	block-size: var(--vis-control-height);
	padding-inline: var(--vis-space-4);
	border: var(--vis-border-width) solid var(--vis-border);
	border-radius: var(--vis-radius-sm);
	background: var(--vis-white);
	color: var(--vis-text);
	font-family: inherit;
	font-size: var(--vis-fs-body);
}

.vis-pdp .variations select:focus-visible {
	outline: var(--vis-focus-width) solid var(--vis-accent);
	outline-offset: var(--vis-focus-offset);
}

/* Die Auswahlliste bleibt im Markup und bleibt die Wahrheit; sichtbar sind
   die Knöpfe daneben (E77). `shop-product.js` hängt ihr dafür
   `screen-reader-text` an — und dort steht `width: 1px`.

   Die Regel darüber ist spezifischer und gewann: Die Liste blieb 371 px
   breit, absolut positioniert, und schob das Dokument bei 390 px um
   23 px nach rechts. Auf dem Handy war das ein waagrechter Balken unter
   jeder Produktseite, den niemand einem Auswahlfeld zugeordnet hätte.  */
.vis-pdp .variations select.screen-reader-text {
	inline-size: 1px;
	block-size: 1px;
	padding: 0;
	border: 0;
}

.vis-pdp .reset_variations {
	display: inline-block;
	margin-block-start: var(--vis-space-2);
	color: var(--vis-text-2);
	font-size: var(--vis-fs-caption);
}

.vis-pdp form.cart {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: var(--vis-space-4);
	margin-block-start: var(--vis-space-6);
}

.vis-pdp form.variations_form { display: block; }

.vis-pdp .single_add_to_cart_button {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: var(--vis-space-2);

	min-block-size: var(--vis-control-height-lg);
	padding-inline: var(--vis-space-8);
	border: 0;
	border-radius: var(--vis-radius-sm);

	background: var(--vis-accent-fill);
	color: var(--vis-white);
	font-family: inherit;
	font-size: var(--vis-fs-body);
	font-weight: var(--vis-fw-medium);
	cursor: pointer;

	transition: background-color var(--vis-duration-ui) var(--vis-ease-out);
}

.vis-pdp .single_add_to_cart_button:hover { background: var(--vis-purple-700); }

.vis-pdp .single_add_to_cart_button:focus-visible {
	outline: var(--vis-focus-width) solid var(--vis-accent);
	outline-offset: var(--vis-focus-offset);
}

.vis-pdp .single_add_to_cart_button.disabled {
	background: var(--vis-ink-200);
	color: var(--vis-text-disabled);
	cursor: not-allowed;
}

.vis-pdp .woocommerce-variation-price {
	margin-block-end: var(--vis-space-4);
	font-size: var(--vis-fs-h4);
	font-weight: var(--vis-fw-bold);
}

.vis-pdp__meta {
	display: grid;
	gap: 0;
	margin-block-start: var(--vis-space-8);
}

.vis-pdp__meta > div {
	display: grid;
	grid-template-columns: minmax(0, 1fr) minmax(0, 1.4fr);
	gap: var(--vis-space-4);

	padding-block: var(--vis-space-3);
	border-block-start: var(--vis-border-width) solid var(--vis-border);
	font-size: var(--vis-fs-body-s);
}

.vis-pdp__meta dt { color: var(--vis-text-3); }
.vis-pdp__meta dd { margin: 0; }

.vis-pdp__ask { margin-block-start: var(--vis-space-6); }

/* ── Galerie ───────────────────────────────────────────────────────────── */

.vis-pdp .woocommerce-product-gallery { position: relative; }

.vis-pdp .woocommerce-product-gallery__wrapper {
	margin: 0;
	overflow: hidden;
	background: var(--vis-bg-subtle);
}

.vis-pdp .woocommerce-product-gallery__image img {
	inline-size: 100%;
	block-size: auto;
	display: block;
}

.vis-pdp .flex-control-thumbs {
	display: grid;
	grid-template-columns: repeat(4, minmax(0, 1fr));
	gap: var(--vis-space-3);

	margin: var(--vis-space-4) 0 0;
	padding: 0;
	list-style: none;
}

.vis-pdp .flex-control-thumbs li { margin: 0; }

.vis-pdp .flex-control-thumbs img {
	inline-size: 100%;
	aspect-ratio: var(--vis-product-ratio);
	object-fit: cover;
	display: block;
	cursor: pointer;

	border: var(--vis-border-width) solid transparent;
	opacity: 0.7;
	transition: opacity var(--vis-duration-ui) var(--vis-ease-out);
}

.vis-pdp .flex-control-thumbs img:hover,
.vis-pdp .flex-control-thumbs img.flex-active {
	opacity: 1;
	border-color: var(--vis-accent);
}

.vis-pdp .woocommerce-product-gallery__trigger {
	position: absolute;
	inset-block-start: var(--vis-space-4);
	inset-inline-end: var(--vis-space-4);
	z-index: var(--vis-z-raised);
}

/* ── Beschreibung und ähnliche Produkte ────────────────────────────────── */

.vis-pdp__detail {
	margin-block-start: var(--vis-section-l);
	padding-block-start: var(--vis-section-s);
	border-block-start: var(--vis-border-width) solid var(--vis-border);
}

.vis-pdp__detail-inner {
	display: grid;
	gap: var(--vis-space-12);
}

@media (min-width: 1024px) {
	.vis-pdp__detail-inner {
		grid-template-columns: minmax(0, 1.4fr) minmax(0, 1fr);
		gap: var(--vis-space-16);
		align-items: start;
	}
}

.vis-pdp__section-title {
	margin: 0 0 var(--vis-space-5);
	font-size: var(--vis-fs-h3);
	font-weight: var(--vis-fw-bold);
	letter-spacing: var(--vis-ls-heading);
}

.vis-pdp__prose {
	max-inline-size: 68ch;
	color: var(--vis-text-2);
	font-size: var(--vis-fs-body);
	line-height: var(--vis-lh-body);
}

.vis-pdp__prose > * + * { margin-block-start: var(--vis-space-4); }

.vis-pdp .woocommerce-product-attributes {
	inline-size: 100%;
	border-collapse: collapse;
}

.vis-pdp .woocommerce-product-attributes th,
.vis-pdp .woocommerce-product-attributes td {
	padding-block: var(--vis-space-3);
	border-block-start: var(--vis-border-width) solid var(--vis-border);
	font-size: var(--vis-fs-body-s);
	text-align: start;
	vertical-align: top;
}

.vis-pdp .woocommerce-product-attributes th {
	inline-size: 40%;
	color: var(--vis-text-3);
	font-weight: var(--vis-fw-regular);
}

.vis-pdp .woocommerce-product-attributes p { margin: 0; }

.related.products,
.up-sells.products {
	margin-block-start: var(--vis-section-l);
	padding-block-start: var(--vis-section-s);
	border-block-start: var(--vis-border-width) solid var(--vis-border);
}

.related.products > h2,
.up-sells.products > h2 {
	margin: 0 0 var(--vis-space-8);
	font-size: var(--vis-fs-h2);
	font-weight: var(--vis-fw-bold);
	letter-spacing: var(--vis-ls-heading);
}

/* ══ 13 — Warenkorb ══════════════════════════════════════════════════════

   Der Warenkorb steht vollständig im Abschnitt „WARENKORB — UNIVERSELL"
   weiter unten. Hier stand bis zur Warenkorb-Phase eine ältere Fassung
   aus Phase 11 (`.vis-cartitem`) — eine zweite Kartendarstellung
   derselben Sache. Sie ist entfallen, als Warenkorbseite und Drawer
   denselben Baustein bekamen.                                            */

/* ══ 14 — Kasse ══════════════════════════════════════════════════════════ */

/* Im Checkout gibt es eine sinnvolle Handlung. Kategorien und Suche wären
   nur Ausgänge — der Rückweg zum Warenkorb bleibt über den Browser. */
.visaro-checkout .vis-shophead__nav,
.visaro-checkout .vis-shophead__search,
.visaro-checkout .vis-shophead__mobile-start { visibility: hidden; }

.vis-checkout__grid {
	display: grid;
	gap: var(--vis-space-10);
}

@media (min-width: 1024px) {
	.vis-checkout__grid {
		grid-template-columns: minmax(0, 1.3fr) minmax(0, 1fr);
		gap: var(--vis-space-16);
		align-items: start;
	}

	.vis-checkout__aside {
		position: sticky;
		inset-block-start: calc(var(--vis-shophead-height) + var(--vis-space-8));
	}
}

.vis-checkout__block + .vis-checkout__block { margin-block-start: var(--vis-section-s); }

.vis-checkout__title {
	margin: 0 0 var(--vis-space-6);
	font-size: var(--vis-fs-h3);
	font-weight: var(--vis-fw-bold);
	letter-spacing: var(--vis-ls-heading);
}

.vis-checkout__summary {
	padding: var(--vis-space-8);
	background: var(--vis-bg-subtle);
	border: var(--vis-border-width) solid var(--vis-border);
}

/* Auf dem Telefon frisst der Innenabstand von 32 px je Seite rund ein
   Fünftel der Breite — genau dort, wo Produktnamen, Beträge und die
   Zahlungsarten Platz brauchen. Dieselbe Stufe wie die Warenkorbkarte. */
@media (max-width: 599.98px) {
	.vis-checkout__summary { padding: var(--vis-space-5) var(--vis-space-4); }
}

.woocommerce-billing-fields__field-wrapper,
.woocommerce-shipping-fields__field-wrapper,
.woocommerce-additional-fields__field-wrapper {
	display: grid;
	gap: var(--vis-space-5);
}

@media (min-width: 768px) {
	.woocommerce-billing-fields__field-wrapper,
	.woocommerce-shipping-fields__field-wrapper {
		grid-template-columns: repeat(2, minmax(0, 1fr));
	}

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

.woocommerce form .form-row { margin: 0; }

/* Beschriftungen in 15 px statt 13 px — dieselbe Größe wie im Shopkonto
   (`.vis-field label`). Bei zehn Adressfeldern untereinander ist die
   Beschriftung das, was man liest; das Feld darunter ist leer. */
.woocommerce form .form-row label {
	display: block;
	margin-block-end: var(--vis-space-2);
	color: var(--vis-text-2);
	font-size: var(--vis-fs-body-s);
	font-weight: var(--vis-fw-medium);
}

.woocommerce form .form-row input.input-text,
.woocommerce form .form-row textarea,
.woocommerce form .form-row select,
.woocommerce form .form-row .select2-selection {
	inline-size: 100%;
	min-block-size: var(--vis-input-height);
	padding: var(--vis-space-3) var(--vis-space-4);

	border: var(--vis-border-width) solid var(--vis-border);
	border-radius: var(--vis-radius-sm);
	background: var(--vis-white);

	color: var(--vis-text);
	font-family: inherit;
	font-size: var(--vis-fs-body);
}

.woocommerce form .form-row input.input-text:focus-visible,
.woocommerce form .form-row textarea:focus-visible,
.woocommerce form .form-row select:focus-visible {
	outline: var(--vis-focus-width) solid var(--vis-accent);
	outline-offset: var(--vis-focus-offset);
}

.woocommerce form .form-row.woocommerce-invalid input.input-text,
.woocommerce form .form-row.woocommerce-invalid select {
	border-color: var(--vis-err);
}

.woocommerce form .form-row textarea { min-block-size: var(--vis-space-24); }

.woocommerce-terms-and-conditions-wrapper { margin-block: var(--vis-space-6); }

#payment .wc_payment_methods {
	margin: 0 0 var(--vis-space-6);
	padding: 0;
	list-style: none;
}

#payment .wc_payment_method {
	padding-block: var(--vis-space-4);
	border-block-start: var(--vis-border-width) solid var(--vis-border);
}

#payment .payment_box {
	margin-block-start: var(--vis-space-3);
	padding: var(--vis-space-4);
	background: var(--vis-white);
	font-size: var(--vis-fs-body-s);
}

.woocommerce-checkout #payment { background: transparent; }
.woocommerce-checkout #payment ul.payment_methods { padding: 0; border-bottom: 0; }
.woocommerce-checkout #payment ul.payment_methods li { padding: 16px 0; }
.woocommerce-checkout #payment ul.payment_methods li > label { cursor: pointer; font-weight: 600; }
.woocommerce-checkout #payment div.payment_box { background: var(--vis-white); border: 1px solid var(--vis-border); color: var(--vis-text-2); }
.woocommerce-checkout #payment div.payment_box::before { display: none; }
.woocommerce-checkout #payment div.form-row { padding-inline: 0; }

#place_order {
	inline-size: 100%;
	min-block-size: var(--vis-control-height-lg);
	border: 0;
	border-radius: var(--vis-radius-sm);

	background: var(--vis-accent);
	color: var(--vis-white);
	font-family: inherit;
	font-size: var(--vis-fs-body);
	font-weight: var(--vis-fw-medium);
	cursor: pointer;

	transition: background-color var(--vis-duration-ui) var(--vis-ease-out);
}

#place_order:hover { background: var(--vis-purple-600); }

#place_order:focus-visible {
	outline: var(--vis-focus-width) solid var(--vis-accent);
	outline-offset: var(--vis-focus-offset);
}

/* Das Suchfeld im Länder-/Bundeslandauswahl (Select2). Select2 hängt
   seine Liste an `body`, außerhalb jedes Formulars — die Feldregel oben
   erreicht es nicht, und ohne Angabe nimmt der Browser seine
   Standardgröße von rund 13 px. Auf iOS zoomt das die Kasse beim
   Antippen heran. */
.select2-dropdown .select2-search__field { font-size: var(--vis-fs-body); }

/* ══ 15 — Shopkonto ══════════════════════════════════════════════════════

   **Das Konto hat seine eigene Datei** (`account.css`, nur dort geladen).

   Hier stand das Kontoraster auf `.woocommerce-account .woocommerce` —
   also auf einem **fremden Element**. Das war die Ursache der vertauschten
   Spalten: `woocommerce.css` gibt genau diesem Element einen Clearfix, und
   `::before`/`::after` sind in einem Grid keine Dekoration, sondern
   Grid-Items. Die Navigation landete in der breiten Spalte, der Inhalt in
   der schmalen, eine Zeile tiefer.

   Ebenso stand hier eine Regel für `.woocommerce-form-login button` — für
   **jeden** Knopf im Anmeldeformular. Getroffen hat sie auch den
   Passwort-Umschalter, den WooCommerce per JavaScript ohne Text einfügt:
   der leere lila Knopf aus den Bildschirmfotos.

   Beides ist entfernt und in `account.css` neu aufgebaut, dort auf
   **eigenen** Klassen. Die Reste, die das Konto mit dem übrigen Shop
   teilt (Tabellen, Meldungen), bleiben unten stehen. */

.woocommerce-orders-table,
.woocommerce-table {
	inline-size: 100%;
	border-collapse: collapse;
	font-size: var(--vis-fs-body-s);
}

.woocommerce-orders-table th,
.woocommerce-orders-table td,
.woocommerce-table th,
.woocommerce-table td {
	padding-block: var(--vis-space-4);
	border-block-start: var(--vis-border-width) solid var(--vis-border);
	text-align: start;
}

/* Auf schmalen Bildschirmen wird aus jeder Zeile ein Block. WooCommerce
   liefert die Spaltenüberschrift in `data-title` mit — genau dafür. */
@media (max-width: 767.98px) {
	.woocommerce-orders-table thead { display: none; }

	.woocommerce-orders-table tr {
		display: grid;
		gap: var(--vis-space-2);
		padding-block: var(--vis-space-5);
		border-block-start: var(--vis-border-width) solid var(--vis-border);
	}

	.woocommerce-orders-table td {
		display: grid;
		grid-template-columns: minmax(0, 1fr) auto;
		gap: var(--vis-space-4);
		padding: 0;
		border: 0;
	}

	.woocommerce-orders-table td::before {
		content: attr(data-title);
		color: var(--vis-text-3);
		font-family: var(--vis-font-mono);
		font-size: var(--vis-fs-label);
		letter-spacing: var(--vis-ls-label);
		text-transform: uppercase;
	}
}

/* ══ 16 — Shop-Footer ════════════════════════════════════════════════════ */

.vis-shopfoot {
	padding-block: var(--vis-section-m);
	background: var(--vis-ink-950);
	color: var(--vis-white);

	--vis-text:   var(--vis-white);
	--vis-text-2: var(--vis-ink-300);
	--vis-text-3: var(--vis-ink-400);
	--vis-border: var(--vis-ink-800);
}

.vis-shopfoot__cols {
	display: grid;
	gap: var(--vis-space-10);
}

@media (min-width: 768px) {
	.vis-shopfoot__cols { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--vis-space-12); }
}

.vis-shopfoot__help {
	display: grid;
	gap: 0;
	margin: var(--vis-space-5) 0 0;
}

.vis-shopfoot__help > div {
	padding-block: var(--vis-space-4);
	border-block-start: var(--vis-border-width) solid var(--vis-border);
}

.vis-shopfoot__help dt {
	margin-block-end: var(--vis-space-1);
	font-size: var(--vis-fs-body-s);
	font-weight: var(--vis-fw-medium);
}

.vis-shopfoot__help dd {
	margin: 0;
	color: var(--vis-text-2);
	font-size: var(--vis-fs-caption);
	line-height: var(--vis-lh-snug);
}

.vis-shopfoot__lead {
	margin: var(--vis-space-5) 0 0;
	max-inline-size: 40ch;
	color: var(--vis-text-2);
	font-size: var(--vis-fs-body-s);
	line-height: var(--vis-lh-body);
}

.vis-shopfoot__contact {
	display: grid;
	gap: var(--vis-space-3);
	margin: var(--vis-space-5) 0 0;
	padding: 0;
	list-style: none;
}

.vis-shopfoot__contact a {
	display: inline-flex;
	align-items: center;
	gap: var(--vis-space-3);
	color: var(--vis-white);
	font-size: var(--vis-fs-body-s);
	text-decoration: none;
}

.vis-shopfoot__contact a:hover { color: var(--vis-purple-400); }

.vis-shopfoot__contact .vis-icon {
	inline-size: var(--vis-space-5);
	block-size: var(--vis-space-5);
	color: var(--vis-text-3);
}

.vis-shopfoot__link {
	display: inline-flex;
	align-items: center;
	gap: var(--vis-space-2);
	margin-block-start: var(--vis-space-5);

	color: var(--vis-purple-400);
	font-size: var(--vis-fs-body-s);
	font-weight: var(--vis-fw-medium);
	text-decoration: none;

	transition: transform var(--vis-duration-ui) var(--vis-ease-out);
}

.vis-shopfoot__link .vis-icon {
	inline-size: var(--vis-space-4);
	block-size: var(--vis-space-4);
	transition: transform var(--vis-duration-ui) var(--vis-ease-out);
}

.vis-shopfoot__link:hover .vis-icon { transform: translateX(var(--vis-nudge)); }

.vis-shopfoot__legal {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: space-between;
	gap: var(--vis-space-4);

	margin-block-start: var(--vis-section-s);
	padding-block-start: var(--vis-space-6);
	border-block-start: var(--vis-border-width) solid var(--vis-border);
}

.vis-shopfoot__copy {
	margin: 0;
	color: var(--vis-text-3);
	font-size: var(--vis-fs-caption);
}

.vis-shopfoot__legal-links {
	display: flex;
	flex-wrap: wrap;
	gap: var(--vis-space-5);
	margin: 0;
	padding: 0;
	list-style: none;
}

.vis-shopfoot__legal-links a {
	color: var(--vis-text-3);
	font-size: var(--vis-fs-caption);
	text-decoration: none;
}

.vis-shopfoot__legal-links a:hover { color: var(--vis-white); }
.vis-shopfoot__legal-links .is-featured a { color: var(--vis-white); font-weight: 650; text-decoration: underline; text-decoration-thickness: 2px; text-underline-offset: 4px; }

/* ══ 17 — Reduzierte Bewegung ════════════════════════════════════════════ */

@media (prefers-reduced-motion: reduce) {
	.vis-product__image,
	.vis-shopdrawer__panel,
	.vis-shopdrawer__scrim,
	.is-enhanced .vis-filters__panel,
	.is-enhanced .vis-filters__scrim,
	.vis-filters__chevron {
		transition: none;
		transform: none;
	}

	.vis-product__inner:hover .vis-product__image { transform: none; }

	.vis-product__arrow,
	.vis-shophead__back .vis-icon,
	.vis-shopfoot__link .vis-icon {
		transition: color var(--vis-duration-ui) var(--vis-ease-out);
	}

	.vis-product__inner:hover .vis-product__arrow,
	.vis-shophead__back:hover .vis-icon,
	.vis-shopfoot__link:hover .vis-icon { transform: none; }

	.vis-shopdrawer.is-open .vis-shopdrawer__panel,
	.vis-filters.is-open .vis-filters__panel { transform: none; }
}

/* ── Nachträge ─────────────────────────────────────────────────────────── */

/* Im Fuß des Drawers steht das Symbol vor dem Wort — dort ist nichts
   auszurichten, was rechts stehen müsste. */
.vis-shopdrawer__foot .vis-shopdrawer__item {
	justify-content: flex-start;
	border-block-start: 0;
}

/* Strukturhüllen. Sie tragen keine eigene Gestaltung, brauchen im Raster
   aber die Erlaubnis zu schrumpfen — ohne `min-inline-size: 0` sprengt ein
   langer Produktname oder eine breite Tabelle die Spalte. */
.vis-checkout__fields,
.vis-checkout__review,
.vis-account__nav,
.vis-cart__form,
.vis-shopfoot__col,
.vis-pdp__media,
.vis-pdp__specs { min-inline-size: 0; }

.vis-shopsearch__input { min-inline-size: 0; }

/* Der Zähler ist versteckt, solange der Warenkorb leer ist. `display` aus
   der Komponentenregel schlägt sonst das `hidden`-Attribut. */
.vis-shophead__count[hidden] { display: none; }

/* Die Sortierung darf schrumpfen. Ohne diese drei Zeilen schob das breiteste
   Optionswort („Nach Durchschnittsbewertung sortiert") die Leiste bei 375 px
   um rund 60 px über den Rand hinaus. */
.vis-catalog__tools {
	flex-wrap: wrap;
	min-inline-size: 0;
}

.woocommerce-ordering {
	min-inline-size: 0;
	max-inline-size: 100%;
}

.woocommerce-ordering select { max-inline-size: 100%; }

/* Das geschlossene Filterpanel steht als `translateX(100%)` neben dem
   Sichtfeld und zählte zur Dokumentbreite. Fest positioniert und
   abgeschnitten zählt es nicht mehr mit. Nur am Drawer: Die offene Liste
   ohne Skript würde sonst die Fokusringe der Optionen abschneiden. */
@media (max-width: 1023.98px) {
	.vis-filters.is-enhanced { overflow: hidden; }
}

/* ══ 18 — Spalten, die schrumpfen dürfen ═════════════════════════════════

   Eine Grid-Spur ist standardmäßig so breit wie ihr breitester Inhalt. Das
   Länderfeld der Kasse enthält Optionen wie „Vereinigte Staaten von Amerika
   (Föderierte Staaten von Mikronesien)" — bei 375 px schob sein
   Mindestmaß von 333 px die ganze Kasse 51 px über den Rand.

   `minmax(0, 1fr)` erlaubt der Spur, unter das Mindestmaß des Inhalts zu
   gehen; `min-inline-size: 0` erlaubt es dem Feld darin. Beides gehört
   zusammen — eines allein reicht nicht.                                   */

.vis-checkout__grid,
.vis-cart__totals,
.vis-catalog__layout,
.vis-pdp__inner,
.vis-pdp__detail-inner,
.vis-shopfoot__cols,
.woocommerce-billing-fields__field-wrapper,
.woocommerce-shipping-fields__field-wrapper,
.woocommerce-additional-fields__field-wrapper {
	grid-template-columns: minmax(0, 1fr);
}

@media (min-width: 768px) {
	.woocommerce-billing-fields__field-wrapper,
	.woocommerce-shipping-fields__field-wrapper {
		grid-template-columns: repeat(2, minmax(0, 1fr));
	}
}

@media (min-width: 1024px) {
	.vis-checkout__grid   { grid-template-columns: minmax(0, 1.3fr) minmax(0, 1fr); }
	.vis-cart__totals     { grid-template-columns: minmax(0, 1fr) minmax(0, 420px); }
	.vis-catalog__layout  { grid-template-columns: var(--vis-filters-width) minmax(0, 1fr); }

	/* Ohne Filter gibt es nichts zu teilen.
	   Die Filterspalte entfällt, wenn eine Kategorie keine Filtergruppe
	   hergibt (E68) — bislang trat das nicht auf, weil der Feuerwehrshop
	   immer welche hatte. Ohne diese Regel bliebe die 260 px breite
	   Spalte reserviert, und das Produktraster fiele hinein: vier Karten
	   übereinander in einer Spalte. Steht nach der Regel darüber, damit
	   die Reihenfolge entscheidet und kein `!important` nötig ist. */
	.vis-catalog__layout--plain { grid-template-columns: minmax(0, 1fr); }
	.vis-pdp__inner       { grid-template-columns: minmax(0, 1.1fr) minmax(0, 0.9fr); }
	.vis-pdp__detail-inner { grid-template-columns: minmax(0, 1.4fr) minmax(0, 1fr); }
}


@media (min-width: 768px) {
	.vis-shopfoot__cols { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

.woocommerce form .form-row,
.woocommerce form .form-row select,
.woocommerce form .form-row .select2-container { min-inline-size: 0; }

/* WooCommerce hängt der Produktliste einen Clearfix aus zwei
   Pseudo-Elementen an. Im Float-Layout ist der unsichtbar — im Grid werden
   daraus zwei echte Rasterzellen, und die erste Kachel rutschte in Spalte
   zwei. */
.woocommerce ul.products::before,
.woocommerce ul.products::after,
ul.products::before,
ul.products::after { display: none; }

/* ══ 19 — Nachjustierungen an der Produktseite ═══════════════════════════ */

/* Zwischen 768 und 1023 steht die Galerie noch über der Kaufspalte. Ein
   hochkantes Produktfoto über die volle Breite ist dort kein Bild mehr,
   sondern eine Wand. */
@media (min-width: 768px) and (max-width: 1023.98px) {
	.vis-pdp__media { max-inline-size: 460px; }
}

/* Menge vor Knopf. WooCommerce floatet beide nach links; je nachdem,
   welches Element zuerst floatet, stand der Knopf links neben der Menge —
   also vor der Entscheidung, wie viele. */
.vis-pdp form.cart,
.vis-pdp .woocommerce-variation-add-to-cart {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: var(--vis-space-4);
}

.vis-pdp form.cart .quantity,
.vis-pdp .woocommerce-variation-add-to-cart .quantity,
.vis-pdp form.cart .vis-qty { order: 1; float: none; }

.vis-pdp .single_add_to_cart_button { order: 2; float: none; }

/* Der nicht wählbare Knopf sagt es auch ohne Farbe: WooCommerce blendet
   ihn nur ab. Der Zeiger und `aria-disabled` sagen dasselbe noch einmal. */
.vis-pdp .single_add_to_cart_button.disabled,
.vis-pdp .wc-variation-selection-needed .single_add_to_cart_button {
	cursor: not-allowed;
}

/* Zwei Knöpfe nebeneinander passen in ein 270 px breites Panel nicht:
   „Ergebnisse ansehen" braucht allein schon mehr als die Hälfte. Sie stehen
   deshalb untereinander — im Drawer ist Höhe billig, Breite nicht. */
@media (max-width: 1023.98px) {
	.is-enhanced .vis-filters__foot { grid-template-columns: minmax(0, 1fr); }
}

/* Das vollständige Logo bekommt eine feste Höhe; das SVG bringt seine
   Originalmaße mit und stünde sonst in Rohgröße im Kopf.

   Bewusst zurückhaltend: rund 22 px hoch. Ein Logo, das den halben Kopf
   füllt, macht aus der Marke ein Schild. */
.vis-shophead__logo {
	block-size: var(--vis-space-6);
	inline-size: auto;
	display: block;
}

/* Der Schließknopf gehört zum Drawer, nicht zur Seitenspalte. Die Regel
   steht am Dateiende, weil die allgemeine `.vis-filters__close`-Regel
   sonst später käme und gewönne. */
@media (min-width: 1024px) {
	.vis-filters__close { display: none; }
}

/* Das Mengenfeld trägt jetzt zusätzlich WooCommerce' eigene Klassen — die
   Breite muss deshalb spezifischer gesetzt werden als `.quantity .qty`. */
.vis-qty .vis-qty__input,
.woocommerce .quantity .vis-qty__input {
	inline-size: var(--vis-space-12);
	min-inline-size: 0;
}

/* Schreibgeschützt: eine Zahl, keine Tasten. */
.vis-qty--fixed {
	grid-template-columns: minmax(0, 1fr);
	padding-inline: var(--vis-space-3);
}

.vis-qty--fixed .vis-qty__input {
	text-align: center;
	color: var(--vis-text-2);
}

/* ══ 20 — Brotkrumen ═════════════════════════════════════════════════════

   In einer Shopwelt liegen über einem Produkt drei Ebenen: Welt →
   Kategorie → Produkt. Ohne diese Zeile ist der einzige Weg zurück der
   Zurück-Knopf — und der hilft nicht, wenn man über die Suche gekommen ist.

   Auf schmalen Bildschirmen scrollt die Zeile waagrecht, statt sich auf
   drei Zeilen zu stapeln: Sie ist Orientierung, nicht Inhalt.            */

.vis-crumbs {
	margin-block-end: var(--vis-space-6);
	overflow-x: auto;
	scrollbar-width: none;
}

.vis-crumbs::-webkit-scrollbar { display: none; }

.vis-crumbs__list {
	display: flex;
	align-items: center;
	gap: var(--vis-space-2);
	margin: 0;
	padding: 0;
	list-style: none;
	white-space: nowrap;
}

.vis-crumbs__item {
	display: inline-flex;
	align-items: center;
	gap: var(--vis-space-2);

	color: var(--vis-text-3);
	font-size: var(--vis-fs-caption);
}

.vis-crumbs__item + .vis-crumbs__item::before {
	content: "/";
	color: var(--vis-border-strong);
}

.vis-crumbs__link {
	color: var(--vis-text-2);
	text-decoration: none;
}

.vis-crumbs__link:hover { color: var(--vis-accent-text); }

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

.vis-crumbs__current {
	color: var(--vis-text-3);
	max-inline-size: 28ch;
	overflow: hidden;
	text-overflow: ellipsis;
}

/* ══ 21 — Personalisierung ═══════════════════════════════════════════════

   Sitzt mitten im Kaufweg: bei Varianten unmittelbar nach der Größe, bei
   einfachen Produkten über dem Warenkorb-Knopf. Ein aufklappbarer Kasten
   weiter unten wäre bequemer zu bauen und leichter zu übersehen — und bei
   Feuerwehrbekleidung ist die Beschriftung kein Extra, sondern der Grund
   für den Kauf.                                                          */

.vis-perso {
	margin: var(--vis-space-8) 0 0;
	padding: var(--vis-space-6);
	border: var(--vis-border-width) solid var(--vis-border);
	border-radius: var(--vis-radius-sm);
	background: var(--vis-bg-subtle);
}

.vis-perso__legend {
	padding-inline: var(--vis-space-2);
	margin-inline-start: calc(var(--vis-space-2) * -1);

	color: var(--vis-text-2);
	font-family: var(--vis-font-mono);
	font-size: var(--vis-fs-label);
	letter-spacing: var(--vis-ls-label);
	text-transform: uppercase;
}

.vis-perso__field + .vis-perso__field { margin-block-start: var(--vis-space-5); }

.vis-perso__label {
	display: flex;
	flex-wrap: wrap;
	align-items: baseline;
	gap: var(--vis-space-2) var(--vis-space-3);
	margin-block-end: var(--vis-space-2);
}

.vis-perso__name {
	color: var(--vis-text);
	font-size: var(--vis-fs-body-s);
	font-weight: var(--vis-fw-medium);
}

/* Pflicht und Aufpreis stehen als Wort da, nicht als Sternchen und nicht
   als Farbe allein (§44). */
.vis-perso__flag {
	color: var(--vis-text-2);
	font-family: var(--vis-font-mono);
	font-size: var(--vis-fs-label);
	letter-spacing: var(--vis-ls-label);
	text-transform: uppercase;
}

.vis-perso__flag--soft { color: var(--vis-text-2); }

.vis-perso__surcharge {
	margin-inline-start: auto;
	color: var(--vis-accent-text);
	font-size: var(--vis-fs-caption);
	font-variant-numeric: tabular-nums;
	white-space: nowrap;
}

.vis-perso__input,
.vis-perso__select {
	inline-size: 100%;
	min-inline-size: 0;
	min-block-size: var(--vis-input-height);
	padding: var(--vis-space-3) var(--vis-space-4);

	border: var(--vis-border-width) solid var(--vis-border-strong);
	border-radius: var(--vis-radius-sm);
	background: var(--vis-white);

	color: var(--vis-text);
	font-family: inherit;
	font-size: var(--vis-fs-body);
}

.vis-perso__input:focus-visible,
.vis-perso__select:focus-visible {
	outline: var(--vis-focus-width) solid var(--vis-accent);
	outline-offset: var(--vis-focus-offset);
}

.vis-perso__check {
	display: flex;
	align-items: center;
	gap: var(--vis-space-3);
	min-block-size: var(--vis-tap-target-min);
	cursor: pointer;
}

.vis-perso__check input {
	inline-size: var(--vis-space-5);
	block-size: var(--vis-space-5);
	accent-color: var(--vis-accent);
	flex: none;
}

.vis-perso__help {
	margin: var(--vis-space-2) 0 0;
	color: var(--vis-text-2);
	font-size: var(--vis-fs-caption);
	line-height: var(--vis-lh-snug);
}

/* Eine Zeile, keine zweite Preistabelle. Sie erscheint erst, wenn wirklich
   etwas dazukommt — und sie ist eine Vorschau: Gerechnet wird im
   Warenkorb. */
.vis-perso__total {
	margin-block-start: var(--vis-space-5);
	padding-block-start: var(--vis-space-4);
	border-block-start: var(--vis-border-width) solid var(--vis-border);
}

.vis-perso__sum {
	display: grid;
	grid-template-columns: minmax(0, 1fr) auto;
	gap: var(--vis-space-1) var(--vis-space-4);
	margin: 0;
}

.vis-perso__sum dt {
	color: var(--vis-text-2);
	font-size: var(--vis-fs-caption);
}

.vis-perso__sum dd {
	margin: 0;
	color: var(--vis-text-2);
	font-size: var(--vis-fs-caption);
	font-variant-numeric: tabular-nums;
	text-align: end;
}

.vis-perso__sum .vis-perso__sum-total {
	margin-block-start: var(--vis-space-2);
	padding-block-start: var(--vis-space-2);
	border-block-start: var(--vis-border-width) solid var(--vis-border);

	color: var(--vis-text);
	font-size: var(--vis-fs-body-s);
	font-weight: var(--vis-fw-bold);
}

/* ══ 22 — „Bitte wähle zuerst eine Größe." (SH6) ═════════════════════════

   WooCommerce blendet den Knopf nur ab. Das ist ein Zustand, den man sehen,
   aber nicht lesen kann — wer nicht weiß, warum der Knopf nicht geht,
   klickt ihn dreimal.                                                    */

.vis-pdp__choose {
	display: flex;
	align-items: center;
	gap: var(--vis-space-2);

	margin: var(--vis-space-4) 0 0;
	color: var(--vis-text-2);
	font-size: var(--vis-fs-body-s);
}

.vis-pdp__choose::before {
	content: "";
	flex: none;
	inline-size: var(--vis-space-2);
	block-size: var(--vis-space-2);
	border-radius: var(--vis-radius-full);
	background: var(--vis-world-accent, var(--vis-accent));
}

.vis-pdp__choose[hidden] { display: none; }

/* ══ 23 — Shopwelt im Fuß ════════════════════════════════════════════════ */

.vis-shopfoot__world {
	display: block;
	margin: 0 0 var(--vis-space-2);
	color: var(--vis-white);
	font-size: var(--vis-fs-body-s);
	font-weight: var(--vis-fw-medium);
}

/* ══ 24 — WooCommerce-Farben überschreiben ═══════════════════════════════

   `woocommerce-general` bleibt geladen, weil dort die Produktgalerie liegt
   (Abschnitt 9). Es bringt aber auch seine eigene Markenfarbe mit — ein
   Violett, das dem VISARO Purple ähnlich genug sieht, um unbemerkt zu
   bleiben, und das in einer Shopwelt schlicht falsch ist.

   Die Selektoren spiegeln WooCommerce' eigene Spezifität (drei Klassen und
   ein Element); `shop.css` lädt danach und gewinnt deshalb. Ein `!important`
   braucht es dafür nicht.                                                 */

.woocommerce a.button,
.woocommerce button.button,
.woocommerce input.button,
.woocommerce #respond input#submit {
	background-color: transparent;
	border: var(--vis-border-width) solid var(--vis-border-strong);
	color: var(--vis-text);
	border-radius: var(--vis-radius-sm);
	font-family: inherit;
	font-weight: var(--vis-fw-medium);
}

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

.woocommerce a.button.alt,
.woocommerce button.button.alt,
.woocommerce input.button.alt,
.woocommerce #respond input#submit.alt {
	background-color: var(--vis-accent);
	border-color: transparent;
	color: var(--vis-white);
}

.woocommerce a.button.alt:hover,
.woocommerce button.button.alt:hover,
.woocommerce input.button.alt:hover,
.woocommerce #respond input#submit.alt:hover {
	background-color: var(--vis-ink-950);
	border-color: transparent;
	color: var(--vis-white);
}

.woocommerce a.button.disabled,
.woocommerce button.button.disabled,
.woocommerce button.button.alt.disabled,
.woocommerce input.button:disabled {
	background-color: var(--vis-ink-200);
	border-color: transparent;
	color: var(--vis-text-disabled);
	opacity: 1;
	cursor: not-allowed;
}

/* Preise tragen die Textfarbe, nicht WooCommerce' Grün. Der Preis ist eine
   Angabe, kein Signal. */
.woocommerce div.product p.price,
.woocommerce div.product span.price,
.woocommerce ul.products li.product .price,
.vis-pdp .woocommerce-variation-price .price,
.vis-pdp .woocommerce-variation-price .amount {
	color: var(--vis-text);
}

.woocommerce div.product p.price ins,
.woocommerce div.product span.price ins,
.woocommerce ul.products li.product .price ins {
	color: var(--vis-accent-text);
	text-decoration: none;
}

.woocommerce div.product p.price del,
.woocommerce div.product span.price del,
.woocommerce ul.products li.product .price del {
	color: var(--vis-text-3);
	opacity: 1;
}

/* Lagerhinweise ebenfalls in der Textfarbe. */
.woocommerce div.product .stock,
.woocommerce .woocommerce-variation-availability .stock { color: var(--vis-text-2); }
.woocommerce div.product .stock.out-of-stock { color: var(--vis-err-text); }

/* ── Warenkorb-Kontext ─────────────────────────────────────────────────────

   Eine Zeile über dem Warenkorb, die sagt, woher der Inhalt kommt. In
   Shopwelten mit eigener Oberfläche wird sie dort neu gesetzt; das hier ist
   die allgemeine Fassung.                                                  */

.vis-cartcontext {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: var(--vis-space-3);

	margin-block-end: var(--vis-space-6);
	padding: var(--vis-space-3) var(--vis-space-4);
	border-radius: var(--vis-radius-md);
	background: var(--vis-bg-subtle);
}

.vis-cartcontext__label {
	color: var(--vis-text-3);
	font-family: var(--vis-font-mono);
	font-size: var(--vis-fs-label);
	letter-spacing: var(--vis-ls-label);
	text-transform: uppercase;
}

.vis-cartcontext__world {
	color: var(--vis-text);
	font-size: var(--vis-fs-body-s);
	font-weight: var(--vis-fw-bold);
}

.vis-cartcontext__note {
	color: var(--vis-text-3);
	font-size: var(--vis-fs-caption);
}

.vis-cartcontext__back {
	margin-inline-start: auto;
	display: inline-flex;
	align-items: center;
	gap: var(--vis-space-2);
	font-size: var(--vis-fs-body-s);
	text-decoration: none;
}

.vis-cartcontext__back .vis-icon {
	inline-size: var(--vis-space-4);
	block-size: var(--vis-space-4);
}

/* ══════════════════════════════════════════════════════════════════════════
   BEWERTUNGEN

   Bewusst hier und nicht in einer Shopwelt: Der Baustein arbeitet
   ausschließlich mit Rollentokens (--vis-text, --vis-border, --vis-bg …).
   Eine Shopwelt, die diese Tokens neu belegt — wie die Feuerwehrwelt —
   bekommt die passende Darstellung, ohne dass hier etwas verdoppelt wird.

   Ohne Bewertung steht hier ein ehrlicher Leerzustand. Keine graue
   Sternreihe, kein „(0)", kein Durchschnitt ohne Grundlage.
   ══════════════════════════════════════════════════════════════════════════ */

.vis-reviews {
	border-block-start: var(--vis-border-width) solid var(--vis-border);
	padding-block: var(--vis-section-m);
}

.vis-reviews__inner {
	max-width: var(--vis-container-content);
	margin-inline: auto;
	padding-inline: var(--vis-gutter);
}

.vis-reviews__head {
	display: flex;
	flex-wrap: wrap;
	align-items: baseline;
	justify-content: space-between;
	gap: var(--vis-space-4);
	margin-block-end: var(--vis-space-8);
}

.vis-reviews__title {
	margin: 0;
	font-size: var(--vis-fs-h3);
	color: var(--vis-text);
}

.vis-reviews__avg {
	display: flex;
	align-items: center;
	gap: var(--vis-space-3);
	margin: var(--vis-space-2) 0 0;
}

.vis-reviews__score {
	color: var(--vis-text);
	font-family: var(--vis-font-mono);
	font-size: var(--vis-fs-body);
	font-variant-numeric: tabular-nums;
}

.vis-reviews__count {
	color: var(--vis-text-3);
	font-size: var(--vis-fs-body-s);
}

/* ── Sterne ───────────────────────────────────────────────────────────────

   Gefüllt für die erreichten, ausgegraut für die übrigen. Der Wert steht
   immer als Zahl daneben: 4,3 als vier volle Sterne darzustellen wäre eine
   Rundung zu Lasten der Wahrheit.                                          */

.vis-stars {
	display: inline-flex;
	align-items: center;
	gap: 2px;
}

.vis-stars .vis-icon {
	width: var(--vis-space-4);
	height: var(--vis-space-4);
}

.vis-stars__on { color: var(--vis-world-accent, var(--vis-accent)); }
.vis-stars__on .vis-icon { fill: currentColor; }
.vis-stars__off { color: var(--vis-border-strong); }

/* Sternezeile in der Kaufspalte — erst ab der ersten Bewertung. */
.vis-pdp__rating {
	display: flex;
	align-items: center;
	gap: var(--vis-space-2);
	margin: var(--vis-space-2) 0 0;
	font-size: var(--vis-fs-caption);
}

.vis-pdp__rating a {
	color: var(--vis-text-2);
	text-decoration: underline;
	text-underline-offset: var(--vis-space-1);
}

.vis-pdp__rating a:hover { color: var(--vis-text); }

/* ── Eine Bewertung ───────────────────────────────────────────────────── */

.vis-reviews__list {
	display: grid;
	gap: 0;
	margin: 0;
	padding: 0;
	list-style: none;
}

.vis-review {
	padding-block: var(--vis-space-6);
	border-block-start: var(--vis-border-width) solid var(--vis-border);
}

.vis-review:first-child { border-block-start: 0; }

.vis-review__head {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: var(--vis-space-3);
}

.vis-review__title {
	margin: var(--vis-space-3) 0 var(--vis-space-2);
	color: var(--vis-text);
	font-size: var(--vis-fs-body);
	font-weight: var(--vis-fw-bold);
}

.vis-review__text {
	max-inline-size: 68ch;
	color: var(--vis-text-2);
	line-height: var(--vis-lh-body);
}

.vis-review__text p { margin: 0 0 var(--vis-space-3); }
.vis-review__text p:last-child { margin-block-end: 0; }

.vis-review__meta {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: var(--vis-space-3);
	margin: var(--vis-space-3) 0 0;
	color: var(--vis-text-3);
	font-size: var(--vis-fs-caption);
}

.vis-review__author {
	color: var(--vis-text);
	font-weight: var(--vis-fw-medium);
}

/* Der Haken steht für einen tatsächlich zugeordneten Kauf — sonst steht er
   nicht da. */
.vis-review__verified {
	display: inline-flex;
	align-items: center;
	gap: var(--vis-space-1);
	padding: 2px var(--vis-space-2);
	border-radius: var(--vis-radius-full);
	background: rgba(30, 122, 70, 0.12);
	color: #1E7A46;
	font-size: var(--vis-fs-label);
}

.vis-review__verified .vis-icon {
	width: var(--vis-space-4);
	height: var(--vis-space-4);
}

.vis-review__variant {
	font-family: var(--vis-font-mono);
	font-size: var(--vis-fs-label);
	letter-spacing: var(--vis-ls-label);
	text-transform: uppercase;
}

/* ── Bilder einer Bewertung ───────────────────────────────────────────── */

.vis-review__shots {
	display: flex;
	gap: var(--vis-space-2);
	margin: var(--vis-space-4) 0 0;
	padding: 0;
	list-style: none;
}

@media (max-width: 767.98px) {
	/* Mobil waagrecht wischbar statt umgebrochen. */
	.vis-review__shots {
		overflow-x: auto;
		scrollbar-width: none;
		scroll-snap-type: x proximity;
	}

	.vis-review__shots::-webkit-scrollbar { display: none; }
	.vis-review__shots li { scroll-snap-align: start; }
}

.vis-review__shot {
	display: block;
	width: 96px;
	height: 96px;
	flex: none;

	padding: 0;
	border: 0;
	border-radius: var(--vis-radius-sm);
	overflow: hidden;
	background: var(--vis-bg-subtle);
	cursor: zoom-in;
}

.vis-review__shot img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	display: block;
}

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

/* ── Leerzustand ──────────────────────────────────────────────────────── */

.vis-reviews__empty {
	display: grid;
	gap: var(--vis-space-3);
	justify-items: start;
	padding-block: var(--vis-space-8);
}

.vis-reviews__empty-title {
	margin: 0;
	color: var(--vis-text);
	font-size: var(--vis-fs-body-l);
	font-weight: var(--vis-fw-bold);
}

.vis-reviews__empty-text {
	margin: 0;
	max-inline-size: 46ch;
	color: var(--vis-text-2);
}

/* ── Formular ─────────────────────────────────────────────────────────── */

.vis-reviewform {
	margin-block-start: var(--vis-section-s);
	padding: var(--vis-space-8);
	border: var(--vis-border-width) solid var(--vis-border);
	border-radius: var(--vis-radius-lg);
	background: var(--vis-bg-subtle);
}

.vis-reviewform__title {
	margin: 0 0 var(--vis-space-2);
	font-size: var(--vis-fs-h4);
	color: var(--vis-text);
}

.vis-reviewform__lead {
	margin: 0 0 var(--vis-space-6);
	max-inline-size: 52ch;
	color: var(--vis-text-2);
	font-size: var(--vis-fs-body-s);
}

.vis-reviewform__row {
	display: grid;
	gap: var(--vis-space-2);
	margin: 0 0 var(--vis-space-5);
}

.vis-reviewform__label {
	color: var(--vis-text-2);
	font-size: var(--vis-fs-body-s);
	font-weight: var(--vis-fw-medium);
}

.vis-reviewform__req { color: var(--vis-error, #B32419); }

.vis-reviewform input[type="text"],
.vis-reviewform input[type="email"],
.vis-reviewform textarea,
.vis-reviewform select {
	width: 100%;
	min-inline-size: 0;
	min-block-size: var(--vis-control-height);
	padding: var(--vis-space-3) var(--vis-space-4);

	border: var(--vis-border-width) solid var(--vis-border-strong);
	border-radius: var(--vis-radius-sm);
	background: var(--vis-white);

	color: var(--vis-text);
	font-family: inherit;
	font-size: var(--vis-fs-body-s);
}

.vis-reviewform textarea {
	min-block-size: 140px;
	resize: vertical;
}

.vis-reviewform input:focus-visible,
.vis-reviewform textarea:focus-visible,
.vis-reviewform select:focus-visible {
	outline: var(--vis-focus-width) solid var(--vis-accent);
	outline-offset: var(--vis-focus-offset);
}

.vis-reviewform__note {
	display: block;
	margin: var(--vis-space-2) 0 0;
	max-inline-size: 60ch;
	color: var(--vis-text-3);
	font-size: var(--vis-fs-caption);
	line-height: var(--vis-lh-snug);
}

.vis-reviewform__submit { margin: var(--vis-space-6) 0 0; }

/* Honigfalle: aus dem Bild, aber nicht `display: none` — manche Skripte
   überspringen ausgeblendete Felder gerade deshalb. */
.vis-reviewform__trap {
	position: absolute;
	width: 1px;
	height: 1px;
	overflow: hidden;
	clip-path: inset(50%);
	white-space: nowrap;
}

/* ── Sterne wählen ────────────────────────────────────────────────────── */

/* Die Wahl liegt auf echten Radiofeldern: Sie funktioniert ohne
   JavaScript, ist mit der Tastatur bedienbar und braucht keinen eigenen
   Zustand. Sichtbar sind die Sterne. */
.vis-rating {
	display: inline-flex;
	flex-direction: row-reverse;
	justify-content: flex-end;
	gap: var(--vis-space-1);
}

.vis-rating input {
	position: absolute;
	width: 1px;
	height: 1px;
	overflow: hidden;
	clip-path: inset(50%);
}

.vis-rating label {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: var(--vis-tap-target-min);
	height: var(--vis-tap-target-min);
	color: var(--vis-border-strong);
	cursor: pointer;
	transition: color var(--vis-duration-ui) var(--vis-ease-out);
}

.vis-rating label .vis-icon {
	width: var(--vis-space-6);
	height: var(--vis-space-6);
}

/* Der gewählte Stern und alle davor: `row-reverse` macht „alle davor" zu
   „alle Geschwister danach". */
.vis-rating input:checked ~ label,
.vis-rating label:hover,
.vis-rating label:hover ~ label {
	color: var(--vis-world-accent, var(--vis-accent));
}

.vis-rating input:checked ~ label .vis-icon,
.vis-rating label:hover .vis-icon,
.vis-rating label:hover ~ label .vis-icon { fill: currentColor; }

.vis-rating input:focus-visible + label {
	outline: var(--vis-focus-width) solid var(--vis-accent);
	outline-offset: var(--vis-focus-offset);
	border-radius: var(--vis-radius-sm);
}

/* ── Bilder hinzufügen ────────────────────────────────────────────────── */

.vis-shots__drop {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: var(--vis-space-3);

	padding: var(--vis-space-4);
	border: var(--vis-border-width) dashed var(--vis-border-strong);
	border-radius: var(--vis-radius-sm);
	background: var(--vis-white);
}

.vis-shots__btn {
	display: inline-flex;
	align-items: center;
	gap: var(--vis-space-2);

	min-block-size: var(--vis-control-height);
	padding-inline: var(--vis-space-4);
	border: var(--vis-border-width) solid var(--vis-border-strong);
	border-radius: var(--vis-radius-full);
	background: transparent;

	color: var(--vis-text);
	font-family: inherit;
	font-size: var(--vis-fs-body-s);
	font-weight: var(--vis-fw-medium);
	cursor: pointer;
}

.vis-shots__btn:hover { border-color: var(--vis-text); }
.vis-shots__btn[disabled] { opacity: 0.5; cursor: not-allowed; }

.vis-shots__rule {
	margin: 0;
	color: var(--vis-text-3);
	font-size: var(--vis-fs-caption);
	line-height: var(--vis-lh-snug);
}

/* Das Dateifeld bleibt bedienbar, nur unsichtbar: Ohne JavaScript ist es
   der einzige Weg, Bilder auszuwählen — deshalb kommt es dort zurück. */
.vis-shots__input {
	position: absolute;
	width: 1px;
	height: 1px;
	overflow: hidden;
	clip-path: inset(50%);
}

.no-js .vis-shots__input {
	position: static;
	width: auto;
	height: auto;
	clip-path: none;
}

.no-js .vis-shots__btn { display: none; }

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

.vis-shots__item {
	position: relative;
	width: 88px;
	height: 88px;
	border-radius: var(--vis-radius-sm);
	overflow: hidden;
	background: var(--vis-bg-subtle);
}

.vis-shots__item img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	display: block;
}

.vis-shots__remove {
	position: absolute;
	inset-block-start: var(--vis-space-1);
	inset-inline-end: var(--vis-space-1);

	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: var(--vis-space-6);
	height: var(--vis-space-6);

	border: 0;
	border-radius: var(--vis-radius-full);
	background: rgba(8, 9, 10, 0.78);
	color: #FFFFFF;
	cursor: pointer;
}

.vis-shots__remove .vis-icon {
	width: var(--vis-space-4);
	height: var(--vis-space-4);
}

.vis-shots__error {
	margin: 0;
	color: var(--vis-error, #B32419);
	font-size: var(--vis-fs-caption);
}

.vis-shots__error:empty { display: none; }

/* ── Mono-Label auf Linie ──────────────────────────────────────────────────

   Sonst in `signature.css` zu Hause. Der Shop lädt dieses Stylesheet nicht
   mehr — die 60°-Geometrie, die Eckmarken und die Indexlisten kommen dort
   in keiner Vorlage vor, und für eine einzige Regel lohnen sich 14 KB
   nicht. Also steht sie hier.                                             */

.vis-label-rule {
	display: flex;
	align-items: center;
	gap: var(--vis-space-4);
}

.vis-label-rule::after {
	content: "";
	flex: 1;
	height: var(--vis-border-width);
	background: var(--vis-border);
}

/* ══════════════════════════════════════════════════════════════════════════
   PRODUKTGALERIE

   Ein Markup, zwei Darstellungen:

     ab 1024   großes Hauptbild, Vorschaubilder als Spalte daneben
     darunter  Wischstrecke mit Zähler „1 / 6"

   Beide tragen 1 bis 10 Bilder und mehr ohne Sonderfall. Bei einem Bild
   entfallen Vorschau und Zähler von selbst.

   Steht hier und nicht in einer Shopwelt: Die Produktseite ist für alle
   Welten dieselbe Struktur, nur mit anderen Tokens.
   ══════════════════════════════════════════════════════════════════════════ */

.vis-gal {
	display: grid;
	gap: var(--vis-space-4);
}

@media (min-width: 1024px) {
	.vis-gal {
		grid-template-columns: 84px minmax(0, 1fr);
		align-items: start;
	}

	/* Bei nur einem Bild braucht es keine leere Spalte. */
	.vis-gal--single { grid-template-columns: minmax(0, 1fr); }
}

/* ── Hauptbild ─────────────────────────────────────────────────────────── */

.vis-gal__main {
	position: relative;
	order: 2;
	border-radius: var(--vis-radius-lg);
	background: var(--vis-bg-subtle);
	overflow: hidden;
}

.vis-gal__track {
	display: grid;
	grid-auto-flow: column;
	grid-auto-columns: 100%;

	overflow-x: auto;
	scroll-snap-type: x mandatory;
	scrollbar-width: none;
	-webkit-overflow-scrolling: touch;
}

.vis-gal__track::-webkit-scrollbar { display: none; }

/* Das Format steht fest, bevor das Bild da ist — kein Sprung im Layout. */
.vis-gal__slide {
	scroll-snap-align: center;
	aspect-ratio: 4 / 5;
	display: block;
	width: 100%;
	border: 0;
	padding: 0;
	background: transparent;
	cursor: zoom-in;
}

/* Das Produkt liegt vollständig in der Fläche, mit Luft ringsum (§9). Der
   Rahmen ist groß und ruhig; das Bild füllt ihn nicht randlos aus, sondern
   steht darin. Vorher stand hier `cover`: Bei einem Shirt fehlte der Saum,
   bei einer Jacke der Kragen — ausgerechnet auf der Seite, auf der man das
   Produkt ansieht, bevor man es kauft. */
.vis-gal__slide img {
	width: 100%;
	height: 100%;
	display: block;

	object-fit: contain;
	padding: var(--vis-media-pad);
	box-sizing: border-box;
}

.vis-gal__slide:focus-visible {
	outline: var(--vis-focus-width) solid var(--vis-accent);
	outline-offset: calc(var(--vis-focus-offset) * -1);
}

.vis-gal__placeholder {
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	gap: var(--vis-space-2);

	aspect-ratio: 4 / 5;
	padding: var(--vis-space-6);
	background: var(--vis-bg-surface);
	text-align: center;
}

.vis-gal__ph-id {
	color: var(--vis-text-2);
	font-family: var(--vis-font-mono);
	font-size: var(--vis-fs-label);
	letter-spacing: var(--vis-ls-label);
}

.vis-gal__ph-motif {
	max-inline-size: 34ch;
	color: var(--vis-text-3);
	font-size: var(--vis-fs-caption);
	line-height: var(--vis-lh-snug);
}

/* ── Zähler ────────────────────────────────────────────────────────────── */

.vis-gal__counter {
	position: absolute;
	inset-block-end: var(--vis-space-3);
	inset-inline-end: var(--vis-space-3);

	margin: 0;
	padding: var(--vis-space-1) var(--vis-space-3);
	border-radius: var(--vis-radius-full);
	background: rgba(8, 9, 10, 0.72);
	color: #FFFFFF;

	font-family: var(--vis-font-mono);
	font-size: var(--vis-fs-label);
	font-variant-numeric: tabular-nums;
	letter-spacing: var(--vis-ls-label);
	pointer-events: none;
}

@media (min-width: 1024px) {
	.vis-gal__counter { display: none; }
}

/* ── Vorschaubilder ────────────────────────────────────────────────────── */

.vis-gal__thumbs {
	order: 1;
	display: none;
	gap: var(--vis-space-2);
	margin: 0;
	padding: 0;
	list-style: none;
}

@media (min-width: 1024px) {
	.vis-gal__thumbs { display: grid; }
}

.vis-gal__thumb {
	display: block;
	width: 100%;
	aspect-ratio: 4 / 5;
	padding: 0;
	border: var(--vis-border-width-strong) solid transparent;
	border-radius: var(--vis-radius-sm);
	background: var(--vis-bg-subtle);
	overflow: hidden;
	cursor: pointer;

	transition: border-color var(--vis-duration-ui) var(--vis-ease-out);
}

.vis-gal__thumb img {
	width: 100%;
	height: 100%;
	display: block;

	/* Auch die Vorschau zeigt das ganze Produkt. Ein angeschnittenes
	   Vorschaubild neben einem vollständigen Hauptbild lässt beide wie
	   verschiedene Artikel aussehen. */
	object-fit: contain;
	padding: 6%;
	box-sizing: border-box;
}

.vis-gal__thumb:hover { border-color: var(--vis-border-strong); }
.vis-gal__thumb[aria-current="true"] { border-color: var(--vis-text); }

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

/* ── Lightbox ──────────────────────────────────────────────────────────── */

.vis-lb {
	position: fixed;
	inset: 0;
	z-index: var(--vis-z-modal);
	display: grid;
	grid-template-rows: auto minmax(0, 1fr);
	background: rgba(8, 9, 10, 0.94);
}

.vis-lb[hidden] { display: none; }

.vis-lb__bar {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: var(--vis-space-4);
	padding: var(--vis-space-4) var(--vis-gutter);
	color: #B9BCC2;
}

.vis-lb__count {
	margin: 0;
	font-family: var(--vis-font-mono);
	font-size: var(--vis-fs-label);
	font-variant-numeric: tabular-nums;
	letter-spacing: var(--vis-ls-label);
}

.vis-lb__close {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: var(--vis-tap-target-min);
	height: var(--vis-tap-target-min);
	border: 0;
	border-radius: var(--vis-radius-full);
	background: transparent;
	color: #FFFFFF;
	cursor: pointer;
}

.vis-lb__close:hover { background: rgba(255, 255, 255, 0.10); }

.vis-lb__controls {
	display: flex;
	align-items: center;
	gap: var(--vis-space-2);
}

.vis-lb__nav { font-size: var(--vis-fs-h3); }
.vis-lb__nav:disabled { color: var(--vis-text-disabled); cursor: default; }
.vis-lb__close:focus-visible {
	outline: var(--vis-focus-width) solid var(--vis-white);
	outline-offset: var(--vis-focus-offset);
}

.vis-lb__stage {
	display: grid;
	grid-auto-flow: column;
	grid-auto-columns: 100%;
	overflow-x: auto;
	scroll-snap-type: x mandatory;
	scrollbar-width: none;
	align-items: center;
}

.vis-lb__stage::-webkit-scrollbar { display: none; }

.vis-lb__stage img {
	scroll-snap-align: center;
	width: 100%;
	max-height: 100%;
	object-fit: contain;
	display: block;
	padding: var(--vis-gutter);
}

/* ══════════════════════════════════════════════════════════════════════════
   GRÖSSEN ALS KNÖPFE

   Eine Auswahlliste verlangt drei Handlungen — öffnen, suchen, wählen —
   und zeigt nicht, welche Größe fehlt.

   Die Umwandlung macht `shop-product.js` aus der bestehenden
   WooCommerce-Auswahl und schreibt jede Wahl dorthin zurück. Ohne
   JavaScript bleibt die Auswahlliste sichtbar und der Kauf funktioniert
   unverändert.
   ══════════════════════════════════════════════════════════════════════════ */

.vis-sizes {
	display: flex;
	flex-wrap: wrap;
	gap: var(--vis-space-2);
	margin-block-start: var(--vis-space-2);
}

/* `display: flex` gewinnt gegen die Browserregel für `[hidden]`. Ohne
   diese Zeile stehen die Größen weiter da, während daneben „Bitte zuerst
   die Ausführung wählen" steht — genau der Zustand, den das Ausblenden
   beenden sollte. */
.vis-sizes[hidden] { display: none; }

.vis-size {
	min-inline-size: 56px;
	min-block-size: var(--vis-tap-target-min);
	padding-inline: var(--vis-space-3);

	border: var(--vis-border-width) solid var(--vis-border);
	border-radius: var(--vis-radius-sm);
	background: var(--vis-white);

	color: var(--vis-text);
	font-family: inherit;
	font-size: var(--vis-fs-body-s);
	font-weight: var(--vis-fw-medium);
	cursor: pointer;

	transition:
		border-color var(--vis-duration-ui) var(--vis-ease-out),
		background-color var(--vis-duration-ui) var(--vis-ease-out);
}

.vis-size:hover { border-color: var(--vis-text); }

.vis-size[aria-pressed="true"] {
	background: var(--vis-text);
	border-color: var(--vis-text);
	color: var(--vis-bg);
}

/* Nicht verfügbar heißt sichtbar und durchgestrichen, nicht verschwunden:
   Wer seine Größe sucht, will wissen, dass es sie gibt — nur gerade
   nicht.

   Das gilt für die **erste** Achse. Bei einer abhängigen Achse blendet
   `shop-product.js` stattdessen aus: Eine Damengröße ist für ein
   Herrenshirt nicht vergriffen, sondern gar nicht gemeint. */
.vis-size[disabled] {
	color: var(--vis-text-disabled);
	border-color: var(--vis-border-subtle);
	cursor: not-allowed;
	text-decoration: line-through;
}

.vis-size[hidden] { display: none; }

/* Der Satz an der Stelle der Größen, solange die Ausführung offen ist.
   Er nimmt ungefähr die Höhe einer Knopfreihe ein, damit die Kaufspalte
   beim Wählen nicht springt. */
.vis-sizes__wait {
	display: flex;
	align-items: center;

	min-block-size: var(--vis-tap-target-min);
	margin-block-start: var(--vis-space-2);

	color: var(--vis-text-2);
	font-size: var(--vis-fs-body-s);
}

/* Wie bei `.vis-sizes`: `display: flex` gewinnt gegen die Browserregel
   für `[hidden]`. Ohne diese Zeile stand unter der Ausführung ein leeres
   Band von 44 px, das niemand einem versteckten Satz zugeordnet hätte. */
.vis-sizes__wait[hidden] { display: none; }

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

/* Underwear-Farben sind Produktansichten statt beschrifteter Chips. Die
   kleine Aufnahme beantwortet die Frage schneller als ein Farbname allein;
   der Name bleibt für Eindeutigkeit und Bedienhilfen darunter erhalten. */
.vis-sizes.vis-colors {
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(68px, 1fr));
	gap: var(--vis-space-3);
	inline-size: 100%;
}

.vis-color-option {
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: var(--vis-space-1);

	min-inline-size: 0;
	min-block-size: 0;
	padding: var(--vis-space-1);
	background: var(--vis-bg-subtle);
	color: var(--vis-text);
}

.vis-color-option img {
	display: block;
	inline-size: 100%;
	aspect-ratio: 1;
	object-fit: contain;
	border-radius: calc(var(--vis-radius-sm) - 2px);
	background: transparent;
}

.vis-color-option span {
	max-inline-size: 100%;
	font-size: 11px;
	line-height: 1.2;
	text-align: center;
	overflow-wrap: anywhere;
}

.vis-color-option:hover {
	border-color: var(--vis-club-primary, var(--vis-text));
	background: var(--vis-white);
}

.vis-color-option[aria-pressed="true"] {
	background: var(--vis-white);
	border-color: var(--vis-club-primary, var(--vis-text));
	color: var(--vis-text);
	box-shadow: 0 0 0 1px var(--vis-club-primary, var(--vis-text));
}

.vis-sizeguide {
	display: inline-flex;
	align-items: center;
	gap: var(--vis-space-2);
	margin-block-start: var(--vis-space-3);

	border: 0;
	background: transparent;
	padding: 0;
	min-block-size: var(--vis-tap-target-min);

	color: var(--vis-text-2);
	font-family: inherit;
	font-size: var(--vis-fs-caption);
	text-decoration: underline;
	text-underline-offset: var(--vis-space-1);
	cursor: pointer;
}

.vis-sizeguide:hover { color: var(--vis-text); }

/* ── Fehler am Feld ────────────────────────────────────────────────────── */

.vis-fielderror {
	display: flex;
	align-items: center;
	gap: var(--vis-space-2);
	margin: var(--vis-space-2) 0 0;

	color: var(--vis-error, #B32419);
	font-size: var(--vis-fs-caption);
}

.vis-fielderror::before {
	content: "!";
	display: inline-flex;
	align-items: center;
	justify-content: center;

	width: var(--vis-space-5);
	height: var(--vis-space-5);
	border-radius: var(--vis-radius-full);
	background: var(--vis-error, #B32419);
	color: #FFFFFF;
	font-size: var(--vis-fs-label);
	font-weight: var(--vis-fw-bold);
	flex: none;
}

.vis-invalid .vis-perso__input,
.vis-invalid .vis-perso__select,
.vis-invalid .vis-team__field { border-color: var(--vis-error, #B32419); }

/* ══════════════════════════════════════════════════════════════════════════
   KAUFLEISTE (MOBIL)

   Erscheint, sobald der Warenkorb-Knopf aus dem Bild ist. Deckend statt
   durchscheinend: Ein `backdrop-filter` auf einer festen Leiste wird bei
   jedem Scrollframe neu berechnet.
   ══════════════════════════════════════════════════════════════════════════ */

.vis-buybar {
	position: fixed;
	inset-block-end: 0;
	inset-inline: 0;
	z-index: var(--vis-z-sticky);

	background: var(--vis-white);
	border-block-start: var(--vis-border-width) solid var(--vis-border);
	box-shadow: 0 -8px 30px rgba(8, 9, 10, 0.08);

	transform: translateY(100%);
	transition: transform 200ms var(--vis-ease-out);
	padding-block-end: env(safe-area-inset-bottom);
}

.vis-buybar.is-visible { transform: none; }
.vis-buybar[hidden] { display: none; }

.vis-buybar__inner {
	display: grid;
	grid-template-columns: minmax(0, 1fr) auto;
	align-items: center;
	gap: var(--vis-space-4);
	padding: var(--vis-space-3) var(--vis-gutter);
}

.vis-buybar__info { display: grid; min-inline-size: 0; }

.vis-buybar__name {
	color: var(--vis-text-3);
	font-size: var(--vis-fs-caption);
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}

.vis-buybar__price {
	color: var(--vis-text);
	font-size: var(--vis-fs-body);
	font-weight: var(--vis-fw-bold);
	font-variant-numeric: tabular-nums;
}

.vis-buybar__price del { display: none; }

@media (min-width: 1024px) {
	.vis-buybar { display: none; }
}

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

/* ══════════════════════════════════════════════════════════════════════════
   GRÖSSENMATRIX

   Eine Feuerwehr bestellt nicht ein Polo, sondern achtzehn. Diese Matrix
   sieht deshalb aus wie die Liste, die man ohnehin auf einem Zettel hätte:

       HERREN
       XS   S   M   L   XL   2XL   3XL   4XL
       [0] [0] [4] [6] [2]  [0]   [0]   [0]

   Größen **nebeneinander**, Mengen darunter, Ausführungen
   **untereinander**. Reiter versteckten die Hälfte der Bestellung; hier
   steht alles gleichzeitig da.

   Die Zahl der Spalten kommt aus der Zahl der Größen (`--vis-matrix-cols`)
   und wird nach unten begrenzt, sobald der Platz nicht mehr reicht — nie
   nach oben aufgefüllt. Fünf Damengrößen belegen fünf Spalten, nicht neun
   mit vier leeren.

   Kein Rahmen um jede Zelle, keine Trennlinien, keine Preiszeile bei
   gleichem Preis: Bei neun Feldern nebeneinander ist Ruhe die einzige
   Möglichkeit, das noch lesbar zu halten.
   ══════════════════════════════════════════════════════════════════════════ */

.vis-team {
	display: grid;
	gap: var(--vis-space-5);
	margin-block-start: var(--vis-space-5);
}

.vis-matrix__top {
	display: flex;
	align-items: baseline;
	justify-content: space-between;
	gap: var(--vis-space-3);
	margin-block-end: var(--vis-space-4);
}

.vis-matrix__top .vis-label-rule { margin: 0; }

.vis-matrix__guide {
	color: var(--vis-text-3);
	font-size: var(--vis-fs-caption);
	white-space: nowrap;
}

/* ── Eine Ausführung ─────────────────────────────────────────────────────

   `fieldset` und `legend`, weil es genau das ist: eine benannte Gruppe von
   Feldern. Der Bildschirmleser sagt damit „Herren, Größe M, Menge" statt
   nur „Menge".                                                            */

.vis-matrix__group {
	margin: 0;
	padding: 0;
	border: 0;
	min-inline-size: 0;
}

.vis-matrix__group + .vis-matrix__group { margin-block-start: var(--vis-space-5); }

.vis-matrix__fit {
	display: flex;
	align-items: center;
	gap: var(--vis-space-2);

	float: left;          /* damit `legend` sich wie ein Block verhält */
	inline-size: 100%;
	margin: 0 0 var(--vis-space-3);
	padding: 0;

	color: var(--vis-text);
	font-family: var(--vis-font-mono);
	font-size: var(--vis-fs-label);
	letter-spacing: var(--vis-ls-label);
	text-transform: uppercase;
}

.vis-matrix__fit-count {
	display: inline-flex;
	align-items: center;
	justify-content: center;

	min-inline-size: 20px;
	block-size: 18px;
	padding-inline: 5px;
	border-radius: var(--vis-radius-full);
	background: var(--vis-accent);

	color: var(--vis-white);
	font-size: 11px;
	font-variant-numeric: tabular-nums;
	letter-spacing: 0;
}

.vis-matrix__fit-count[hidden] { display: none; }

/* ── Das Raster ──────────────────────────────────────────────────────────

   Neun Größen sollen im rechten Kaufbereich in **eine** Zeile passen. Das
   geht nur mit schmalen Zellen: 34 px Feldbreite plus 4 px Abstand. Enger
   wäre die Zahl nicht mehr zu treffen, breiter passt es nicht.           */

.vis-matrix__grid {
	display: grid;
	grid-template-columns: repeat(var(--vis-matrix-cols, 6), minmax(0, 1fr));
	gap: var(--vis-space-2) 4px;
	clear: both;
}

.vis-cell {
	display: grid;
	justify-items: center;
	gap: 4px;
	min-inline-size: 0;
}

.vis-cell__size {
	color: var(--vis-text-3);
	font-family: var(--vis-font-mono);
	font-size: 11px;
	line-height: 1;
	letter-spacing: 0.02em;
	text-align: center;
	white-space: nowrap;
	cursor: pointer;
}

.vis-cell.is-set .vis-cell__size {
	color: var(--vis-text);
	font-weight: var(--vis-fw-bold);
}

.vis-cell.is-out .vis-cell__size {
	color: var(--vis-text-disabled);
	text-decoration: line-through;
}

/* ── Das Mengenfeld ──────────────────────────────────────────────────────

   Klein, aber ein echtes Zahlenfeld: anklicken, überschreiben, fertig.
   Plus und Minus liegen darüber und erscheinen erst beim Überfahren oder
   im Fokus — sonst kosten sie neunmal Platz, den es nicht gibt.           */

/*
 * Breiter als nötig wird das Feld nicht.
 *
 * Ohne Obergrenze zog es sich über die ganze Spalte: bei 1023 px maß es
 * 154 Pixel — für eine zweistellige Zahl. Der Kaufbereich ist dort
 * einspaltig und damit sehr breit, und ein Eingabefeld, das aussieht wie
 * ein Textfeld, lädt zu allem Möglichen ein außer zu einer Menge.
 */
.vis-cell__box {
	position: relative;
	inline-size: min(100%, 72px);
}

.vis-cell__field {
	inline-size: 100%;
	min-inline-size: 0;
	block-size: 38px;

	border: var(--vis-border-width) solid var(--vis-border);
	border-radius: var(--vis-radius-sm);
	background: var(--vis-white);
	text-align: center;

	color: var(--vis-text);
	font-family: var(--vis-font-mono);
	font-size: var(--vis-fs-body);
	font-variant-numeric: tabular-nums;
	-moz-appearance: textfield;

	transition:
		border-color var(--vis-duration-micro) var(--vis-ease-out),
		background var(--vis-duration-micro) var(--vis-ease-out);
}

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

.vis-cell__field:hover { border-color: var(--vis-border-strong); }

.vis-cell__field:focus-visible {
	outline: var(--vis-focus-width) solid var(--vis-accent);
	outline-offset: 1px;
	border-color: var(--vis-accent);
}

.vis-cell__field[disabled] {
	background: var(--vis-bg-subtle);
	color: var(--vis-text-disabled);
	cursor: not-allowed;
}

/* Eine gesetzte Menge hebt sich ab — beim Überfliegen sieht man sofort,
   was in der Bestellung steht. */
.vis-cell.is-set .vis-cell__field {
	border-color: var(--vis-text);
	font-weight: var(--vis-fw-bold);
}

/* ── Stepper ─────────────────────────────────────────────────────────────

   Sie sind eine Bequemlichkeit, keine Bedingung: `tabindex="-1"` und
   `aria-hidden`, weil die Tastatur das Zahlenfeld selbst bedient. Auf
   Touch erscheinen sie dauerhaft — dort gibt es kein Überfahren, und
   tippen ist umständlicher als tippen.                                    */

.vis-cell__steps {
	position: absolute;
	inset-block: 1px;
	inset-inline-end: 1px;

	display: flex;
	flex-direction: column;
	inline-size: 15px;

	opacity: 0;
	pointer-events: none;
	transition: opacity var(--vis-duration-micro) var(--vis-ease-out);
}

.vis-cell__box:hover .vis-cell__steps,
.vis-cell__field:focus-visible ~ .vis-cell__steps {
	opacity: 1;
	pointer-events: auto;
}

.vis-cell__step {
	display: flex;
	flex: 1 1 50%;
	align-items: center;
	justify-content: center;

	padding: 0;
	border: 0;
	border-start-end-radius: var(--vis-radius-sm);
	background: var(--vis-bg-subtle);
	color: var(--vis-text-2);
	cursor: pointer;
}

.vis-cell__step + .vis-cell__step {
	border-start-end-radius: 0;
	border-end-end-radius: var(--vis-radius-sm);
}

.vis-cell__step:hover { background: var(--vis-border); color: var(--vis-text); }

.vis-cell__step[disabled] { cursor: not-allowed; opacity: 0.4; }

.vis-cell__step .vis-icon {
	inline-size: 10px;
	block-size: 10px;
}

/* Ohne Zeigegerät bleiben sie stehen: Auf einem Telefon gibt es kein
   Überfahren, mit dem sie erscheinen könnten. */
@media (hover: none) {
	.vis-cell__steps {
		opacity: 1;
		pointer-events: auto;
	}
}

.vis-cell__price {
	color: var(--vis-text-3);
	font-size: 10px;
	font-variant-numeric: tabular-nums;
	line-height: 1.2;
	text-align: center;
}

/* ── Weniger Spalten, wenn der Platz knapp wird ──────────────────────────

   `min()` statt fester Stufen: Ein Produkt mit fünf Größen behält seine
   fünf Spalten auch auf dem Handy, ein Produkt mit dreizehn fällt auf
   vier. Aufgefüllt wird nie — leere Spalten wären eine Auswahl, die es
   nicht gibt.                                                             */

@media (max-width: 1279.98px) {
	.vis-matrix__grid { grid-template-columns: repeat(min(var(--vis-matrix-cols, 6), 6), minmax(0, 1fr)); }
}

@media (max-width: 767.98px) {
	.vis-matrix__grid { grid-template-columns: repeat(min(var(--vis-matrix-cols, 5), 5), minmax(0, 1fr)); }
}

@media (max-width: 479.98px) {
	/* Vier Spalten, nicht drei: Acht Größen ergeben damit zwei volle
	   Reihen statt drei ungleicher. Produkte mit mehr Größen fallen
	   entsprechend auf mehr Reihen — aufgefüllt wird nie. */
	.vis-matrix__grid {
		grid-template-columns: repeat(min(var(--vis-matrix-cols, 4), 4), minmax(0, 1fr));
		gap: var(--vis-space-3) var(--vis-space-2);
	}

	/* Auf dem Handy ist Platz für ein größeres Ziel — und der Daumen
	   braucht ihn. */
	.vis-cell__field { block-size: 44px; }
	.vis-cell__size { font-size: var(--vis-fs-caption); }
}

/* ── Zusammenfassung ──────────────────────────────────────────────────────

   Eine **Vorschau**. Verbindlich rechnet der Server (E49). Sie bleibt auch
   bei null Stück stehen: Eine Zeile, die erst beim ersten Klick erscheint,
   verschiebt darunter alles — und der Knopf springt weg, während man ihn
   ansieht.

   Ein zusätzliches WooCommerce-Mengenfeld gibt es nicht: Die Summe der
   Felder **ist** die Bestellmenge.                                        */

.vis-team__sum {
	display: flex;
	align-items: baseline;
	justify-content: space-between;
	gap: var(--vis-space-3);

	margin: 0;
	padding-block: var(--vis-space-3);
	border-block-start: var(--vis-border-width) solid var(--vis-border);
}

.vis-team__sum p { margin: 0; }

.vis-team__sum-count {
	color: var(--vis-text);
	font-size: var(--vis-fs-body-s);
	font-variant-numeric: tabular-nums;
}

.vis-team__sum-count [data-visaro-team-count] { font-weight: var(--vis-fw-bold); }

.vis-team__sum-total {
	color: var(--vis-text);
	font-size: var(--vis-fs-body);
	font-weight: var(--vis-fw-bold);
	font-variant-numeric: tabular-nums;
}

.vis-team__sum.is-empty,
.vis-team__sum.is-empty .vis-team__sum-count { color: var(--vis-text-3); }

.vis-team__error {
	margin: 0;
	color: var(--vis-error, #B32419);
	font-size: var(--vis-fs-body-s);
}

.vis-team__error:empty { display: none; }

.vis-team__submit { width: 100%; }

.vis-team__submit.is-busy { opacity: 0.7; cursor: progress; }

.vis-team__submit[disabled] {
	opacity: 0.45;
	cursor: not-allowed;
}

@media (prefers-reduced-motion: reduce) {
	.vis-cell__field,
	.vis-cell__steps { transition: none; }
}


/* ══════════════════════════════════════════════════════════════════════════
   DESIGNKARTEN

   Ein Motiv wählt man mit den Augen. Die Karten sind trotzdem Radioknöpfe:
   Tastatur, Pfeiltasten, Pflichtprüfung und der Weg ohne JavaScript kommen
   dann vom Browser und müssen nicht nachgebaut werden.

   Drei nebeneinander im Kaufbereich, zwei auf schmalen Geräten. Vier wären
   im rechten Panel briefmarkengroß.
   ══════════════════════════════════════════════════════════════════════════ */

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

@media (max-width: 419.98px) {
	.vis-swatches { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

.vis-swatch {
	display: grid;
	gap: 6px;
	cursor: pointer;
	min-inline-size: 0;
}

/* Der Knopf selbst bleibt bedienbar und erreichbar, ist aber unsichtbar:
   Die Karte ist seine Beschriftung. */
.vis-swatch__input {
	position: absolute;
	width: 1px;
	height: 1px;
	margin: -1px;
	padding: 0;
	overflow: hidden;
	clip: rect(0 0 0 0);
	clip-path: inset(50%);
	white-space: nowrap;
	border: 0;
}

.vis-swatch__box {
	position: relative;
	display: flex;
	align-items: center;
	justify-content: center;

	aspect-ratio: 1 / 1;
	border: 2px solid var(--vis-border);
	border-radius: var(--vis-radius-sm);
	background: var(--vis-bg-subtle);
	overflow: hidden;

	transition: border-color var(--vis-duration-ui) var(--vis-ease-out);
}

/* Das Motiv sitzt vollständig in der Karte — angeschnitten wäre es
   ausgerechnet dort falsch, wo es um das Motiv geht (§8). */
.vis-swatch__box img {
	width: 100%;
	height: 100%;
	object-fit: contain;
	padding: 6%;
}

.vis-swatch__blank {
	color: var(--vis-text-3);
	font-family: var(--vis-font-mono);
	font-size: var(--vis-fs-h4);
}

.vis-swatch:hover .vis-swatch__box { border-color: var(--vis-text-3); }

.vis-swatch__input:checked + .vis-swatch__box {
	border-color: var(--vis-text);
	background: var(--vis-white);
}

.vis-swatch__input:focus-visible + .vis-swatch__box {
	outline: var(--vis-focus-width) solid var(--vis-accent);
	outline-offset: var(--vis-focus-offset);
}

.vis-swatch__name {
	color: var(--vis-text-2);
	font-size: var(--vis-fs-caption);
	line-height: var(--vis-lh-snug);
	text-align: center;
	overflow-wrap: anywhere;
}

.vis-swatch__input:checked ~ .vis-swatch__name {
	color: var(--vis-text);
	font-weight: var(--vis-fw-medium);
}

/* ══════════════════════════════════════════════════════════════════════════
   WARENKORB — UNIVERSELL

   Ein Warenkorb für alle Shopwelten. Hell, ruhig, transaktionsorientiert;
   die Welt erscheint über die Rollentokens und den Kopf, nicht über ein
   eigenes Layout (E59). Wer aus dem Feuerwehrshop kommt und später aus dem
   Vereinsshop, soll denselben Warenkorb bedienen.

   Drei Ebenen
   -----------
       .vis-cartgroup     ein Bestellvorgang
         .vis-cartgroup__fit   Herren, Damen …
           .vis-cartrow        eine Größe mit ihrer Menge

   Dieselben Klassen tragen Warenkorbseite und Drawer. Zwei Darstellungen
   desselben Warenkorbs laufen auseinander, sobald eine davon einen
   Sonderfall bekommt.

   Was hier nicht steht: „Kostenloser Versand", „30 Tage Rückgabe",
   „Morgen geliefert". Nichts davon ist geschäftlich entschieden (SH2,
   SH3, P3), und erfunden wird es nicht (Non-Negotiable 10).
   ══════════════════════════════════════════════════════════════════════════ */

@media (min-width: 1024px) {
	.vis-cart {
		display: grid;
		grid-template-columns: minmax(0, 64fr) minmax(0, 36fr);
		gap: var(--vis-space-8);
		align-items: start;
	}

	/* Feste Zeilen statt automatischer Platzierung (07.10.2026): WooCommerce
	   gibt seinen Hinweiscontainer in dieselbe Hülle aus. Er belegte, auch
	   leer, die erste Zelle links — die Artikel rutschten in Zeile 2 und
	   begannen erst unter der Bestellübersicht. Jetzt steht er über beiden
	   Spalten, und leer nimmt er keinen Platz. */
	.vis-cart { row-gap: 0; }

	.vis-cart > .woocommerce-notices-wrapper { grid-column: 1 / -1; grid-row: 1; }
	.vis-cart > .woocommerce-notices-wrapper:not(:empty) { margin-block-end: var(--vis-space-6); }

	.vis-cart__form { grid-column: 1; grid-row: 2; }

	.vis-cart__totals {
		grid-column: 2;
		grid-row: 2;
		position: sticky;
		inset-block-start: calc(var(--vis-shophead-height) + var(--vis-space-5));
	}
}

/* ── Eine Bestellung ────────────────────────────────────────────────────── */

.vis-cartlist {
	display: grid;
	gap: var(--vis-space-4);
	margin: 0;
	padding: 0;
	list-style: none;
}

.vis-cartgroup {
	position: relative;
	display: grid;
	gap: var(--vis-space-4);

	padding: var(--vis-space-5);
	border: var(--vis-border-width) solid var(--vis-border);
	border-radius: var(--vis-radius-md);
	background: var(--vis-white);
}

.vis-cartgroup.has-issue { border-color: var(--vis-error, #B32419); }

.vis-cartgroup__head {
	display: grid;
	grid-template-columns: auto minmax(0, 1fr) auto;
	gap: var(--vis-space-4);
	align-items: start;
}

/* ── Bild ────────────────────────────────────────────────────────────────

   Das ganze Produkt, mit Luft — dieselbe Regel wie überall (E66). Ein
   angeschnittenes Bild im Warenkorb lässt zweifeln, ob das Richtige drin
   liegt.                                                                  */

.vis-cartgroup__media {
	display: flex;
	align-items: center;
	justify-content: center;

	inline-size: 96px;
	aspect-ratio: 4 / 5;
	border-radius: var(--vis-radius-sm);
	background: var(--vis-bg-subtle);
	overflow: hidden;
}

.vis-cartgroup__media img {
	inline-size: 100%;
	block-size: 100%;
	display: block;

	object-fit: contain;
	padding: 8%;
	box-sizing: border-box;
}

.vis-cartgroup__ph {
	color: var(--vis-text-3);
	display: flex;
}

.vis-cartgroup__body { min-inline-size: 0; }

.vis-cartgroup__name {
	margin: 0 0 var(--vis-space-2);
	font-size: var(--vis-fs-body);
	font-weight: var(--vis-fw-bold);
	line-height: var(--vis-lh-snug);
}

.vis-cartgroup__name a { color: var(--vis-text); text-decoration: none; }
.vis-cartgroup__name a:hover { color: var(--vis-accent); }

/* ── Optionen ────────────────────────────────────────────────────────────

   Ortsname und Motiv stehen **einmal** über der Gruppe: Sie gelten für
   alle Größen, je Zeile wiederholt wären es fünfmal derselbe Ortsname.
   Beschriftungen, keine technischen Schlüssel.                            */

.vis-cartgroup__options {
	display: grid;
	gap: 2px;
	margin: 0;
}

.vis-cartgroup__options > div {
	display: flex;
	gap: var(--vis-space-2);
	font-size: var(--vis-fs-body-s);
	line-height: var(--vis-lh-snug);
}

.vis-cartgroup__options dt { color: var(--vis-text-3); }
.vis-cartgroup__options dt::after { content: ":"; }
.vis-cartgroup__options dd { margin: 0; color: var(--vis-text); }

.vis-cartgroup__issue {
	display: flex;
	align-items: flex-start;
	gap: var(--vis-space-2);
	margin: var(--vis-space-3) 0 0;

	color: var(--vis-error, #B32419);
	font-size: var(--vis-fs-body-s);
	line-height: var(--vis-lh-snug);
}

.vis-cartgroup__issue .vis-icon {
	flex: none;
	inline-size: 16px;
	block-size: 16px;
	margin-block-start: 1px;
}

.vis-cartgroup__issue a { color: inherit; }

.vis-cartgroup__remove {
	display: inline-flex;
	align-items: center;
	justify-content: center;

	inline-size: var(--vis-tap-target-min);
	block-size: var(--vis-tap-target-min);
	margin: calc(var(--vis-space-2) * -1) calc(var(--vis-space-2) * -1) 0 0;

	color: var(--vis-text-3);
	border-radius: var(--vis-radius-sm);
}

.vis-cartgroup__remove:hover { color: var(--vis-text); background: var(--vis-bg-subtle); }

.vis-cartgroup__remove:focus-visible {
	outline: var(--vis-focus-width) solid var(--vis-accent);
	outline-offset: calc(var(--vis-focus-offset) * -1);
}

/* ── Ausführungen und Größen ─────────────────────────────────────────────

   Herren und Damen untereinander, wie im Kaufbereich. Wer die Bestellung
   im Warenkorb wiedererkennen soll, muss sie so sehen, wie er sie
   eingegeben hat.                                                         */

.vis-cartgroup__fits {
	display: grid;
	gap: var(--vis-space-3);
}

.vis-cartgroup__fit {
	margin: 0;
	color: var(--vis-text-3);
	font-family: var(--vis-font-mono);
	font-size: var(--vis-fs-label);
	letter-spacing: var(--vis-ls-label);
	text-transform: uppercase;
}

.vis-cartrows {
	display: grid;
	margin: 0;
	padding: 0;
	list-style: none;
}

.vis-cartrow {
	display: grid;
	grid-template-columns: minmax(0, 1fr) auto auto;
	gap: var(--vis-space-3);
	align-items: center;

	min-block-size: 44px;
	border-block-start: var(--vis-border-width) solid var(--vis-border-subtle, var(--vis-border));
}

.vis-cartrow:first-child { border-block-start: 0; }

.vis-cartrow__label {
	color: var(--vis-text);
	font-size: var(--vis-fs-body-s);
	font-weight: var(--vis-fw-medium);
}

.vis-cartrow__out {
	display: block;
	color: var(--vis-error, #B32419);
	font-size: var(--vis-fs-caption);
	font-weight: var(--vis-fw-regular);
}

.vis-cartrow__total {
	color: var(--vis-text);
	font-size: var(--vis-fs-body-s);
	font-variant-numeric: tabular-nums;
	text-align: end;
	min-inline-size: 5.5em;
	white-space: nowrap;
}

/* ── Kleines Mengenfeld ──────────────────────────────────────────────────

   Dieselbe Bauform wie in der Größenmatrix: eine Zahl, die man
   überschreibt, mit Plus und Minus daneben. Null entfernt die Position —
   das ist die kürzeste Art, eine Größe wieder loszuwerden.                */

.vis-qtymini {
	display: inline-flex;
	align-items: center;

	border: var(--vis-border-width) solid var(--vis-border);
	border-radius: var(--vis-radius-full);
	background: var(--vis-white);
	overflow: hidden;
}

.vis-qtymini__step {
	display: inline-flex;
	align-items: center;
	justify-content: center;

	inline-size: 34px;
	block-size: 34px;
	border: 0;
	background: transparent;
	color: var(--vis-text-2);
	cursor: pointer;
}

.vis-qtymini__step:hover { background: var(--vis-bg-subtle); color: var(--vis-text); }

.vis-qtymini__step .vis-icon {
	inline-size: 13px;
	block-size: 13px;
}

.vis-qtymini__field {
	inline-size: 34px;
	block-size: 34px;
	border: 0;
	background: transparent;
	text-align: center;

	color: var(--vis-text);
	font-family: var(--vis-font-mono);
	font-size: var(--vis-fs-body-s);
	font-variant-numeric: tabular-nums;
	-moz-appearance: textfield;
}

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

.vis-qtymini__field:focus-visible {
	outline: var(--vis-focus-width) solid var(--vis-accent);
	outline-offset: calc(var(--vis-focus-offset) * -1);
}

/* ── Fuß einer Gruppe ───────────────────────────────────────────────────── */

.vis-cartgroup__foot {
	display: flex;
	align-items: baseline;
	justify-content: space-between;
	gap: var(--vis-space-3);

	padding-block-start: var(--vis-space-3);
	border-block-start: var(--vis-border-width) solid var(--vis-border);
}

.vis-cartgroup__foot p { margin: 0; }

.vis-cartgroup__count {
	color: var(--vis-text-3);
	font-size: var(--vis-fs-body-s);
	font-variant-numeric: tabular-nums;
}

.vis-cartgroup__sum {
	color: var(--vis-text);
	font-size: var(--vis-fs-body);
	font-weight: var(--vis-fw-bold);
	font-variant-numeric: tabular-nums;
}

.vis-cartgroup__edit {
	margin: 0;
	font-size: var(--vis-fs-caption);
}

.vis-cartgroup__edit a { color: var(--vis-text-3); }
.vis-cartgroup__edit a:hover { color: var(--vis-text); }

/* Eine einzelne Position braucht keine Zwischensumme: Sie steht schon in
   der Zeile. */
.vis-cartgroup:not(.vis-cartgroup--team) .vis-cartgroup__foot { display: none; }

/* ── Aktionen und Gutschein ──────────────────────────────────────────────

   Der Gutschein liegt zugeklappt. Ein offenes Feld fragt jeden Kunden, ob
   er einen Code hat — und die meisten haben keinen; die Frage lässt sie
   suchen gehen statt kaufen.                                              */

.vis-cart__actions {
	display: flex;
	flex-wrap: wrap;
	align-items: flex-start;
	justify-content: space-between;
	gap: var(--vis-space-4);
	margin-block-start: var(--vis-space-5);
}

.vis-cart__coupon { min-inline-size: 0; }

/* Als Zeile mit Mindesthöhe statt als nackter Text: Ein unterstrichenes
   Wort von 15 px Höhe ist auf dem Telefon kein Tippziel. */
.vis-cart__coupon-toggle {
	display: inline-flex;
	align-items: center;
	min-block-size: var(--vis-tap-target-min);

	cursor: pointer;
	color: var(--vis-text-2);
	font-size: var(--vis-fs-body-s);
	text-decoration: underline;
	text-underline-offset: 3px;
	list-style: none;
}

.vis-cart__coupon-toggle::-webkit-details-marker { display: none; }
.vis-cart__coupon-toggle:hover { color: var(--vis-text); }

.vis-cart__coupon-row {
	display: flex;
	gap: var(--vis-space-2);
	margin-block-start: var(--vis-space-3);
}

/* Das Feld gibt nach, der Knopf nicht — sonst schiebt „Einlösen" auf
   schmalen Bildschirmen über den Rand. */
.vis-cart__coupon-row .vis-input {
	flex: 1 1 auto;
	min-inline-size: 0;
	max-inline-size: 12rem;
}

.vis-cart__coupon-row .vis-btn { flex: 0 0 auto; }

/* Fokus für die Links und Schalter des Warenkorbs — dieselbe Sprache wie
   an Knöpfen und Mengenfeld. */
.vis-cart__coupon-toggle:focus-visible,
.vis-cartgroup__name a:focus-visible,
.vis-cartgroup__edit a:focus-visible,
.vis-cartgroup__issue a:focus-visible,
.vis-cartcontext__back:focus-visible {
	outline: var(--vis-focus-width) solid var(--vis-accent);
	outline-offset: var(--vis-focus-offset);
	border-radius: var(--vis-radius-xs);
}

/* Mit Skript übernimmt jede Eingabe sofort; ohne ist dieser Knopf der
   einzige Weg. Versteckt wird er deshalb erst von JavaScript. */
.vis-cart__form.is-live .vis-cart__update { display: none; }

/* ── Bestellübersicht ───────────────────────────────────────────────────── */

.vis-summary {
	padding: var(--vis-space-5);
	border: var(--vis-border-width) solid var(--vis-border);
	border-radius: var(--vis-radius-md);
	background: var(--vis-bg-subtle);
}

/* Die Warenkorbseite liegt im Seiteninhalt, und `.visaro-entry__content h2`
   gibt jeder Überschrift dort 40 px Abstand nach oben — in der Übersicht
   eine leere Fläche über dem Titel. Hier gilt die eigene Regel. */
.vis-summary > .vis-summary__title { margin-block-start: 0; }

.vis-summary__title {
	margin: 0 0 var(--vis-space-4);
	font-family: var(--vis-font-mono);
	font-size: var(--vis-fs-label);
	letter-spacing: var(--vis-ls-label);
	text-transform: uppercase;
}

.vis-summary__lines {
	display: grid;
	gap: var(--vis-space-2);
	margin: 0 0 var(--vis-space-4);
}

.vis-summary__line {
	display: flex;
	align-items: baseline;
	justify-content: space-between;
	gap: var(--vis-space-3);
	font-size: var(--vis-fs-body-s);
}

.vis-summary__line dt { color: var(--vis-text-2); }

.vis-summary__line dd {
	margin: 0;
	color: var(--vis-text);
	font-variant-numeric: tabular-nums;
	text-align: end;
}

.vis-summary__line--soft dd { color: var(--vis-text-3); }
.vis-summary__line--discount dd { color: var(--vis-accent); }

.vis-summary__line--total {
	margin-block-start: var(--vis-space-2);
	padding-block-start: var(--vis-space-3);
	border-block-start: var(--vis-border-width) solid var(--vis-border);
}

.vis-summary__line--total dt,
.vis-summary__line--total dd {
	color: var(--vis-text);
	font-size: var(--vis-fs-body-l);
	font-weight: var(--vis-fw-bold);
}

.vis-summary__line--total dd small {
	display: block;
	color: var(--vis-text-3);
	font-size: var(--vis-fs-caption);
	font-weight: var(--vis-fw-regular);
}

.vis-summary__block {
	display: flex;
	align-items: flex-start;
	gap: var(--vis-space-2);
	margin: 0 0 var(--vis-space-3);
	padding: var(--vis-space-3);
	border-radius: var(--vis-radius-sm);
	background: var(--vis-white);

	color: var(--vis-error, #B32419);
	font-size: var(--vis-fs-body-s);
	line-height: var(--vis-lh-snug);
}

.vis-summary__block .vis-icon {
	flex: none;
	inline-size: 16px;
	block-size: 16px;
	margin-block-start: 1px;
}

.vis-summary__secure {
	display: flex;
	align-items: center;
	gap: var(--vis-space-2);
	margin: var(--vis-space-3) 0 0;

	color: var(--vis-text-3);
	font-size: var(--vis-fs-caption);
	line-height: var(--vis-lh-snug);
}

.vis-summary__secure .vis-icon {
	flex: none;
	inline-size: 14px;
	block-size: 14px;
}

/* ── Leerer Warenkorb ───────────────────────────────────────────────────── */

.vis-cartempty {
	padding-block: var(--vis-space-12);
	text-align: center;
}

.vis-cartempty__title {
	margin: 0 0 var(--vis-space-2);
	font-size: var(--vis-fs-h3);
	font-weight: var(--vis-fw-bold);
	line-height: var(--vis-lh-heading);
	letter-spacing: var(--vis-ls-heading);
}

.vis-cartempty__text {
	margin: 0 auto var(--vis-space-6);
	max-inline-size: 40ch;
	color: var(--vis-text-2);
	line-height: var(--vis-lh-body);
}

.vis-cartempty--drawer {
	padding-block: var(--vis-space-10);
}

.vis-cartempty--drawer .vis-cartempty__title { font-size: var(--vis-fs-h4); }

/* ── Mobil ───────────────────────────────────────────────────────────────

   Kein Zweispaltenlayout erzwingen. Reihenfolge: Positionen, Übersicht,
   Kasse — in der Reihenfolge, in der man sie braucht.                     */

@media (max-width: 1023.98px) {
	.vis-cart__totals { margin-block-start: var(--vis-space-6); }
}

@media (max-width: 599.98px) {
	.vis-cartgroup { padding: var(--vis-space-4); }

	.vis-cartgroup__media { inline-size: 72px; }

	.vis-cartrow {
		grid-template-columns: minmax(0, 1fr) auto;
		grid-template-areas:
			"label qty"
			"total qty";
		row-gap: 0;
		padding-block: var(--vis-space-2);
	}

	.vis-cartrow__label { grid-area: label; }
	.vis-cartrow .vis-qtymini { grid-area: qty; align-self: center; }

	/* Der Zeilenbetrag ist auf dem Telefon der einzige Preis neben der
	   Menge. In Bildunterschriftgröße und dritter Textfarbe las er sich wie
	   eine Fußnote; eine Stufe größer und dunkler bleibt er trotzdem
	   unter dem Größennamen. */
	.vis-cartrow__total {
		grid-area: total;
		text-align: start;
		min-inline-size: 0;
		color: var(--vis-text-2);
		font-size: var(--vis-fs-body-s);
	}

	.vis-cart__actions { flex-direction: column; align-items: stretch; }
	.vis-cart__coupon-row .vis-input { max-inline-size: none; }
}

/* ── Mengenfeld auf Touch-Geräten ────────────────────────────────────────

   Zwei Probleme, eine Stelle. iOS vergrößert die Seite, sobald ein Feld
   mit weniger als 16 px Schrift den Fokus bekommt — das Mengenfeld stand
   auf 15 px, und jedes Antippen zoomte den Warenkorb heran. Und Plus und
   Minus waren mit 34 px kleiner als das Mindesttippziel.

   Nur für grobe Zeiger bzw. schmale Fenster: Am Schreibtisch bleibt das
   Feld so kompakt wie bisher. Gilt in Warenkorbseite **und** Drawer, weil
   beide denselben Baustein tragen. */
@media (pointer: coarse), (max-width: 767.98px) {
	.vis-qtymini__step {
		inline-size: var(--vis-tap-target-min);
		block-size: var(--vis-tap-target-min);
	}

	.vis-qtymini__field {
		inline-size: var(--vis-space-10);
		block-size: var(--vis-tap-target-min);
		font-size: var(--vis-fs-body);
	}
}

/* ══════════════════════════════════════════════════════════════════════════
   CART DRAWER

   Fährt von rechts ein, sobald etwas im Warenkorb landet — statt die
   Produktseite zu verlassen. Wer für eine Feuerwehr bestellt, legt selten
   einen Artikel hinein und geht zur Kasse; er legt fünf hinein.

   Inhalt sind dieselben Bausteine wie auf der Warenkorbseite, nur
   schmaler. Kopf und Fuß kleben, nur die Mitte rollt.
   ══════════════════════════════════════════════════════════════════════════ */

.vis-cartdrawer {
	position: fixed;
	inset: 0;
	z-index: var(--vis-z-drawer);
	visibility: hidden;
}

.vis-cartdrawer[hidden] { display: none; }
.vis-cartdrawer.is-open { visibility: visible; }

.vis-cartdrawer__scrim {
	position: absolute;
	inset: 0;
	background: var(--vis-ink-950);
	opacity: 0;
	transition: opacity var(--vis-duration-content) var(--vis-ease-out);
}

.vis-cartdrawer.is-open .vis-cartdrawer__scrim { opacity: 0.55; }

.vis-cartdrawer__panel {
	position: absolute;
	inset-block: 0;
	inset-inline-end: 0;

	display: flex;
	flex-direction: column;
	inline-size: min(460px, 100vw);

	background: var(--vis-bg);
	color: var(--vis-text);
	box-shadow: -12px 0 48px rgba(8, 9, 10, 0.16);

	transform: translateX(100%);
	transition: transform var(--vis-duration-content) var(--vis-ease-out);
}

.vis-cartdrawer.is-open .vis-cartdrawer__panel { transform: none; }

@media (max-width: 479.98px) {
	/* Auf dem Handy nahezu die ganze Fläche — ein 460 px breiter Streifen
	   auf 375 px Bildschirm wäre ein Fenster im Fenster. */
	.vis-cartdrawer__panel { inline-size: min(100vw, 100%); }
}

.vis-cartdrawer__head {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: var(--vis-space-3);

	padding: var(--vis-space-4) var(--vis-space-5);
	border-block-end: var(--vis-border-width) solid var(--vis-border);
}

.vis-cartdrawer__title {
	display: flex;
	align-items: baseline;
	gap: var(--vis-space-2);
	margin: 0;

	font-family: var(--vis-font-mono);
	font-size: var(--vis-fs-label);
	letter-spacing: var(--vis-ls-label);
	text-transform: uppercase;
}

.vis-cartdrawer__count {
	color: var(--vis-text-3);
	font-variant-numeric: tabular-nums;
	letter-spacing: 0;
	text-transform: none;
}

.vis-cartdrawer__count:empty { display: none; }

.vis-cartdrawer__close {
	display: inline-flex;
	align-items: center;
	justify-content: center;

	inline-size: var(--vis-tap-target-min);
	block-size: var(--vis-tap-target-min);
	margin-inline-end: calc(var(--vis-space-2) * -1);

	border: 0;
	background: transparent;
	color: var(--vis-text-2);
	cursor: pointer;
}

.vis-cartdrawer__close:hover { color: var(--vis-text); }

.vis-cartdrawer__close:focus-visible {
	outline: var(--vis-focus-width) solid var(--vis-accent);
	outline-offset: calc(var(--vis-focus-offset) * -1);
}

/* Eine Zeile, kein Toast über der halben Seite. Sie steht dort, wo man
   ohnehin hinschaut, und verschwindet mit dem Drawer. */
.vis-cartdrawer__note {
	display: flex;
	align-items: center;
	gap: var(--vis-space-2);
	margin: 0;

	padding: var(--vis-space-3) var(--vis-space-5);
	background: var(--vis-bg-subtle);

	color: var(--vis-text-2);
	font-size: var(--vis-fs-body-s);
}

.vis-cartdrawer__note[hidden] { display: none; }

/* ── Nur die Mitte rollt ─────────────────────────────────────────────────

   Kopf und Fuß kleben, der Hintergrund scrollt nicht mit
   (`overscroll-behavior`), und die Scrollposition der Seite bleibt beim
   Schließen erhalten — das erledigt der Overlay-Helfer in `shop.js`.      */

.vis-cartdrawer__body {
	flex: 1 1 auto;
	overflow-y: auto;
	overscroll-behavior: contain;
	-webkit-overflow-scrolling: touch;
	padding: var(--vis-space-4) var(--vis-space-5);
}

.vis-cartdrawer.is-busy .vis-cartdrawer__body { opacity: 0.6; }

.vis-cartdrawer__foot {
	border-block-start: var(--vis-border-width) solid var(--vis-border);
	background: var(--vis-bg);
}

.vis-cartdrawer__summary { padding: var(--vis-space-4) var(--vis-space-5); }
.vis-cartdrawer__summary[hidden] { display: none; }

.vis-cartdrawer__line {
	display: flex;
	align-items: baseline;
	justify-content: space-between;
	gap: var(--vis-space-3);
	font-size: var(--vis-fs-body);
}

.vis-cartdrawer__line strong { font-variant-numeric: tabular-nums; }

.vis-cartdrawer__hint {
	margin: var(--vis-space-1) 0 var(--vis-space-4);
	color: var(--vis-text-3);
	font-size: var(--vis-fs-caption);
}

.vis-cartdrawer__block {
	margin: 0 0 var(--vis-space-3);
	color: var(--vis-error, #B32419);
	font-size: var(--vis-fs-caption);
}

.vis-cartdrawer__actions {
	display: grid;
	gap: var(--vis-space-2);
}

/* Im Drawer ist die Karte schmal: Bild kleiner, Abstände enger, kein
   „Auswahl bearbeiten" — dafür ist eine Warenkorbseite da. */
.vis-cartlist--drawer .vis-cartgroup {
	padding: var(--vis-space-4);
	gap: var(--vis-space-3);
}

.vis-cartlist--drawer .vis-cartgroup__media { inline-size: 64px; }

.vis-cartlist--drawer .vis-cartgroup__name { font-size: var(--vis-fs-body-s); }

.vis-cartlist--drawer .vis-cartrow {
	grid-template-columns: minmax(0, 1fr) auto auto;
	min-block-size: 40px;
}

.vis-cartlist--drawer .vis-cartrow__total { min-inline-size: 4.5em; }

@media (prefers-reduced-motion: reduce) {
	.vis-cartdrawer__panel,
	.vis-cartdrawer__scrim { transition: none; }
}

/* ══════════════════════════════════════════════════════════════════════════
   MEGA-MENÜ

   Fünf Einstiege in einer Zeile, die Tiefe darunter. Vorher standen alle
   Kategorien der Shopwelt nebeneinander — mit vier Testkategorien passte
   das, mit neun echten brach die Zeile um. Diese Zeile wächst nicht mehr
   mit dem Sortiment.

   **Ohne JavaScript.** Aufgeklappt wird über `:hover` und `:focus-within`.
   Damit erreicht die Tabulatortaste dieselbe Fläche wie die Maus, ohne dass
   ein Skript Zustände verwaltet — und ein Mega-Menü, das erst nach dem
   Laden eines Bundles reagiert, fühlt sich zäh an, egal wie schnell das
   Bundle ist.

   Auf Touch gibt es kein Überfahren. Dort greift unter 1024 der Drawer.
   ══════════════════════════════════════════════════════════════════════════ */

.vis-shopnav {
	display: none;
	margin: 0;
	padding: 0;
	list-style: none;
}

/*
 * Die Navigation füllt die volle Kopfhöhe.
 *
 * Sie ist ein Rasterelement des Kopfes und war nur so hoch wie ihr Inhalt
 * — zwischen ihrer Unterkante und dem Kopfende blieben rund zwanzig Pixel
 * Luft. Die Tafel hängt aber am **Kopf** (`top: 100%`), nicht am Eintrag.
 * Wer mit der Maus nach unten fuhr, verließ auf diesem Streifen den
 * Eintrag, ohne die Tafel erreicht zu haben: `:hover` fiel weg, die Tafel
 * verschwand unter dem Zeiger.
 *
 * Mit voller Höhe grenzen Hoverzone und Tafel unmittelbar aneinander — es
 * gibt keinen Streifen mehr, über den man fallen könnte.
 */
@media (min-width: 1024px) {
	.vis-shophead__nav { align-self: stretch; }

	.vis-shopnav {
		display: flex;
		align-items: stretch;
		block-size: 100%;
		gap: var(--vis-space-1);

		/* Umbrechen ist keine Rückfalllösung, sondern der Fehler, der hier
		   behoben wird. Passt etwas nicht, soll es auffallen — nicht sich
		   still in eine zweite Zeile legen. */
		flex-wrap: nowrap;
	}
}

.vis-shopnav__item {
	position: static;
	display: flex;
	align-items: stretch;
}

.vis-shopnav__link {
	display: inline-flex;
	align-items: center;
	gap: 4px;

	padding-inline: var(--vis-space-3);
	border-radius: var(--vis-radius-sm);

	color: var(--vis-text-2);
	font-size: var(--vis-fs-body-s);
	font-weight: var(--vis-fw-medium);
	white-space: nowrap;
	text-decoration: none;

	transition: color var(--vis-duration-ui) var(--vis-ease-out);
}

.vis-shopnav__link:hover,
.vis-shopnav__item:focus-within .vis-shopnav__link { color: var(--vis-text); }

.vis-shopnav__link.is-current { color: var(--vis-text); }

.vis-shopnav__link:focus-visible {
	outline: var(--vis-focus-width) solid var(--vis-accent);
	outline-offset: calc(var(--vis-focus-offset) * -1);
}

.vis-shopnav__chevron {
	display: inline-flex;
	transition: transform var(--vis-duration-ui) var(--vis-ease-out);
}

.vis-shopnav__chevron .vis-icon {
	width: 14px;
	height: 14px;
}

.vis-shopnav__item:hover .vis-shopnav__chevron,
.vis-shopnav__item:focus-within .vis-shopnav__chevron,
.vis-shopnav__item.is-open .vis-shopnav__chevron { transform: rotate(180deg); }

/* ── Die Tafel ────────────────────────────────────────────────────────────

   Sie hängt am Kopf, nicht am Eintrag: Vier Spalten und eine Teaserfläche
   brauchen die ganze Breite, und eine Tafel, die unter dem dritten Eintrag
   beginnt, steht bei fünf Einträgen zwangsläufig schief.

   `visibility` statt `display`, damit der Übergang läuft. Solange sie zu
   ist, nimmt sie keine Klicks an.                                          */

.vis-mega { display: none; }

@media (min-width: 1024px) {
	.vis-mega {
		display: block;
		position: absolute;
		inset-inline: 0;
		inset-block-start: 100%;
		z-index: 60;

		border-block-start: var(--vis-border-width) solid var(--vis-border);
		background: var(--vis-bg);
		box-shadow: 0 18px 48px rgba(8, 9, 10, 0.10);

		visibility: hidden;
		opacity: 0;
		transform: translateY(-6px);
		pointer-events: none;

		transition:
			opacity var(--vis-duration-ui) var(--vis-ease-out),
			transform var(--vis-duration-ui) var(--vis-ease-out),
			visibility 0s linear var(--vis-duration-ui);
	}

	/*
	 * Zwei Wege, dasselbe Ziel.
	 *
	 * **Ohne JavaScript** öffnet `:hover` und `:focus-within` — dieselbe
	 * Fläche, die man mit der Maus erreicht, erreicht man mit der
	 * Tabulatortaste.
	 *
	 * **Mit JavaScript** übernimmt `.is-open`, und `.is-ready` am
	 * Navigationselement schaltet den reinen Hover ab. Sonst kämpften
	 * beide gegeneinander: Das Skript hält die Tafel nach dem Verlassen
	 * kurz offen, `:hover` hätte sie im selben Moment geschlossen.
	 */
	.vis-shopnav:not(.is-ready) .vis-shopnav__item:hover .vis-mega,
	.vis-shopnav:not(.is-ready) .vis-shopnav__item:focus-within .vis-mega,
	.vis-shopnav__item.is-open .vis-mega {
		visibility: visible;
		opacity: 1;
		transform: none;
		pointer-events: auto;
		transition-delay: 0s;
	}
}

.vis-mega__inner {
	display: grid;
	gap: var(--vis-space-8);
	align-items: start;

	max-inline-size: var(--vis-container-wide);
	margin-inline: auto;
	padding: var(--vis-space-8) var(--vis-gutter);
}

@media (min-width: 1280px) {
	/* Die Teaserfläche bekommt eine feste Spur, damit die Spalten links
	   nicht je nach Textlänge unterschiedlich breit werden. */
	.vis-mega__inner:has(.vis-mega__teaser) {
		grid-template-columns: minmax(0, 1fr) 300px;
	}
}

.vis-mega__cols {
	display: grid;
	gap: var(--vis-space-6);
	grid-template-columns: repeat(var(--vis-mega-cols, 4), minmax(0, 1fr));
}

.vis-mega__col { min-inline-size: 0; }

.vis-mega__head {
	display: block;
	margin: 0 0 var(--vis-space-3);
	padding-block-end: var(--vis-space-2);
	border-block-end: var(--vis-border-width) solid var(--vis-border);

	color: var(--vis-text);
	font-family: var(--vis-font-mono);
	font-size: var(--vis-fs-label);
	letter-spacing: var(--vis-ls-label);
	text-transform: uppercase;
	text-decoration: none;
}

.vis-mega__head:hover { color: var(--vis-accent); }

.vis-mega__head--plain { color: var(--vis-text-3); }

.vis-mega__list {
	display: grid;
	gap: 2px;
	margin: 0;
	padding: 0;
	list-style: none;
}

.vis-mega__link {
	display: flex;
	align-items: baseline;
	justify-content: space-between;
	gap: var(--vis-space-2);

	padding-block: 5px;
	color: var(--vis-text-2);
	font-size: var(--vis-fs-body-s);
	line-height: var(--vis-lh-snug);
	text-decoration: none;
}

.vis-mega__link:hover { color: var(--vis-text); }

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

/* „Anfrage" — was hinter dem Klick liegt, steht vor dem Klick da. */
.vis-mega__note {
	flex: none;
	padding: 1px var(--vis-space-2);
	border: var(--vis-border-width) solid var(--vis-border);
	border-radius: var(--vis-radius-full);

	color: var(--vis-text-3);
	font-family: var(--vis-font-mono);
	font-size: 10px;
	letter-spacing: var(--vis-ls-label);
	text-transform: uppercase;
	white-space: nowrap;
}

/* ── Teaserfläche ─────────────────────────────────────────────────────────

   Eine, nicht drei. Ein Mega-Menü mit drei Werbeflächen ist ein Prospekt.  */

.vis-mega__teaser {
	display: grid;
	gap: var(--vis-space-3);
	padding: var(--vis-space-4);
	border-radius: var(--vis-radius-md);
	background: var(--vis-bg-subtle);
	text-decoration: none;

	transition: background var(--vis-duration-ui) var(--vis-ease-out);
}

.vis-mega__teaser:hover { background: var(--vis-bg-surface); }

/* Bis zum Shooting ein beschrifteter Platzhalter mit Kennung — kein
   Stockfoto und kein graues Rechteck (Non-Negotiable 8, 13). */
.vis-mega__photo {
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	gap: var(--vis-space-2);

	aspect-ratio: 3 / 2;
	padding: var(--vis-space-4);
	border: var(--vis-border-width) dashed var(--vis-border-strong);
	border-radius: var(--vis-radius-sm);
	text-align: center;
}

.vis-mega__photo-id {
	color: var(--vis-text-2);
	font-family: var(--vis-font-mono);
	font-size: 10px;
	letter-spacing: var(--vis-ls-label);
}

.vis-mega__photo-motif {
	color: var(--vis-text-3);
	font-size: var(--vis-fs-caption);
	line-height: var(--vis-lh-snug);
}

.vis-mega__teaser-body {
	display: grid;
	gap: 6px;
}

.vis-mega__teaser-title {
	color: var(--vis-text);
	font-size: var(--vis-fs-body);
	font-weight: var(--vis-fw-bold);
}

.vis-mega__teaser-text {
	color: var(--vis-text-2);
	font-size: var(--vis-fs-body-s);
	line-height: var(--vis-lh-snug);
}

.vis-mega__teaser-cta {
	display: inline-flex;
	align-items: center;
	gap: var(--vis-space-2);
	color: var(--vis-accent);
	font-size: var(--vis-fs-body-s);
	font-weight: var(--vis-fw-medium);
}

.vis-mega__teaser-cta .vis-icon {
	width: 15px;
	height: 15px;
}

@media (prefers-reduced-motion: reduce) {
	.vis-mega,
	.vis-shopnav__chevron { transition: none; }
}

/* ── Drawer: dieselbe Struktur, ausgeklappt ─────────────────────────────── */

.vis-shopdrawer__group + .vis-shopdrawer__group {
	margin-block-start: var(--vis-space-5);
	padding-block-start: var(--vis-space-5);
	border-block-start: var(--vis-border-width) solid var(--vis-border);
}

.vis-shopdrawer__top {
	display: block;
	margin-block-end: var(--vis-space-2);

	color: var(--vis-text);
	font-family: var(--vis-font-mono);
	font-size: var(--vis-fs-label);
	letter-spacing: var(--vis-ls-label);
	text-transform: uppercase;
	text-decoration: none;
}

.vis-shopdrawer__top.is-current { color: var(--vis-accent); }

.vis-shopdrawer__item--sub {
	padding-inline-start: var(--vis-space-4);
	color: var(--vis-text-2);
	font-size: var(--vis-fs-body-s);
}

.vis-shopdrawer__note {
	padding: 1px var(--vis-space-2);
	border: var(--vis-border-width) solid var(--vis-border);
	border-radius: var(--vis-radius-full);

	color: var(--vis-text-3);
	font-family: var(--vis-font-mono);
	font-size: 10px;
	letter-spacing: var(--vis-ls-label);
	text-transform: uppercase;
}

/* Aktive Filter im Drawer.

   Auf dem Desktop stehen dieselben Marken über dem Raster. Im Drawer
   verdeckt die Überlagerung das Raster — ohne diese Zeile bliebe unklar,
   warum nur noch drei Produkte übrig sind. */
.vis-filters__active {
	display: flex;
	flex-wrap: wrap;
	gap: var(--vis-space-2);
	margin-block-end: var(--vis-space-4);
	padding-block-end: var(--vis-space-4);
	border-block-end: var(--vis-border-width) solid var(--vis-border);
}

@media (min-width: 1024px) {
	/* Dort stehen sie schon über dem Raster; zweimal dieselbe Zeile
	   untereinander wäre eine Wiederholung, kein Hinweis. */
	.vis-filters__active { display: none; }
}

/* ══════════════════════════════════════════════════════════════════════════
   PRODUKTDETAILS

   Links der Text, rechts die Fakten — die Aufteilung aus §37. Sie hat einen
   Grund über die Optik hinaus: Beschreibungstexte sind unterschiedlich
   lang, Faktenlisten sind kurz und gleichförmig. Untereinander gestellt
   schiebt ein langer Text die Fakten aus dem Blick; nebeneinander stehen
   sie da, wo man sie sucht.

   Auf schmalen Geräten stehen sie untereinander, Fakten zuletzt: Wer auf
   dem Handy scrollt, will zuerst wissen, was das Produkt ist.
   ══════════════════════════════════════════════════════════════════════════ */

.vis-detail {
	display: grid;
	gap: var(--vis-space-8);
	align-items: start;
}

@media (min-width: 1024px) {
	.vis-detail { grid-template-columns: minmax(0, 1.6fr) minmax(0, 1fr); }
}

.vis-detail__title {
	margin: 0 0 var(--vis-space-3);
	font-size: var(--vis-fs-h4);
	line-height: var(--vis-lh-snug);
}

.vis-detail__title + .vis-detail__text { margin-block-end: var(--vis-space-8); }
.vis-detail__text + .vis-detail__title { margin-block-start: var(--vis-space-2); }

.vis-detail__text {
	color: var(--vis-text-2);
	line-height: var(--vis-lh-body);
	max-inline-size: 68ch;
}

.vis-detail__text p { margin: 0 0 var(--vis-space-4); }
.vis-detail__text p:last-child { margin-block-end: 0; }

.vis-detail__text ul {
	margin: 0 0 var(--vis-space-4);
	padding-inline-start: var(--vis-space-5);
}

.vis-detail__text li { margin-block-end: var(--vis-space-1); }

/* ── Fakten ───────────────────────────────────────────────────────────────

   Eine Liste, keine Tabelle mit Rahmen: Es sind zwei Spalten, und zwei
   Spalten brauchen keine Gitterlinien, um lesbar zu sein.                  */

.vis-detail__facts {
	padding: var(--vis-space-5);
	border-radius: var(--vis-radius-md);
	background: var(--vis-bg-subtle);
}

.vis-facts {
	display: grid;
	gap: 0;
	margin: 0;
}

.vis-facts__row {
	display: grid;
	grid-template-columns: minmax(0, 0.9fr) minmax(0, 1.1fr);
	gap: var(--vis-space-3);

	padding-block: var(--vis-space-3);
	border-block-start: var(--vis-border-width) solid var(--vis-border);
}

.vis-facts__row:first-child { border-block-start: 0; padding-block-start: 0; }

.vis-facts dt {
	color: var(--vis-text-3);
	font-size: var(--vis-fs-body-s);
}

.vis-facts dd {
	margin: 0;
	color: var(--vis-text);
	font-size: var(--vis-fs-body-s);
	overflow-wrap: anywhere;
}

/* ── Detailbilder ───────────────────────────────────────────────────────── */

.vis-detail__shots {
	display: grid;
	gap: var(--vis-space-4);
	margin-block-start: var(--vis-space-10);
}

@media (min-width: 768px) {
	.vis-detail__shots { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

.vis-detail__shot {
	margin: 0;
	border-radius: var(--vis-radius-md);
	background: var(--vis-bg-subtle);
	overflow: hidden;
}

.vis-detail__shot img {
	inline-size: 100%;
	block-size: 100%;
	display: block;

	/* Auch hier vollständig: Ein Detailbild, das seinen eigenen Gegenstand
	   anschneidet, zeigt nichts (§8). */
	aspect-ratio: 4 / 3;
	object-fit: contain;
	padding: var(--vis-media-pad);
	box-sizing: border-box;
}

/* ══════════════════════════════════════════════════════════════════════════
   BEWERTUNGSFORMULAR

   Nicht dauerhaft sichtbar. Sechshundert Pixel Formular unter den
   Bewertungen sind der Preis dafür, dass ein Bruchteil der Besucher
   tatsächlich eine schreibt — und sie stehen ausgerechnet dort, wo die
   anderen weiterlesen wollen.

   Ohne JavaScript bleibt der Kasten ein gewöhnlicher Block und das
   Formular steht offen: `.is-ready` setzt das Skript, und erst damit
   greifen die Regeln für die Überlagerung. Ein Formular, das ohne Skript
   unerreichbar wäre, wäre kein Fortschritt, sondern ein Rückschritt.

   Desktop ein Dialog in der Mitte, Handy eine Tafel von unten — dort ist
   der Daumen, und ein zentrierter Dialog über der Tastatur ist auf einem
   Telefon nicht bedienbar.
   ══════════════════════════════════════════════════════════════════════════ */

.vis-reviews__head {
	display: flex;
	flex-wrap: wrap;
	align-items: flex-end;
	justify-content: space-between;
	gap: var(--vis-space-4);
}

.vis-reviews__actions {
	display: flex;
	flex-wrap: wrap;
	gap: var(--vis-space-2);
}

.vis-reviews__empty > .vis-btn { margin-block-start: var(--vis-space-4); }

/* Vor `is-ready`: ein Block wie jeder andere. */
.vis-reviewsheet__scrim { display: none; }

.vis-reviewsheet.is-ready {
	position: fixed;
	inset: 0;
	z-index: var(--vis-z-drawer);
	visibility: hidden;
}

.vis-reviewsheet.is-ready[hidden] { display: none; }
.vis-reviewsheet.is-ready.is-open { visibility: visible; }

.vis-reviewsheet.is-ready .vis-reviewsheet__scrim {
	display: block;
	position: absolute;
	inset: 0;
	background: var(--vis-ink-950);
	opacity: 0;
	transition: opacity var(--vis-duration-content) var(--vis-ease-out);
}

.vis-reviewsheet.is-ready.is-open .vis-reviewsheet__scrim { opacity: 0.6; }

.vis-reviewsheet__panel {
	margin-block-start: var(--vis-space-8);
	border: var(--vis-border-width) solid var(--vis-border);
	border-radius: var(--vis-radius-md);
	background: var(--vis-white);
}

.vis-reviewsheet.is-ready .vis-reviewsheet__panel {
	position: absolute;
	inset-block-end: 0;
	inset-inline: 0;
	margin: 0;

	display: flex;
	flex-direction: column;
	max-block-size: 92vh;

	border: 0;
	border-start-start-radius: var(--vis-radius-lg);
	border-start-end-radius: var(--vis-radius-lg);

	transform: translateY(100%);
	transition: transform var(--vis-duration-content) var(--vis-ease-out);
}

.vis-reviewsheet.is-ready.is-open .vis-reviewsheet__panel { transform: none; }

@media (min-width: 768px) {
	.vis-reviewsheet.is-ready .vis-reviewsheet__panel {
		inset: 50% auto auto 50%;
		inline-size: min(38rem, calc(100vw - var(--vis-space-8)));
		max-block-size: 86vh;

		border-radius: var(--vis-radius-lg);
		transform: translate(-50%, -46%);
		opacity: 0;
		transition:
			transform var(--vis-duration-content) var(--vis-ease-out),
			opacity var(--vis-duration-content) var(--vis-ease-out);
	}

	.vis-reviewsheet.is-ready.is-open .vis-reviewsheet__panel {
		transform: translate(-50%, -50%);
		opacity: 1;
	}
}

.vis-reviewsheet__head {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: var(--vis-space-3);

	padding: var(--vis-space-4) var(--vis-space-5);
	border-block-end: var(--vis-border-width) solid var(--vis-border);
}

.vis-reviewsheet__title {
	margin: 0;
	font-family: var(--vis-font-mono);
	font-size: var(--vis-fs-label);
	letter-spacing: var(--vis-ls-label);
	text-transform: uppercase;
}

.vis-reviewsheet__close {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	inline-size: var(--vis-tap-target-min);
	block-size: var(--vis-tap-target-min);
	border: 0;
	background: transparent;
	color: var(--vis-text-2);
	cursor: pointer;
}

.vis-reviewsheet__close:hover { color: var(--vis-text); }

.vis-reviewsheet__close:focus-visible {
	outline: var(--vis-focus-width) solid var(--vis-accent);
	outline-offset: calc(var(--vis-focus-offset) * -1);
}

.vis-reviewsheet__body { padding: var(--vis-space-5); }

.vis-reviewsheet.is-ready .vis-reviewsheet__body {
	flex: 1 1 auto;
	overflow-y: auto;
	overscroll-behavior: contain;
}

@media (prefers-reduced-motion: reduce) {
	.vis-reviewsheet__panel,
	.vis-reviewsheet__scrim { transition: none; }
}

/* Eine Tafel, die höher ist als der Bildschirm.

   Bei 1025 px maß sie 1089 px: Die Teaserfläche bekommt ihre eigene
   Spalte erst ab 1280 und stand darunter als volle Breite unter den
   Kategorien — mit einem Platzhalterbild im Verhältnis 3:2, also über
   fünfhundert Pixel allein dafür.

   Unter 1280 entfällt deshalb das Bild und der Teaser wird zu einer
   Zeile. Und darüber liegt eine Obergrenze mit eigenem Rollbereich: Was
   künftig dazukommt — mehr Kategorien, längere Namen —, darf die Tafel
   nicht wieder aus dem Bild schieben. */
@media (min-width: 1024px) {
	.vis-mega__inner {
		max-block-size: calc(100vh - var(--vis-fire-head-small, 64px) - var(--vis-shophead-top));
		overflow-y: auto;
		overscroll-behavior: contain;
	}
}

@media (min-width: 1024px) and (max-width: 1279.98px) {
	.vis-mega__photo { display: none; }

	.vis-mega__teaser {
		display: flex;
		align-items: center;
		justify-content: space-between;
		gap: var(--vis-space-5);
	}

	.vis-mega__teaser-text { display: none; }
}

/* „Menge" statt des Produktnamens: Die Zeile eines einfachen Produkts
   trägt keine eigene Bezeichnung, nur die Rolle. Leiser gesetzt, damit
   sie nicht wie eine Größe aussieht. */
.vis-cartrow__label--quiet { color: var(--vis-text-3); }

/* ══ 16 — Vereinsauswahl ═════════════════════════════════════════════════

   `/produkt-kategorie/vereine/` ist eine Frage mit drei Antworten, kein
   Sortiment. Sie liegt außerhalb der Vereinsshops und trägt deshalb
   VISARO-Farben — die Vereinsfarbe steht auf der jeweiligen Karte.

   Dieses Stück gehört zu `shop.css` und nicht zu `club.css`: Die Seite
   läuft im neutralen Shopkontext, `club.css` lädt dort nicht.            */

.vis-clubpick__inner {
	max-inline-size: var(--vis-container-wide);
	margin-inline: auto;
	padding-inline: var(--vis-gutter);
}

.vis-clubpick__head { padding-block: var(--vis-section-m) var(--vis-space-8); }

.vis-clubpick__title {
	margin: var(--vis-space-5) 0 0;

	font-size: var(--vis-fs-display-l);
	font-weight: var(--vis-fw-bold);
	line-height: var(--vis-lh-display);
	letter-spacing: var(--vis-ls-display);
}

.vis-clubpick__text {
	margin-block-start: var(--vis-space-4);
	max-inline-size: 58ch;

	font-size: var(--vis-fs-body-l);
	color: var(--vis-text-2);
}

.vis-clubpick__list { padding-block-end: var(--vis-section-m); }

.vis-clubcards {
	display: grid;
	gap: var(--vis-grid-gap);

	/* Feste Spaltenzahl, kein `auto-fill`: Drei Vereine sollen drei
	   Spalten sein, nicht zwei plus eine verlorene. */
	grid-template-columns: 1fr;

	margin: 0;
	padding: 0;
	list-style: none;
}

@media (min-width: 640px)  { .vis-clubcards { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (min-width: 1024px) { .vis-clubcards { grid-template-columns: repeat(3, minmax(0, 1fr)); } }

.vis-clubcard__link {
	position: relative;

	display: flex;
	flex-direction: column;
	align-items: flex-start;
	gap: var(--vis-space-3);
	block-size: 100%;

	padding: var(--vis-space-8) var(--vis-space-6) var(--vis-space-6);

	color: var(--vis-text);
	text-decoration: none;

	background: var(--vis-white);
	border: var(--vis-border-width) solid var(--vis-border);
	border-radius: var(--vis-radius-md);

	transition:
		border-color var(--vis-duration-ui) var(--vis-ease-out),
		transform var(--vis-duration-ui) var(--vis-ease-out);
}

.vis-clubcard__link:hover,
.vis-clubcard__link:focus-visible {
	border-color: var(--vis-club-primary);
	transform: translateY(-2px);
}

/* Die Vereinsfarbe als Band oben — das stärkste Element der Karte, ohne
   die ganze Fläche einzufärben. */
.vis-clubcard__band {
	position: absolute;
	inset-block-start: 0;
	inset-inline: 0;

	block-size: var(--vis-space-2);

	background: var(--vis-club-primary);
	border-start-start-radius: var(--vis-radius-md);
	border-start-end-radius: var(--vis-radius-md);
}

.vis-clubcard__crest-img {
	inline-size: 84px;
	block-size: 84px;
	object-fit: contain;
}

.vis-clubcard__name {
	font-size: var(--vis-fs-h3);
	font-weight: var(--vis-fw-bold);
	letter-spacing: var(--vis-ls-heading);
	line-height: var(--vis-lh-snug);
	color: var(--vis-club-strong);
}

.vis-clubcard__count {
	font-size: var(--vis-fs-body-s);
	color: var(--vis-text-3);
}

.vis-clubcard__cta {
	display: inline-flex;
	align-items: center;
	gap: var(--vis-space-2);

	margin-block-start: auto;
	padding-block-start: var(--vis-space-4);

	font-size: var(--vis-fs-body-s);
	font-weight: var(--vis-fw-medium);
	color: var(--vis-club-strong);
}

.vis-clubcard__cta svg {
	inline-size: 16px;
	block-size: 16px;

	transition: transform var(--vis-duration-micro) var(--vis-ease-out);
}

.vis-clubcard__link:hover .vis-clubcard__cta svg { transform: translateX(3px); }

.vis-clubpick__more {
	margin-block-start: var(--vis-space-8);
	font-size: var(--vis-fs-body-s);
	color: var(--vis-text-2);
}

/* ══════════════════════════════════════════════════════════════════════════
   VOM KLICK ZUM PAKET

   Vier Schritte, waagrecht auf dem Desktop, senkrecht auf dem Handy.

   Die Linie zwischen den Marken ist das, was die vier Kästen zu einem
   Weg macht. Sie liegt hinter den Marken, nicht zwischen ihnen: Ein Strich
   je Lücke wäre drei Elemente mehr im Markup und bräche an jeder anderen
   Spaltenzahl. So ist es eine Linie, die von den Marken verdeckt wird.
   ══════════════════════════════════════════════════════════════════════════ */

.vis-process {
	margin-block-start: var(--vis-space-12);
	padding-block: var(--vis-space-8);
	border-block-start: var(--vis-border-width) solid var(--vis-border-subtle);
}

.vis-process__title {
	margin: 0 0 var(--vis-space-6);
	font-size: var(--vis-fs-h4);
	font-weight: var(--vis-fw-medium);
	letter-spacing: -0.01em;
}

.vis-process__list {
	position: relative;

	display: grid;
	grid-template-columns: repeat(var(--vis-process-cols, 4), 1fr);
	gap: var(--vis-space-6);

	margin: 0;
	padding: 0;
	list-style: none;
	counter-reset: none;
}

/* Die durchgehende Linie auf Höhe der Marken. Sie beginnt und endet in der
   Mitte der äußeren Marke, damit sie nicht ins Leere läuft. */
.vis-process__list::before {
	content: "";
	position: absolute;
	inset-block-start: 21px;
	inset-inline: calc(100% / var(--vis-process-cols, 4) / 2);

	block-size: var(--vis-border-width);
	background: var(--vis-border);
}

.vis-process__step {
	display: grid;
	gap: var(--vis-space-3);
	justify-items: start;
	margin: 0;
}

/* ── Die Marke: Nummer und Symbol ───────────────────────────────────────── */

.vis-process__mark {
	position: relative;
	z-index: 1;

	display: inline-flex;
	align-items: center;
	gap: var(--vis-space-2);

	min-block-size: 42px;
	padding-inline: var(--vis-space-3);

	border: var(--vis-border-width) solid var(--vis-border);
	border-radius: var(--vis-radius-full);
	background: var(--vis-white);
	color: var(--vis-world-accent-text, var(--vis-text));
}

.vis-process__num {
	font-family: var(--vis-font-mono);
	font-size: var(--vis-fs-caption);
	font-weight: var(--vis-fw-medium);
	color: var(--vis-text-3);
	font-variant-numeric: tabular-nums;
}

.vis-process__mark svg {
	inline-size: 20px;
	block-size: 20px;
}

/* ── Text ───────────────────────────────────────────────────────────────── */

.vis-process__body { max-inline-size: 34ch; }

.vis-process__step-title {
	margin: 0 0 var(--vis-space-1);
	font-size: var(--vis-fs-body);
	font-weight: var(--vis-fw-medium);
}

.vis-process__text {
	margin: 0;
	font-size: var(--vis-fs-body-s);
	line-height: 1.55;
	color: var(--vis-text-2);
}

.vis-process__note {
	margin-block-start: var(--vis-space-6);
	max-inline-size: 68ch;

	font-size: var(--vis-fs-body-s);
	color: var(--vis-text-2);
}

/* ── Kompakt: nur die Kette, ohne Erklärung ─────────────────────────────── */

.vis-process--compact { padding-block: var(--vis-space-5); }

.vis-process--compact .vis-process__list { gap: var(--vis-space-4); }

.vis-process--compact .vis-process__step-title { font-size: var(--vis-fs-body-s); }

/* ── Drei Schritte statt vier ───────────────────────────────────────────── */

/* Ein Artikel ohne Veredelung hat einen Schritt weniger. Die Spaltenzahl
   ergibt sich dann aus der Kette selbst — ohne eine zweite Klasse im
   Markup, die jemand zu setzen vergessen könnte. */
.vis-process__list:has(.vis-process__step:nth-child(3):last-child) {
	--vis-process-cols: 3;
}

/* ── Mobil: senkrecht, mit Linie durch die Marken ───────────────────────── */

@media (max-width: 767.98px) {
	.vis-process__list {
		--vis-process-cols: 1;
		gap: var(--vis-space-5);
	}

	.vis-process__list::before {
		inset-block: 21px;
		inset-inline: 20px auto;

		inline-size: var(--vis-border-width);
		block-size: auto;
	}

	.vis-process__step {
		grid-template-columns: auto 1fr;
		align-items: start;
		gap: var(--vis-space-4);
	}

	/* Auf einer Spalte trägt die Nummer die Reihenfolge allein — das Symbol
	   daneben würde die Marke so breit machen, dass für den Text nichts
	   bleibt. */
	.vis-process__mark {
		inline-size: 42px;
		justify-content: center;
		padding-inline: 0;
	}

	.vis-process__num { display: none; }

	.vis-process__body { max-inline-size: none; }
}

/* ══════════════════════════════════════════════════════════════════════════
   KAUFEN AUF DEM HANDY

   Die Kaufspalte ist am Schreibtisch eine Spalte neben dem Bild. Auf dem
   Handy ist sie die Seite: Alles, was zwischen Bild und Knopf steht, muss
   mit einem Daumen bedienbar sein und darf keine Zeile verschwenden.

   Drei Eingriffe, mehr nicht:

     Tippziele   Größen und Ausführungen auf 48 px — 44 trifft man, 48
                 trifft man auch mit kalten Fingern am Spielfeldrand.
     Rhythmus    Weniger Abstand zwischen den Achsen. Vorher standen
                 zwischen „Ausführung" und „Größe" zwei leere Zeilen, weil
                 der Abstand für zwei nebeneinanderstehende Felder gemacht
                 war — auf dem Handy stehen sie untereinander.
     Handlung    Der Kaufknopf nimmt die volle Breite. Ein Knopf, der auf
                 halber Strecke aufhört, sieht aus wie ein Vorschlag.
   ══════════════════════════════════════════════════════════════════════════ */

@media (max-width: 767.98px) {
	.vis-pdp .variations td { margin-block-end: var(--vis-space-4); }

	.vis-sizes {
		gap: var(--vis-space-2);
		margin-block-start: var(--vis-space-3);
	}

	.vis-size {
		min-block-size: 48px;
		min-inline-size: 62px;
		font-size: var(--vis-fs-body);
	}

	.vis-sizes__wait { min-block-size: 48px; }

	/* Menge und Kaufen untereinander statt nebeneinander: Nebeneinander
	   bleiben dem Knopf rund 220 px, und die Menge ändert fast niemand. */
	.vis-pdp .woocommerce-variation-add-to-cart,
	.vis-pdp form.cart:not(.variations_form) {
		display: grid;
		grid-template-columns: minmax(0, 1fr);
		gap: var(--vis-space-3);
	}

	.vis-pdp .single_add_to_cart_button {
		inline-size: 100%;
		min-block-size: 52px;
	}

	.vis-qty { justify-self: start; }

	/* Die Ablaufkette steht auf dem Handy direkt unter der Beschreibung
	   und braucht dort keinen zusätzlichen Rahmen. */
	.vis-process { padding-block: var(--vis-space-6); }
}

/* ══════════════════════════════════════════════════════════════════════════
   DIE ERSTE ACHSE IST EINE REITERLEISTE

   Ausführung und Größe stellen zwei verschiedene Fragen: „für wen" und
   „welche". Solange beide als gleich aussehende Chips nebeneinander
   standen, las sich das als eine lange Liste mit einem Umbruch darin.

   Die Ausführung bekommt deshalb die Form, die sie im Sportfachhandel
   ohnehin hat — eine segmentierte Leiste. Sie steht auf ruhigem Grund,
   der gewählte Reiter hebt sich als Fläche ab.
   ══════════════════════════════════════════════════════════════════════════ */

.vis-sizes--axis {
	display: inline-flex;
	flex-wrap: wrap;
	gap: var(--vis-space-1);

	padding: var(--vis-space-1);
	border-radius: var(--vis-radius-md);
	background: var(--vis-bg-subtle);
}

.vis-sizes--axis .vis-size {
	min-inline-size: 88px;
	min-block-size: 40px;
	padding-inline: var(--vis-space-4);

	border-color: transparent;
	background: transparent;
	border-radius: var(--vis-radius-sm);
}

.vis-sizes--axis .vis-size:hover { background: var(--vis-white); }

.vis-sizes--axis .vis-size[aria-pressed="true"] {
	background: var(--vis-white);
	border-color: var(--vis-border);
	color: var(--vis-text);
	box-shadow: 0 1px 2px rgb(0 0 0 / 8%);
}

.visaro-club .vis-sizes--axis .vis-size[aria-pressed="true"] {
	background: var(--vis-club-primary);
	border-color: var(--vis-club-primary);
	color: var(--vis-club-on);
}

/* „Zurücksetzen" ist entfallen: Die Ausführung lässt sich direkt wechseln,
   und ein Link, der nichts ermöglicht, was nicht ohnehin geht, ist ein
   Angebot zum Nachdenken über ein gelöstes Problem. */
.vis-pdp .reset_variations { display: none; }

/* ══════════════════════════════════════════════════════════════════════════
   VOM KLICK ZUM PAKET — EIGENER ABSCHNITT

   Die Kette stand im Detailbereich darüber. Der ist ab 1024 px
   zweispaltig, und sie landete als drittes Rasterkind in der linken
   Spalte: vier Schritte auf knapp die Hälfte der Breite.

   Jetzt ist sie ein eigener Abschnitt über die volle Contentbreite — mit
   Abstand davor, damit sie nicht an der Beschreibung klebt, und ohne
   eigene Kante: Die Linie darüber gehört dem Detailbereich, zwei
   Haarlinien in Folge wären eine zu viel.
   ══════════════════════════════════════════════════════════════════════════ */

.vis-pdp__process { margin-block-start: var(--vis-section-m); }

.vis-pdp__process .vis-process {
	margin-block-start: 0;
	padding-block: var(--vis-space-10) 0;
}

.vis-pdp__process .vis-process__title {
	margin-block-end: var(--vis-space-8);
	font-size: var(--vis-fs-h3);
}

/* Der Detailbereich ist **einspaltig**: Was darin zweispaltig steht,
   ordnet `.vis-detail` selbst. Die zweite Spalte hier schob die
   Detailbilder neben den Text statt darunter. */
@media (min-width: 1024px) {
	.vis-pdp__detail-inner {
		grid-template-columns: minmax(0, 1fr);
		gap: var(--vis-space-12);
	}
}

/* ══════════════════════════════════════════════════════════════════════════
   SHOPWELTEN-ÜBERSICHT (/shop/)

   Dieselbe Haltung wie die Vereinsauswahl darunter: eine Frage, wenige
   Karten, fertig. Sie ist bewusst **ruhiger** als die Vereinskarten — dort
   trägt jede Karte eine Vereinsfarbe, hier steht VISARO.
   ══════════════════════════════════════════════════════════════════════════ */

.vis-worlds__inner {
	max-inline-size: var(--vis-container-wide);
	margin-inline: auto;
	padding-inline: var(--vis-gutter);
}

.vis-worlds__head { padding-block: var(--vis-section-m) var(--vis-space-8); }

.vis-worlds__title {
	margin: var(--vis-space-5) 0 0;

	font-size: var(--vis-fs-display-l);
	font-weight: var(--vis-fw-bold);
	line-height: var(--vis-lh-display);
	letter-spacing: var(--vis-ls-display);
}

.vis-worlds__text {
	margin-block-start: var(--vis-space-4);
	max-inline-size: 58ch;

	font-size: var(--vis-fs-body-l);
	color: var(--vis-text-2);
}

.vis-worlds__list { padding-block-end: var(--vis-section-m); }

.vis-worldcards {
	display: grid;
	gap: var(--vis-grid-gap);
	grid-template-columns: 1fr;

	margin: 0;
	padding: 0;
	list-style: none;
}

@media (min-width: 768px) {
	.vis-worldcards { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

.vis-worldcard__link {
	display: grid;
	grid-template-columns: auto minmax(0, 1fr);
	grid-template-areas:
		"mark body"
		"go   go";
	gap: var(--vis-space-5);
	align-items: start;

	block-size: 100%;
	padding: var(--vis-space-8);

	border: var(--vis-border-width) solid var(--vis-border);
	border-radius: var(--vis-radius-md);
	background: var(--vis-white);
	text-decoration: none;
	color: inherit;

	transition:
		border-color var(--vis-duration-ui) var(--vis-ease-out),
		transform var(--vis-duration-ui) var(--vis-ease-out);
}

.vis-worldcard__link:hover,
.vis-worldcard__link:focus-visible {
	border-color: var(--vis-text);
	transform: translateY(-2px);
}

@media (prefers-reduced-motion: reduce) {
	.vis-worldcard__link { transition: none; }
	.vis-worldcard__link:hover { transform: none; }
}

.vis-worldcard__mark {
	grid-area: mark;

	display: grid;
	place-items: center;

	inline-size: 52px;
	block-size: 52px;

	border-radius: var(--vis-radius-sm);
	background: var(--vis-bg-subtle);
	color: var(--vis-text);
}

.vis-worldcard__mark svg {
	inline-size: 24px;
	block-size: 24px;
}

.vis-worldcard__body { grid-area: body; display: block; }

.vis-worldcard__name {
	display: block;
	font-size: var(--vis-fs-h3);
	font-weight: var(--vis-fw-bold);
	line-height: var(--vis-lh-snug);
}

.vis-worldcard__note {
	display: block;
	margin-block-start: var(--vis-space-2);
	max-inline-size: 44ch;

	font-size: var(--vis-fs-body-s);
	line-height: 1.55;
	color: var(--vis-text-2);
}

.vis-worldcard__go {
	grid-area: go;

	display: inline-flex;
	align-items: center;
	gap: var(--vis-space-2);

	margin-block-start: var(--vis-space-6);
	font-size: var(--vis-fs-body-s);
	font-weight: var(--vis-fw-medium);
}

.vis-worldcard__go svg {
	inline-size: 16px;
	block-size: 16px;
	transition: transform var(--vis-duration-ui) var(--vis-ease-out);
}

.vis-worldcard__link:hover .vis-worldcard__go svg { transform: translateX(3px); }


/* Bild der Karte: blutet bis an den Kartenrand, die 60°-Kante unten rechts
   ist dieselbe wie an den Werkstattbildern. Wappen stehen ruhig auf Weiß. */
.vis-worldcard__link { grid-template-areas: "media media" "mark body" "go go"; overflow: hidden; }

.vis-worldcard__media {
	grid-area: media;
	display: block;
	aspect-ratio: 16 / 9;
	margin: calc(var(--vis-space-8) * -1) calc(var(--vis-space-8) * -1) var(--vis-space-2);
	overflow: hidden;
	background: var(--vis-bg-dark);
}

.vis-worldcard__image {
	display: block;
	inline-size: 100%;
	block-size: 100%;
	object-fit: cover;
	transition: transform var(--vis-duration-content) var(--vis-ease-out);
}

.vis-worldcard__link:hover .vis-worldcard__image,
.vis-worldcard__link:focus-visible .vis-worldcard__image { transform: scale(1.03); }

.vis-worldcard__media--crests {
	display: flex;
	align-items: center;
	justify-content: center;
	gap: var(--vis-space-8);
	padding: var(--vis-space-6);
	background: var(--vis-bg-subtle);
	border-block-end: var(--vis-border-width) solid var(--vis-border);
}

.vis-worldcard__crest {
	inline-size: auto;
	block-size: 72%;
	max-inline-size: 28%;
	object-fit: contain;
}

@media (prefers-reduced-motion: reduce) {
	.vis-worldcard__link:hover .vis-worldcard__image { transform: none; }
}
.vis-worlds__soon {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: var(--vis-space-3);

	margin-block-start: var(--vis-space-10);
	padding-block-start: var(--vis-space-6);
	border-block-start: var(--vis-border-width) solid var(--vis-border-subtle);

	font-size: var(--vis-fs-body-s);
	color: var(--vis-text-2);
}

/* ══════════════════════════════════════════════════════════════════════════
   GALERIE: DIE „+3"-KACHEL

   Die Vorschauspalte hatte `max-height: 640px` und `overflow-y: auto`. Bei
   sieben Bildern entstand daneben eine zweite Scrollfläche — das Mausrad
   über der Spalte bewegte die Vorschau statt der Seite. Die Grenze ist
   jetzt die Anzahl, nicht die Höhe.
   ══════════════════════════════════════════════════════════════════════════ */

.vis-gal__thumb--more { position: relative; }

.vis-gal__more {
	position: absolute;
	inset: 0;

	display: grid;
	place-items: center;

	background: rgb(8 8 12 / 62%);
	color: var(--vis-white);

	font-family: var(--vis-font-mono);
	font-size: var(--vis-fs-body-s);
	font-weight: var(--vis-fw-medium);
	font-variant-numeric: tabular-nums;
}

.vis-gal__thumb--more:hover .vis-gal__more { background: rgb(8 8 12 / 74%); }

/* ── Wischen, nicht ziehen ─────────────────────────────────────────────────

   Die Bildstrecke ist eine waagrechte Scrollfläche. Ohne
   `overscroll-behavior` gibt der Browser die Bewegung an die Seite weiter,
   sobald das letzte Bild erreicht ist: Wer auf dem Handy durch die Bilder
   wischt, schiebt am Ende die ganze Seite zur Seite. Genau der Sprung, der
   eine Produktseite unruhig macht.                                        */

.vis-gal__track { overscroll-behavior-x: contain; }


/* ══════════════════════════════════════════════════════════════════════════
   EINZELBESTELLUNG ODER TEAMBESTELLUNG

   Zwei Ansichten, **eine** davon sichtbar. Umgeschaltet wird der Zustand,
   nicht der Inhalt: Beide Formulare stehen vollständig im Markup und
   behalten ihre Eingaben.

   Warum die Klassen hier `vis-clubteam__…` heißen
   -----------------------------------------------
   Weil `vis-team__…` schon vergeben ist — an die Größenmatrix des
   Feuerwehrshops (E58). Der erste Anlauf hat den Namen mitbenutzt, und
   damit galt `.vis-team { display: grid }` aus dem Feuerwehrteil auch für
   den Vereinsblock. `display` schlägt das `hidden`-Attribut: Die
   Teamansicht stand sichtbar **unter** der Einzelbestellung, obwohl sie im
   Markup versteckt war.

   Zwei Komponenten, die sich einen Klassennamen teilen, sind keine
   Ersparnis — sie sind eine Verabredung, an die sich niemand erinnert.
   ══════════════════════════════════════════════════════════════════════════ */

/* ── Der Schalter ──────────────────────────────────────────────────────────

   Ein Schalter, keine zwei Reiter. Reiter sagen „hier sind zwei gleich
   wichtige Wege"; tatsächlich ist die Einzelbestellung der Normalfall und
   die Teambestellung die Ausnahme, die man einschaltet.                   */

.vis-teamtoggle {
	display: flex;
	align-items: center;
	gap: var(--vis-space-3);

	inline-size: 100%;
	margin-block-end: var(--vis-space-6);
	padding: var(--vis-space-3) var(--vis-space-4);

	border: var(--vis-border-width) solid var(--vis-border);
	border-radius: var(--vis-radius-md);
	background: var(--vis-white);

	cursor: pointer;
	text-align: start;
	font-family: inherit;
	color: inherit;

	transition: border-color var(--vis-duration-ui) var(--vis-ease-out);
}

.vis-teamtoggle:hover { border-color: var(--vis-text); }

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

/* Die Wippe. Sie ist nur Gestaltung — den Zustand trägt `aria-pressed`
   am Knopf, und daran hängen auch die Regeln darunter. */
.vis-teamtoggle__switch {
	position: relative;
	flex: 0 0 auto;

	inline-size: 44px;
	block-size: 26px;

	border-radius: var(--vis-radius-full);
	background: var(--vis-border);

	transition: background-color var(--vis-duration-ui) var(--vis-ease-out);
}

.vis-teamtoggle__switch::after {
	content: "";
	position: absolute;
	inset-block-start: 3px;
	inset-inline-start: 3px;

	inline-size: 20px;
	block-size: 20px;

	border-radius: var(--vis-radius-full);
	background: var(--vis-white);

	transition: transform var(--vis-duration-ui) var(--vis-ease-out);
}

.vis-teamtoggle[aria-pressed="true"] .vis-teamtoggle__switch {
	background: var(--vis-world-accent, var(--vis-text));
}

.vis-teamtoggle[aria-pressed="true"] .vis-teamtoggle__switch::after {
	transform: translateX(18px);
}

@media (prefers-reduced-motion: reduce) {
	.vis-teamtoggle,
	.vis-teamtoggle__switch,
	.vis-teamtoggle__switch::after { transition: none; }
}

.vis-teamtoggle__text {
	display: grid;
	gap: 2px;
	min-inline-size: 0;
}

.vis-teamtoggle__title {
	font-size: var(--vis-fs-body);
	font-weight: var(--vis-fw-medium);
}

.vis-teamtoggle__note {
	font-size: var(--vis-fs-body-s);
	color: var(--vis-text-2);
}

/* ── Die Teamansicht ───────────────────────────────────────────────────── */

.vis-clubteam {
	display: grid;
	gap: var(--vis-space-5);
}

.vis-clubteam__label {
	margin: 0 0 var(--vis-space-2);
	font-size: var(--vis-fs-label);
	font-weight: var(--vis-fw-medium);
	letter-spacing: 0.06em;
	text-transform: uppercase;
	color: var(--vis-text-2);
}

.vis-clubteam__rows {
	display: grid;
	gap: var(--vis-space-2);
	margin: 0;
	padding: 0;
	list-style: none;
}

/* Größe · (Preis) · Menge · Beschriftung.

   Flex statt Grid: Die Preisspalte gibt es nur, wenn sich die Preise
   innerhalb der Ausführung unterscheiden. Ein festes Raster hätte für
   jeden Fall eine eigene Spaltenangabe gebraucht. */
.vis-clubteam__row {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: var(--vis-space-3);

	padding: var(--vis-space-2) var(--vis-space-3);
	border: var(--vis-border-width) solid var(--vis-border-subtle);
	border-radius: var(--vis-radius-sm);
	background: var(--vis-white);
}

.vis-clubteam__row.is-picked { border-color: var(--vis-world-accent, var(--vis-text)); }
.vis-clubteam__row.is-out { color: var(--vis-text-disabled); }

.vis-clubteam__size {
	flex: 0 0 4rem;
	font-weight: var(--vis-fw-medium);
	font-variant-numeric: tabular-nums;
}

.vis-clubteam__price {
	font-size: var(--vis-fs-body-s);
	color: var(--vis-text-2);
}

.vis-clubteam__out { font-size: var(--vis-fs-body-s); }

/* ── Menge ─────────────────────────────────────────────────────────────── */

.vis-clubteam__qty {
	display: inline-grid;
	grid-template-columns: 36px 46px 36px;
	align-items: center;

	border: var(--vis-border-width) solid var(--vis-border);
	border-radius: var(--vis-radius-sm);
	overflow: hidden;
}

.vis-clubteam__step {
	min-block-size: 40px;

	border: 0;
	background: var(--vis-bg-subtle);
	color: var(--vis-text);
	font-size: var(--vis-fs-body);
	line-height: 1;
	cursor: pointer;
}

.vis-clubteam__step:hover { background: var(--vis-border-subtle); }

.vis-clubteam__input {
	min-block-size: 40px;

	border: 0;
	background: var(--vis-white);
	text-align: center;
	font-family: inherit;
	font-size: var(--vis-fs-body-s);
	font-variant-numeric: tabular-nums;

	-moz-appearance: textfield;
}

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

.vis-clubteam__persoinput {
	inline-size: 100%;
	min-block-size: 40px;
	padding-inline: var(--vis-space-3);

	border: var(--vis-border-width) solid var(--vis-border);
	border-radius: var(--vis-radius-sm);
	background: var(--vis-white);

	font-family: inherit;
	font-size: var(--vis-fs-body-s);
}

/* ── Summe ─────────────────────────────────────────────────────────────── */

.vis-clubteam__foot {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: var(--vis-space-4);

	padding-block-start: var(--vis-space-5);
	border-block-start: var(--vis-border-width) solid var(--vis-border-subtle);
}

.vis-clubteam__sum {
	margin: 0;
	margin-inline-end: auto;

	font-size: var(--vis-fs-body);
	font-weight: var(--vis-fw-medium);
	font-variant-numeric: tabular-nums;
}

.vis-clubteam__submit:disabled {
	opacity: 0.45;
	cursor: not-allowed;
}

.vis-clubteam__note {
	margin: 0;
	font-size: var(--vis-fs-body-s);
	color: var(--vis-text-2);
}

@media (max-width: 767.98px) {
	/* Auf dem Handy steht die Beschriftung unter Größe und Menge: Drei
	   Spalten nebeneinander lassen dem Namensfeld rund 90 px. */
	.vis-clubteam__row {
		gap: var(--vis-space-2) var(--vis-space-3);
		padding: var(--vis-space-3);
	}

	.vis-clubteam__foot { gap: var(--vis-space-3); }

	.vis-clubteam__submit { inline-size: 100%; }

	.vis-teamtoggle { padding: var(--vis-space-3); }
}

/* Die Beschriftung einer einzelnen Warenkorbzeile. Sie erscheint nur,
   wenn sie sich von den übrigen Zeilen der Gruppe unterscheidet — sonst
   steht sie einmal darüber (E71, E96). */
.vis-cartrow__opt {
	display: inline-block;
	margin-inline-start: var(--vis-space-2);
	padding: 2px var(--vis-space-2);

	border-radius: var(--vis-radius-xs);
	background: var(--vis-bg-subtle);

	font-size: var(--vis-fs-caption);
	font-weight: var(--vis-fw-regular);
	color: var(--vis-text-2);
}

/* ── Beschriftung je Stück ─────────────────────────────────────────────────

   Vier Trikots in Größe S können vier verschiedene Namen tragen. Die
   Felder entstehen deshalb erst mit der Menge und stehen unter der Zeile,
   nicht daneben: Neben Größe und Mengenfeld blieben ihnen rund neunzig
   Pixel.

   Zwei Spalten, wo Platz ist. Eine Mannschaft hat selten drei Namen,
   sondern vierzehn — untereinander wäre das eine sehr lange Liste.       */

.vis-clubteam__names {
	display: grid;
	grid-template-columns: repeat(2, minmax(0, 1fr));
	gap: var(--vis-space-2);

	inline-size: 100%;
	margin-block-start: var(--vis-space-1);
	padding-block-start: var(--vis-space-3);
	border-block-start: var(--vis-border-width) dashed var(--vis-border-subtle);
}

.vis-clubteam__name {
	display: flex;
	align-items: center;
	gap: var(--vis-space-2);
	min-inline-size: 0;
}

/* Die laufende Nummer ist kein Schmuck: Sie sagt, welches Stück gemeint
   ist — und auf dem Produktionszettel steht dieselbe Reihenfolge. */
.vis-clubteam__nameno {
	flex: 0 0 auto;

	min-inline-size: 1.5rem;
	font-family: var(--vis-font-mono);
	font-size: var(--vis-fs-caption);
	font-variant-numeric: tabular-nums;
	color: var(--vis-text-3);
	text-align: end;
}

.vis-clubteam__name .vis-clubteam__persoinput {
	min-block-size: 38px;
	min-inline-size: 0;
}

@media (max-width: 767.98px) {
	/* Eine Spalte: Zwei Namensfelder nebeneinander sind bei 390 px
	   zusammen kaum breiter als eines. */
	.vis-clubteam__names { grid-template-columns: minmax(0, 1fr); }
}

/* ── Summe ─────────────────────────────────────────────────────────────── */

.vis-clubteam__sums {
	display: grid;
	gap: 2px;
	margin: 0;
	margin-inline-end: auto;
}

.vis-clubteam__sum {
	font-size: var(--vis-fs-body);
	font-weight: var(--vis-fw-medium);
	font-variant-numeric: tabular-nums;
}

.vis-clubteam__extra {
	font-size: var(--vis-fs-body-s);
	font-weight: var(--vis-fw-regular);
	color: var(--vis-text-2);
	font-variant-numeric: tabular-nums;
}

/* Ein Stück ohne Beschriftung, dort wo die anderen eine tragen. Bewusst
   leiser gesetzt: Es ist kein Fehler, sondern eine Entscheidung. */
.vis-cartrow__opt--none {
	background: transparent;
	border: var(--vis-border-width) dashed var(--vis-border);
	color: var(--vis-text-3);
	font-style: italic;
}

/* Zwei Symbole rechts in der mobilen Leiste: Konto und Warenkorb.
   Dasselbe Muster wie im Feuerwehr- und im Vereinskopf. */
@media (max-width: 1023.98px) {
	.vis-shophead__mobile-end {
		display: flex;
		align-items: center;
		gap: var(--vis-space-1);
	}
}

/* ══════════════════════════════════════════════════════════════════════════
   KASSE — DIE BESTELLÜBERSICHT PASST AUF DAS TELEFON
   Gemessen bei 375 px: WooCommerce' eigene Übersichtstabelle war 372 px
   breit in einem 356 px schmalen Fenster — die einzige Seite des Shops mit
   waagrechtem Scrollen. Ursache ist die Tabelle selbst: Sie richtet sich
   nach dem längsten Produktnamen, und ein Vereinstrikot mit Ausführung,
   Größe und Beschriftung ist lang.

   `table-layout: fixed` nimmt ihr das ab: Die Spalten teilen sich die
   verfügbare Breite, der Name bricht um. Kein Scrollcontainer — eine
   Bestellübersicht, die man seitlich schieben muss, liest niemand.
   ══════════════════════════════════════════════════════════════════════════ */

.woocommerce-checkout-review-order-table {
	inline-size: 100%;
	max-inline-size: 100%;
	table-layout: fixed;
	border-collapse: collapse;
}

.woocommerce-checkout-review-order-table th,
.woocommerce-checkout-review-order-table td {
	overflow-wrap: anywhere;
	word-break: normal;
}

/* Die Betragsspalte braucht nur so viel, wie eine Zahl breit ist. */
.woocommerce-checkout-review-order-table .product-total,
.woocommerce-checkout-review-order-table td:last-child,
.woocommerce-checkout-review-order-table th:last-child {
	inline-size: 40%;
	text-align: end;
	white-space: normal;
	font-variant-numeric: tabular-nums;
}

.woocommerce-checkout-review-order-table .order-total .includes_tax { display: block; }
.woocommerce-checkout-review-order-table td[colspan="2"] { inline-size: auto; text-align: start; }
.vis-delivery { border: 0; padding: 12px 0; margin: 0; min-inline-size: 0; }
.vis-delivery legend { font-weight: 700; font-size: 18px; padding: 0 0 12px; }
.vis-delivery__choices { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; }
.vis-delivery__choice { position: relative; min-inline-size: 0; }
.woocommerce .vis-delivery__choice label {
	display: block; height: 100%; box-sizing: border-box; cursor: pointer;
	padding: 16px 12px 16px 34px; border: 2px solid var(--vis-border); border-radius: 8px;
	background: var(--vis-white); color: var(--vis-text); font-size: 15px; line-height: 1.4;
}
.vis-delivery__choice input { position: absolute; top: 21px; left: 12px; accent-color: var(--vis-accent); }
.vis-delivery__choice input:checked + label { border-color: var(--vis-accent); background: var(--vis-bg-subtle); }
.vis-delivery__choice input:focus-visible + label { outline: 2px solid var(--vis-text); outline-offset: 3px; }
.vis-delivery__choice strong, .vis-delivery__choice small, .vis-delivery__choice .amount { display: block; }
.vis-delivery__choice small { margin-top: 6px; font-size: 12px; color: var(--vis-text-2); font-weight: 400; }
@media (max-width: 420px) { .vis-delivery__choices { grid-template-columns: minmax(0, 1fr); } }

@media (max-width: 480px) {
	.woocommerce-checkout-review-order-table th,
	.woocommerce-checkout-review-order-table td {
		padding-inline: var(--vis-space-2);
		font-size: var(--vis-fs-body-s);
	}

	.woocommerce-checkout-review-order-table th:first-child,
	.woocommerce-checkout-review-order-table td:first-child { padding-inline-start: 0; }

	.woocommerce-checkout-review-order-table th:last-child,
	.woocommerce-checkout-review-order-table td:last-child { padding-inline-end: 0; }
}

/* „Design bearbeiten" führt zurück in den Konfigurator. Ein Textlink, kein
   Knopf: Der Hauptweg im Warenkorb ist die Kasse, und zwei gleich starke
   Knöpfe nebeneinander lassen offen, welcher gemeint ist. */
.vis-cartgroup__edit {
	margin: var(--vis-space-2) 0 0;
}

.vis-cartgroup__edit a {
	display: inline-flex;
	align-items: center;
	gap: var(--vis-space-1);
	min-block-size: var(--vis-tap-target-min);
	color: var(--vis-text-2);
	font-size: var(--vis-fs-body-s);
}

.vis-cartgroup__edit svg {
	inline-size: 15px;
	block-size: 15px;
	flex: 0 0 auto;
}

.vis-cartgroup__edit a:hover { color: var(--vis-text); }

/* Die Vorschau der gestalteten Fläche steht im selben Rahmen wie ein
   Produktfoto — sie ersetzt es, sie ergänzt es nicht. */
.vis-cartgroup__media img {
	inline-size: 100%;
	block-size: 100%;
	object-fit: contain;
}

/* Auch lange Filterlisten bleiben in der Desktop-Seitenspalte erreichbar. */
.vis-quantity-pricing { margin-block: 0 28px; padding-block: 20px; border-block: 1px solid var(--vis-border, #dedbd4); }
.vis-quantity-pricing h2 { margin: 0 0 12px; font-size: 1.1rem; }
.vis-quantity-pricing p { margin: 8px 0; font-size: .875rem; line-height: 1.5; }
.vis-quantity-pricing table { width: 100%; margin-block: 12px; border-collapse: collapse; font-variant-numeric: tabular-nums; font-size: .95rem; }
.vis-quantity-pricing th, .vis-quantity-pricing td { padding: 8px 10px; border-bottom: 1px solid var(--vis-border, #dedbd4); text-align: left; }
.vis-quantity-pricing td, .vis-quantity-pricing thead th:last-child { text-align: right; }
.vis-quantity-pricing tbody th { font-weight: 400; }
.vis-quantity-pricing tr.is-current { background: #f1f0e7; color: #08080c; }
.vis-quantity-pricing tr.is-current th, .vis-quantity-pricing tr.is-current td { font-weight: 700; }
.vis-quantity-pricing__note { color: var(--vis-text-2, #52525b); }
.vis-quantity-pricing__selection { font-weight: 700; }

@media (min-width: 1024px) {
	.vis-filters { max-block-size: calc(100vh - var(--vis-shophead-height) - 64px); max-block-size: calc(100dvh - var(--vis-shophead-height) - 64px); overflow-y: auto; padding-inline: 3px; }
}
