/*
Theme Name: b4-shop
Theme URI: https://black4st.de
Author: Blackforest Research
Description: Klassisches Theme für black4st.de ohne Page-Builder. WooCommerce- und Germanized-Ausgaben laufen unverändert über die Standard-Hooks; das Theme liefert Rahmen und Gestaltung. Design aus design/, übernommen mit design/bin/sync-design.
Version: 1.0.0
Requires at least: 6.0
Requires PHP: 8.0
License: GNU General Public License v2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html
Text Domain: b4-shop
Tags: e-commerce, custom-menu, translation-ready
*/

/* --------------------------------------------------------------------------
   Die Gestaltung liegt in assets/css/tokens.css und assets/css/site.css und wird
   aus dem Design-Projekt übernommen — dort NICHT von Hand ändern, sondern im
   Design-Projekt und anschließend `design/bin/sync-design` ausführen.

   Diese Datei enthält nur, was WordPress und WooCommerce zusätzlich brauchen und
   im statischen Design-Entwurf nicht vorkommen konnte.
   -------------------------------------------------------------------------- */

/* Von WordPress erwartete Hilfsklassen (Barrierefreiheit, Ausrichtung, Medien). */
.screen-reader-text {
	position: absolute;
	width: 1px;
	height: 1px;
	padding: 0;
	margin: -1px;
	overflow: hidden;
	clip: rect(0, 0, 0, 0);
	white-space: nowrap;
	border: 0;
}

.skip-link:focus {
	position: fixed;
	top: 0.5rem;
	left: 0.5rem;
	z-index: 10000;
	width: auto;
	height: auto;
	clip: auto;
	padding: var(--space-sm) var(--space-lg);
	background: var(--bg, #111);
	color: var(--fg, #fff);
	outline: 2px solid var(--accent, #c60);
}

.alignleft   { float: left;  margin: 0 var(--space-xl) var(--space-md) 0; }
.alignright  { float: right; margin: 0 0 var(--space-md) var(--space-xl); }
.aligncenter { display: block; margin-inline: auto; }

.wp-caption img { max-width: 100%; height: auto; }
.wp-caption-text,
.wp-block-image figcaption { font-size: var(--fs-sm); opacity: 0.75; }

/* Icons aus dem lokalen Sprite (siehe inc/assets.php, b4_icon). Ersetzt die im Design
   per CDN nachgeladene Lucide-Bibliothek; Größe folgt der Schriftgröße wie im Original. */
.b4-icon {
	display: inline-block;
	flex: none;
	width: 1em;
	height: 1em;
	vertical-align: middle;
	stroke: currentColor;
	fill: none;
}

/* Breite Tabellen (Warenkorb, Bestellübersicht) sollen auf schmalen Viewports nicht
   das Layout sprengen. */
.woocommerce table.shop_table { width: 100%; }


/* ==========================================================================
   WooCommerce → Design-Optik (Produktseite)

   Die Brücke zwischen zwei Markup-Welten: links die Klassen, die WooCommerce und
   Germanized ausgeben, rechts das Aussehen, das das Design für .pdp / .buy-box /
   .bb-* vorsieht (design/styles/site.css, Zeilen 1971–2000).

   Bewusst als CSS und nicht als Template-Override: So bleibt jede Ausgabe dort, wo
   das Plugin sie erzeugt — Preis, Verfügbarkeit, MwSt.-Hinweis, Versandkosten und
   Lieferzeit sind damit garantiert dynamisch (CLAUDE.md, Abschnitt 4, Regeln 1–3).
   Reihenfolge und Umschließung regelt inc/woocommerce.php.

   Sämtliche Werte kommen aus den Design-Tokens. Wo Geometrie aus site.css gespiegelt
   werden musste (Button, Titelstufe), steht die Quelle im Kommentar — ändert sich das
   Design dort, ist hier nachzuziehen.
   ========================================================================== */

/* Icons, die als CSS-Maske gebraucht werden, weil das Element aus einem Plugin kommt und
   sich kein <use> auf das Sprite setzen lässt. Form identisch mit assets/icons/lucide-sprite.svg;
   die Farbe kommt über background-color, wie bei jedem anderen Icon auch. */
:root {
	--b4-icon-chevron: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23A69C8C' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
}

/* Einblend-Animationen absichern.
   `site.css` setzt `.fx { opacity: 0 }`; sichtbar wird der Inhalt erst, wenn app.js die
   Klasse `in` ergänzt. Im statischen Entwurf ist das unkritisch — in einem Shop wäre ein
   Produkttext, der bei einem JavaScript-Fehler unsichtbar bleibt, ein echter Schaden.
   Das Inline-Script in header.php setzt `js` auf <html>; ohne JavaScript greift die
   Animation gar nicht erst. */
html:not(.js) .fx {
	opacity: 1;
	transform: none;
}

/* In den zugeklappten Produktreitern gilt das immer: Ein inaktiver Reiter ist
   `display:none`, wird vom Beobachter nie erfasst und bliebe nach dem Umschalten
   dauerhaft unsichtbar. migration/10-produktinhalte.php entfernt die Klassen zwar schon
   aus dem Produkttext — diese Regel fängt ab, was später von Hand eingefügt wird.

   AUSGENOMMEN ist der Beschreibungs-Reiter (2026-08-19): Er ist der standardmäßig
   offene Reiter, seine Elemente sind beim Laden sichtbar und werden vom Scroll-Beobachter
   normal erfasst — dort laufen die Einblendungen wie auf der Landing. Der pauschale
   Wächter hatte sie mit neutralisiert, und der Betreiber vermisste die Animationen
   sofort. Wer nach einem Reiterwechsel zurückkehrt, verliert nichts: Ein verstecktes
   Element meldet top=0 und bekommt sein `in` mit dem nächsten Scroll-Ereignis. */
.woocommerce div.product .woocommerce-tabs .panel:not(.woocommerce-Tabs-panel--description) .fx {
	opacity: 1;
	transform: none;
}

/* --- Rahmen: Sektionsstruktur wie im Design --------------------------------

   `div.product` umschließt bei WooCommerce die ganze Seite. Im Design liegen unter der
   Kaufbühne aber eigenständige `section`-Blöcke, deren Grund (`.section.alt`) über die
   volle Fensterbreite läuft. `display: contents` nimmt das Produkt-div als Layout-Kasten
   heraus, ohne es aus dem DOM zu entfernen — Klassen und JavaScript bleiben unberührt,
   die Sektionen werden zu direkten Kindern und können durchziehen.
   Aufgebaut werden sie in inc/woocommerce.php. */

.woocommerce div.product { display: contents; }

/* Die Kaufbühne: Galerie links, Buy-Box rechts (.pdp aus dem Design). */
.woocommerce div.product .pdp-stage { padding: 0; }

.woocommerce div.product .pdp {
	display: grid;
	grid-template-columns: minmax(0, 7fr) minmax(320px, 5fr);
	gap: clamp(24px, 4vw, 56px);
	align-items: start;
	padding: clamp(18px, 3vw, 36px) 0 clamp(40px, 5vw, 72px);
}

.woocommerce div.product .pdp > div.images { grid-column: 1; grid-row: 1; }
.woocommerce div.product .pdp > div.summary { grid-column: 2; grid-row: 1; }

/* WooCommerce legt beide Spalten als Floats mit fester Prozentbreite an — im Raster
   stört das. */
.woocommerce div.product .pdp > div.images,
.woocommerce div.product .pdp > div.summary {
	float: none;
	width: auto;
	margin: 0;
	min-width: 0;
}

@media (max-width: 940px) {
	.woocommerce div.product .pdp { grid-template-columns: 1fr; }

	.woocommerce div.product .pdp > div.images,
	.woocommerce div.product .pdp > div.summary { grid-column: 1; grid-row: auto; }
}

/* Der Lesekorridor der Inhaltssektionen — im Design `style="max-width:820px"`. Die
   Sektion „Weitere Produkte" läuft dagegen über die volle Inhaltsbreite. */
.woocommerce .section .b4-section-wrap { max-width: 820px; }
.woocommerce .section#weitere-produkte .b4-section-wrap { max-width: var(--b4-maxw); }

.woocommerce .section > .b4-section-wrap > .kicker { display: block; margin-bottom: var(--space-sm); }
.woocommerce .section > .b4-section-wrap > h2.display { margin: 0 0 var(--space-lg); }
.woocommerce .section > .b4-section-wrap > :last-child { margin-bottom: 0; }

/* --- Buy-Box (div.summary → .buy-box) -------------------------------------- */

.woocommerce div.product .pdp > div.summary {
	display: flex;
	flex-direction: column;
	gap: var(--space-sm);
	padding: clamp(20px, 2.6vw, 30px);
	border: 1px solid var(--b4-line);
	border-radius: var(--radius-card);
	background: var(--b4-card);
}

/* Produkttitel: eigene Stufe unterhalb der globalen h1-Größe (64,8 px — sie bräche in
   der schmalen Spalte über vier Zeilen). Seit der CG-Abnahme (Betreiber, 2026-08-20)
   die Zwischenstufe d1 statt d3: 32 px wirkten neben der 54-px-PLP-H1 zu klein; die
   drei Ladebrett-Titel brechen dafür dreizeilig — gemessen und in Kauf genommen. */
.woocommerce div.product .pdp > div.summary h1.product_title {
	margin: 0;
	font-size: var(--fs-d1);
	line-height: 1.12;
}

/* Kurzbeschreibung → .bb-sub */
.woocommerce div.product .woocommerce-product-details__short-description {
	margin: 0;
	color: var(--color-text-muted);
	line-height: 1.55;
}

.woocommerce div.product .woocommerce-product-details__short-description > :first-child { margin-top: 0; }
.woocommerce div.product .woocommerce-product-details__short-description > :last-child { margin-bottom: 0; }

/* --- Preiszeile (.bb-price-row aus inc/woocommerce.php) --------------------- */

/* Der Preis kommt aus woocommerce_template_single_price, die Verfügbarkeit aus
   wc_get_stock_html(). Hier wird nur ihr Aussehen gesetzt, nie ihr Inhalt. */
.woocommerce div.product .bb-price-row > p.price {
	margin: 0;
	color: var(--color-text);
	font-family: var(--font-mono);
	font-weight: 600;
	font-size: var(--fs-price-lg);
	letter-spacing: 0.01em;
	font-variant-numeric: tabular-nums slashed-zero;
	line-height: 1.1;
}

/* Streichpreis bei Angeboten — Germanized zeigt beide Werte, beide müssen lesbar sein.
   Gedämpft wird über die FARBE, nicht über die Deckkraft: `opacity: 0.55` drückte den
   Alt-Preis auf 2,92:1, gefunden von pruefen/bin/verify-a11y. Für eine Preisangabe ist das zu
   wenig (PAngV/Omnibus: der frühere Preis muss klar erkennbar sein), und das
   Textkonzept verbietet die Deckkraft ohnehin (design/doku/TEXTKONZEPT.md). Zurück tritt
   der Alt-Preis durch den Durchstrich und den Kupfer-Preis daneben. */
.woocommerce div.product .bb-price-row > p.price del { color: var(--color-text-muted); font-weight: 400; opacity: 1; }
.woocommerce div.product .bb-price-row > p.price ins { text-decoration: none; background: none; }

/* Verfügbarkeit → .avail, mit dem Punkt aus dem Design.

   Als **Etikett** gestaltet, wie das Angebot-Etikett auf dem Bild: dunkle Fläche, Haarlinie,
   die Farbe in Schrift und Kante. Beides sind Zustände desselben Produkts und sollen als
   dasselbe Element gelesen werden — vorher stand die Verfügbarkeit als nackter farbiger Text
   neben dem Preis und wirkte wie ein Satzteil.

   Der Rand nimmt `currentColor`: Damit folgt er von selbst der Zustandsfarbe aus den drei
   Regeln unten — vorrätig, Nachlieferung, ausverkauft — ohne dass die Kante dreimal
   wiederholt werden müsste. */
.woocommerce div.product .bb-price-row > p.stock {
	display: inline-flex;
	align-items: center;
	gap: var(--space-xs);
	margin: 0;
	padding: var(--space-2xs) var(--space-xs);
	border: 1px solid currentColor;
	border-radius: var(--radius-badge);
	background: rgba(5, 4, 4, 0.86);
	font-size: var(--fs-small);
	font-weight: 600;
	letter-spacing: 0.08em;
	text-transform: uppercase;
	line-height: 1.4;
}

.woocommerce div.product .bb-price-row > p.stock::before {
	content: '';
	width: 7px;
	height: 7px;
	border-radius: var(--radius-round);
	background: currentColor;
}

.woocommerce div.product .bb-price-row > p.stock.in-stock { color: var(--color-ok); }
.woocommerce div.product .bb-price-row > p.stock.available-on-backorder { color: var(--color-warn); }
.woocommerce div.product .bb-price-row > p.stock.out-of-stock { color: var(--color-error); }

/* Grundpreis und Pfandart (Germanized) gehören unter den Preis, nicht daneben. */
.woocommerce div.product .bb-price-row > .wc-gzd-additional-info { flex-basis: 100%; }

/* --- Steuerhinweis, Versandkosten, Lieferzeit → .bb-tax --------------------- */

/* Pflichtangaben nach PAngV. Sie stammen unverändert aus den Germanized-Hooks
   (legal_info bei Priorität 12, delivery_time_info bei 27) — hier nur die Typografie. */
.woocommerce div.product .pdp > div.summary .legal-price-info,
.woocommerce div.product .pdp > div.summary .legal-price-info p,
.woocommerce div.product .pdp > div.summary p.wc-gzd-additional-info {
	margin: 0;
	font-size: var(--fs-xs);
	line-height: 1.6;
	color: var(--color-text-muted);
}

.woocommerce div.product .pdp > div.summary .wc-gzd-additional-info a {
	color: var(--color-accent-bright);
	text-decoration: underline;
	text-underline-offset: 0.15em;
}

.woocommerce div.product .pdp > div.summary .wc-gzd-additional-info a:hover { color: var(--color-accent-soft); }

/* --- Bestellbereich (form.cart → .bb-cta) ---------------------------------- */

.woocommerce div.product form.cart {
	display: flex;
	flex-wrap: wrap;
	gap: var(--space-xs);
	margin: 0;
}

.woocommerce div.product form.cart .quantity { margin: 0; }

.woocommerce div.product form.cart .quantity .qty {
	width: 5.5rem;
	height: 100%;
	padding: var(--space-xs) var(--space-xs);
	border: 1px solid var(--b4-line);
	border-radius: var(--radius-input);
	background: var(--color-surface);
	color: var(--color-text);
	font-family: var(--font-mono);
	font-size: var(--fs-body);
	text-align: center;
}

/* Der Bestellbutton wird zusammen mit allen anderen WooCommerce-Schaltflächen weiter
   unten gestaltet („Buttons — eine Regel für alle"). Er stand hier zuerst allein; als
   die Kacheln der Shop-Übersicht dazukamen, liefen die Werte auseinander. */

/* --- Produkt-Meta (div.product_meta → dl.bb-meta) -------------------------- */

/* Das Design nutzt eine Definitionsliste; WooCommerce liefert `span`, in denen Label und
   Wert zusammenstehen. Statt das Markup nachzubauen, wird die Optik angenähert: eine
   Zeile je Angabe, der Wert (SKU, Kategorie, Marke) hervorgehoben. */
.woocommerce div.product .pdp > div.summary .product_meta {
	display: flex;
	flex-direction: column;
	gap: var(--space-2xs);
	margin: var(--space-3xs) 0 0;
	padding-top: var(--space-sm);
	border-top: 1px solid var(--b4-line);
	font-size: var(--fs-xs);
	color: var(--color-text-muted);
}

.woocommerce div.product .pdp > div.summary .product_meta > span { display: block; }
.woocommerce div.product .pdp > div.summary .product_meta .sku { font-family: var(--font-mono); color: var(--color-text); }
.woocommerce div.product .pdp > div.summary .product_meta a { color: var(--color-accent-bright); text-decoration: none; }
.woocommerce div.product .pdp > div.summary .product_meta a:hover { text-decoration: underline; }

/* --- Galerie (WooCommerce-Flexslider → .pdp-main / .pdp-thumbs) ------------- */

.woocommerce div.product .pdp div.images.woocommerce-product-gallery {
	display: flex;
	flex-direction: column;
	gap: var(--space-sm);
	opacity: 1;
}

/* Die Bühne ist der Flexslider-Ausschnitt (.flex-viewport), nicht der Bilderstreifen
   darin — der ist so breit wie alle Bilder zusammen. Ohne JavaScript entsteht kein
   Viewport, deshalb trägt der Streifen dieselbe Gestaltung als Rückfallebene. */
.woocommerce div.product .pdp div.images .flex-viewport,
.woocommerce div.product .pdp div.images > .woocommerce-product-gallery__wrapper {
	margin: 0;
	border: 1px solid var(--b4-line);
	border-radius: var(--radius-card);
	overflow: hidden;
	background: var(--b4-black);
}

.woocommerce div.product .pdp div.images .woocommerce-product-gallery__image img { display: block; width: 100%; height: auto; }

/* Die Folien haben schon vor dem Flexslider-Start ihre Endbreite. Flexslider setzt den
   Streifen sofort auf 200 % je Bild, Breite und Float der Folien aber erst 100 ms später —
   dazwischen füllt die erste Folie den ganzen Streifen, das Bild steht in Dateigröße da
   und die Kaufbox springt (CLS 0,31 bei 390 px, JOURNAL 2026-10-16). Die Regel nimmt
   vorweg, was Flexslider danach inline setzt. Ohne JavaScript gibt es keinen
   .flex-viewport; die Rückfallebene bleibt unberührt. */
.woocommerce div.product .pdp div.images .flex-viewport { container-type: inline-size; }
.woocommerce div.product .pdp div.images .flex-viewport .woocommerce-product-gallery__image { float: left; width: 100cqw; }

/* Kein Vergrößern-Symbol auf dem Bild (Entscheidung 2026-07-29).

   Sechs Varianten wurden am echten Produktfoto verglichen — Kreis, Plakette, Kupferknopf,
   Ecke. Keine überzeugte: Jedes Zeichen liegt als Fremdkörper auf dem Produkt. Stattdessen
   sagt der **Zeiger**, was möglich ist: `cursor: zoom-in` über der ganzen Bildfläche.

   Der Knopf bleibt im DOM und wird nur ausgeblendet — er ist der einzige Auslöser, den
   WooCommerce für PhotoSwipe verdrahtet. Gemessen: Ein Klick auf das Bild selbst öffnet
   nichts, weder auf den Link noch auf das Bild ist ein Handler gesetzt. Wer ihn entfernt,
   nimmt die Großansicht mit. Die Brücke in inc/woocommerce.php leitet den Klick weiter. */
.woocommerce div.product .pdp div.images .woocommerce-product-gallery__trigger {
	display: none;
}

/* Der Zeiger auf der ganzen Bühne — auch auf `img.zoomImg`, der Vergrößerungsebene, die
   WooCommerce beim Überfahren über das Bild legt und die alles darunter verdeckt. */
.woocommerce div.product .pdp div.images .woocommerce-product-gallery__image,
.woocommerce div.product .pdp div.images .woocommerce-product-gallery__image a,
.woocommerce div.product .pdp div.images .woocommerce-product-gallery__image img,
.woocommerce div.product .pdp div.images img.zoomImg {
	cursor: zoom-in;
}

/* Thumbnails → .pdp-thumbs */
.woocommerce div.product .pdp div.images .flex-control-thumbs {
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(104px, 1fr));
	gap: var(--space-sm);
	margin: 0;
	padding: 0;
	list-style: none;
}

.woocommerce div.product .pdp div.images .flex-control-thumbs li {
	width: auto;
	float: none;
	margin: 0;
	list-style: none;
}

.woocommerce div.product .pdp div.images .flex-control-thumbs img {
	width: 100%;
	aspect-ratio: 4 / 3;
	object-fit: cover;
	border: 1px solid var(--b4-line);
	border-radius: var(--radius-card);
	opacity: 0.7;
	cursor: pointer;
	transition: opacity var(--mo-1) ease, border-color var(--mo-1) ease;
}

/* Quadratisches Hauptbild → quadratische Vorschau (inc/woocommerce.php) */
.woocommerce div.product .pdp div.images.b4-vorschau-quadrat .flex-control-thumbs img {
	aspect-ratio: 1 / 1;
}

.woocommerce div.product .pdp div.images .flex-control-thumbs img:hover,
.woocommerce div.product .pdp div.images .flex-control-thumbs img.flex-active {
	opacity: 1;
	border-color: var(--accent-line);
}

@media (max-width: 480px) {
	.woocommerce div.product .pdp div.images .flex-control-thumbs { grid-template-columns: repeat(auto-fill, minmax(84px, 1fr)); }
}

/* --- Reiter: Beschreibung, Zusatzinfo, Produktsicherheit -------------------- */

/* Der Reiter „Produktsicherheit" trägt die GPSR-Pflichtangaben (Hersteller,
   EU-Verantwortlicher, Sicherheitshinweise, Dokumente). Er kommt von Germanized über
   woocommerce_gzd_single_product_safety_information und darf nicht wegfallen. */
.woocommerce div.product .woocommerce-tabs { margin-top: clamp(28px, 4vw, 48px); padding: 0; }

.woocommerce div.product .woocommerce-tabs ul.tabs {
	display: flex;
	flex-wrap: wrap;
	gap: var(--space-2xs);
	margin: 0 0 var(--space-lg);
	padding: 0;
	border-bottom: 1px solid var(--b4-line);
	list-style: none;
}

/* WooCommerce zeichnet die Reiterecken mit Pseudo-Elementen — im flachen Design stören sie. */
.woocommerce div.product .woocommerce-tabs ul.tabs::before,
.woocommerce div.product .woocommerce-tabs ul.tabs li::before,
.woocommerce div.product .woocommerce-tabs ul.tabs li::after { display: none; }

/* `li.active` muss mitgenannt werden: WooCommerce setzt dort einen weißen Grund und
   gewinnt sonst über die höhere Spezifität. */
.woocommerce div.product .woocommerce-tabs ul.tabs li,
.woocommerce div.product .woocommerce-tabs ul.tabs li.active {
	margin: 0;
	padding: 0;
	border: 0;
	border-radius: 0;
	background: transparent;
	box-shadow: none;
}

.woocommerce div.product .woocommerce-tabs ul.tabs li a {
	display: block;
	padding: var(--space-xs) var(--space-md);
	border-bottom: 2px solid transparent;
	color: var(--color-text-muted);
	font-weight: 700;
	font-size: var(--fs-nav);
	letter-spacing: 0.05em;
	text-transform: uppercase;
	text-decoration: none;
}

.woocommerce div.product .woocommerce-tabs ul.tabs li.active a,
.woocommerce div.product .woocommerce-tabs ul.tabs li a:hover {
	color: var(--color-text);
	border-bottom-color: var(--color-accent);
}

/* Die Reiterinhalte tragen zusätzlich `entry-content` und würden darüber den Kastengrund
   der Inhaltsseiten erben — hier soll der Text direkt auf dem Seitengrund stehen. */
.woocommerce div.product .woocommerce-tabs .panel {
	max-width: 820px;
	margin: 0;
	padding: 0;
	background: transparent;
	border: 0;
}

.woocommerce div.product .woocommerce-tabs .panel > h2:first-child { margin-top: 0; }

/* Der Beschreibungs-Reiter läuft im Landing-Rhythmus (Betreiber, 2026-08-19):
   `beschreibung.html` trägt echte `.section`/`.section.alt`-Blöcke wie die
   Landingseiten — wechselnder Grund, Sektionsabstände, `.fx`-Einblendungen.
   Dafür braucht das Panel die volle Fensterbreite: Es steckt im `.wrap` der
   umschließenden `produktinfo`-Sektion, und ein Hintergrund, der am Wrap-Rand
   endet, ist kein Sektionsgrund. Der 100vw-Ausbruch ist gefahrlos — die Seite
   steht global auf `overflow-x: hidden`. Die inneren Sektionen bringen ihren
   eigenen `.wrap` mit (820 px, wie auf der PLP). */
/* `:has(> .section)` grenzt auf umgebaute Beschreibungen ein: Die 16 Produktseiten
   im alten Stil (schmale Textspalte, keine inneren Sektionen) würden sonst auf volle
   Fensterbreite ausbrechen — Fließtext über 100vw, gemessener Kollateralschaden vom
   2026-08-19. Sie behalten Panel und produktinfo-Grund unverändert, bis auch sie im
   Landing-Rhythmus neu entstehen. */
.woocommerce div.product .woocommerce-tabs .woocommerce-Tabs-panel--description:has(> .section) {
  max-width: none;
  width: 100vw;
  margin-left: calc(50% - 50vw);
}

/* Die umschließende produktinfo-Sektion darf den inneren Wechselgrund nicht
   übermalen: Je nach Sektionszähler wäre sie `.alt` (dunkler Grund + Ränder),
   und die transparenten inneren Sektionen zeigten dann IHREN Grund statt den
   der Seite. Unten kein Doppelabstand — die letzte innere Sektion polstert selbst. */
#produktinfo:has(.woocommerce-Tabs-panel--description > .section) {
  background: transparent;
  border-block: 0;
  padding-bottom: 0;
}
.woocommerce div.product .woocommerce-tabs .panel .kicker {
  display: block;
  margin-bottom: var(--space-sm);
}

/* Attributtabelle → Optik der .spec-table aus dem Design. */
.woocommerce div.product table.woocommerce-product-attributes {
	width: 100%;
	border: 0;
	border-collapse: collapse;
}

.woocommerce div.product table.woocommerce-product-attributes th,
.woocommerce div.product table.woocommerce-product-attributes td {
	padding: var(--space-xs) var(--space-sm);
	border: 0;
	border-bottom: 1px solid var(--b4-line);
	background: transparent;
	text-align: left;
	font-style: normal;
}

.woocommerce div.product table.woocommerce-product-attributes th {
	width: 40%;
	color: var(--color-text-muted);
	font-weight: 600;
}

.woocommerce div.product table.woocommerce-product-attributes td p { margin: 0; }

/* Werte in der Monospace, wie `.spec-table .val` im Design. Die Klassen `spec-table` und
   `val` vergibt WooCommerce nicht — Tabelle und Zelle tragen die Auszeichnung selbst,
   inklusive der Fließtext-Farbe, die `.spec-table td` im Design setzt. */
.woocommerce div.product table.woocommerce-product-attributes td,
.woocommerce div.product table.woocommerce-product-attributes td p {
	color: var(--color-text-muted);
	font-family: var(--font-mono);
	letter-spacing: 0.01em;
	font-variant-numeric: tabular-nums slashed-zero;
}

/* --- Weitere Produkte (Upsells, ähnliche Produkte) ------------------------- */

.woocommerce div.product .related,
.woocommerce div.product .upsells { margin-top: clamp(40px, 6vw, 72px); }

.woocommerce div.product .related > h2,
.woocommerce div.product .upsells > h2 { margin-bottom: var(--space-lg); }

/* Tabellen aus dem Block-Editor folgen dem Textkonzept: eine Größe wie der Fließtext.
   WordPress setzt für `.wp-block-table` sonst 0.96rem. */
.legal table,
.legal .wp-block-table table {
	width: 100%;
	border-collapse: collapse;
	font-size: var(--fs-body);
}

.legal table th,
.legal table td {
	padding: var(--space-xs) var(--space-sm);
	border: 0;
	border-bottom: 1px solid var(--b4-line);
	text-align: left;
	font-size: inherit;
}

.legal table th { font-weight: 600; color: var(--color-text-muted); }
.legal .wp-block-table { margin: 0 0 var(--space-md); overflow-x: auto; }


/* --- Zustände: Lagerstatus und Meldungen ----------------------------------

   Drei Zustände, alle aus der Materialwelt: Verdigris (bestätigt), Amber (Hinweis),
   Rot (Fehler). WooCommerce liefert die Zustände als Klassen, das Theme nur die Farbe.

   Die Meldungen sind der wichtigere Teil: Ungestylt kommen sie als heller Kasten mit
   dunklem Text — auf dunklem Grund ein Fremdkörper. Im Checkout stehen dort die
   Pflichthinweise („Bitte akzeptieren Sie die AGB"); eine Meldung, die man übersieht,
   kostet die Bestellung. */

.woocommerce-message,
.woocommerce-error,
.woocommerce-info,
.woocommerce-noreviews {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: var(--space-xs) var(--space-md);
	margin: 0 0 var(--space-lg);
	padding: var(--space-sm) var(--space-md);
	border: 1px solid var(--b4-line);
	border-left: 3px solid var(--color-ok);
	border-radius: var(--radius-card);
	background: var(--color-surface);
	color: var(--color-text-muted);
	list-style: none;
	font-size: var(--fs-body);
}

.woocommerce-message::before,
.woocommerce-error::before,
.woocommerce-info::before,
.woocommerce-error li::before { content: none; }

.woocommerce-message { border-left-color: var(--color-ok); }
.woocommerce-info    { border-left-color: var(--color-warn); }
.woocommerce-error   { border-left-color: var(--color-error); flex-direction: column; align-items: flex-start; }

.woocommerce-error li { margin: 0; padding: 0; list-style: none; }
.woocommerce-error strong { color: var(--color-error); }

/* Die Schaltfläche in einer Meldung („Warenkorb anzeigen") bleibt sekundär — die
   Meldung soll informieren, nicht vom Kaufweg ablenken. */
.woocommerce-message .button,
.woocommerce-info .button {
	order: 2;
	margin-left: auto;
	padding: var(--space-xs) var(--space-lg);
	border: 1px solid var(--color-accent);
	border-radius: var(--radius-btn);
	background: var(--accent-faint);
	color: var(--color-accent);
	font-weight: 700;
	font-size: var(--fs-nav);
	letter-spacing: 0.04em;
	text-transform: uppercase;
	text-decoration: none;
}

.woocommerce-message .button:hover,
.woocommerce-info .button:hover { background: var(--accent-fill); color: var(--color-accent); }

/* Pflichtfelder im Checkout: Ein übersehener Fehler kostet die Bestellung. */
.woocommerce form .form-row.woocommerce-invalid input.input-text,
.woocommerce form .form-row.woocommerce-invalid select { border-color: var(--color-error); }
.woocommerce form .form-row.woocommerce-validated input.input-text { border-color: var(--color-ok); }
.woocommerce form .required { color: var(--color-error); text-decoration: none; }


/* --- Auswahllisten von WooCommerce (select2 / selectWoo) -------------------

   Im Checkout ersetzt WooCommerce die Länder- und Bundesland-Auswahl durch select2 —
   ein JavaScript-Dropdown mit eigenem Markup und eigenem, hellem Stylesheet. Es hat
   mit dem nativen `select` nichts mehr zu tun, deshalb greift dessen Gestaltung nicht.

   Anders als beim nativen Element ist die aufgeklappte Liste hier gestaltbar: Sie ist
   normales DOM. `color-scheme: dark` allein reicht dafür nicht. */

.select2-container--default .select2-selection--single,
.select2-container--default .select2-selection--multiple {
	height: auto;
	min-height: 0;
	padding: var(--space-xs) var(--space-3xl) var(--space-xs) var(--space-sm);
	border: 1px solid var(--b4-line);
	border-radius: var(--radius-input);
	background: var(--color-surface);
	color: var(--color-text);
	line-height: 1.4;
}

.select2-container--default .select2-selection--single .select2-selection__rendered {
	padding: 0;
	color: var(--color-text);
	line-height: inherit;
}

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

/* Der eigene Pfeil — derselbe wie beim nativen Feld. */
.select2-container--default .select2-selection--single .select2-selection__arrow {
	top: 0;
	right: 0.8rem;
	height: 100%;
	width: 16px;
	background: var(--b4-icon-chevron) center / contain no-repeat;
}

.select2-container--default .select2-selection--single .select2-selection__arrow b { display: none; }

.select2-container--default.select2-container--open .select2-selection--single,
.select2-container--default.select2-container--focus .select2-selection--single {
	border-color: var(--color-accent);
	box-shadow: 0 0 0 3px var(--accent-ring);
}

/* Die aufgeklappte Liste */
.select2-dropdown {
	border: 1px solid var(--b4-line);
	border-radius: var(--radius-card);
	background: var(--color-surface);
	overflow: hidden;
}

.select2-container--default .select2-search--dropdown .select2-search__field {
	padding: var(--space-xs) var(--space-sm);
	border: 1px solid var(--b4-line);
	border-radius: var(--radius-input);
	background: var(--color-bg);
	color: var(--color-text);
}

.select2-container--default .select2-results__option {
	padding: var(--space-xs) var(--space-sm);
	background: transparent;
	color: var(--color-text-muted);
}

/* Aktiver Eintrag: Kupfer als Position — dieselbe Rolle wie beim aktiven Reiter. */
.select2-container--default .select2-results__option--highlighted[aria-selected],
.select2-container--default .select2-results__option--highlighted[data-selected] {
	background: var(--accent-fill);
	color: var(--color-accent);
}

.select2-container--default .select2-results__option[aria-selected="true"],
.select2-container--default .select2-results__option[data-selected="true"] {
	background: var(--accent-faint);
	color: var(--color-text);
}

.select2-results__options { max-height: 280px; }


/* --- Checkout- und Kontoformulare -----------------------------------------

   WooCommerce sieht für seine Felder eigene CSS-Variablen vor. Sie zu setzen ist der
   saubere Weg — er wirkt auf alle Feldtypen zugleich, auch auf die, die das Plugin
   künftig ergänzt, und erspart ein Wettrüsten über Selektor-Spezifität. */
:root {
	--wc-form-color-background: var(--color-surface);
	--wc-form-color-text: var(--color-text);
	--wc-form-border-color: var(--b4-line);
	--wc-form-border-width: 1px;
	--wc-form-border-radius: var(--radius-input);
}

/* Was die Variablen nicht abdecken: WooCommerce bringt eigene Feldregeln mit — `.woocommerce form .form-row input.input-text`
   und Verwandte. Deren Spezifität schlägt jede Element-Regel aus dem Design, weshalb die
   Felder im Checkout weiß blieben, während alles andere dunkel war. Hier wird sie gezielt
   überschrieben; die Werte sind dieselben wie in der Design-Komponente. */

.woocommerce form .form-row .input-text,
.woocommerce form .form-row input.input-text,
.woocommerce form .form-row textarea,
.woocommerce form .form-row select,
.woocommerce-page form .form-row input.input-text,
.woocommerce-page form .form-row textarea,
.woocommerce-page form .form-row select,
.woocommerce .form-row input[type="text"],
.woocommerce .form-row input[type="email"],
.woocommerce .form-row input[type="tel"],
.woocommerce .form-row input[type="password"],
.woocommerce input#coupon_code {
	width: 100%;
	padding: var(--space-xs) var(--space-sm);
	border: 1px solid var(--b4-line);
	border-radius: var(--radius-input);
	background: var(--color-surface);
	color: var(--color-text);
	font-family: var(--font-body);
	font-size: var(--fs-body);
	line-height: 1.4;
	box-shadow: none;
}

.woocommerce form .form-row textarea { min-height: 130px; line-height: var(--lh-copy); }

.woocommerce form .form-row input.input-text:focus,
.woocommerce form .form-row textarea:focus,
.woocommerce form .form-row select:focus {
	outline: none;
	border-color: var(--color-accent);
	box-shadow: 0 0 0 3px var(--accent-ring);
}

.woocommerce form .form-row label,
.woocommerce-page form .form-row label {
	color: var(--color-text-muted);
	font-size: var(--fs-h6);
}

.woocommerce form .form-row label.checkbox,
.woocommerce form .form-row .woocommerce-form__label-for-checkbox {
	display: flex;
	align-items: flex-start;
	color: var(--color-text-muted);
	font-size: var(--fs-body);
	line-height: var(--lh-copy);
}

/* Die Pflicht-Checkboxen von Germanized (AGB, Widerruf, Datenschutz) — rechtlich
   verbindlich und deshalb nie kleiner oder blasser als der übrige Text. */
.woocommerce-checkout .wc-gzd-checkbox-placeholder label,
.woocommerce-checkout .legal-checkbox label {
	display: flex;
	align-items: flex-start;
	color: var(--color-text-muted);
	font-size: var(--fs-body);
	line-height: var(--lh-copy);
}

/* Tabellen in Warenkorb, Bestellübersicht und Konto */
.woocommerce table.shop_table,
.woocommerce table.shop_table td,
.woocommerce table.shop_table th,
.woocommerce table.shop_table tbody th,
.woocommerce table.shop_table tfoot td,
.woocommerce table.shop_table tfoot th {
	border-color: var(--b4-line);
	background: transparent;
	color: var(--color-text-muted);
}

.woocommerce table.shop_table { border-radius: var(--radius-card); }
.woocommerce table.shop_table th { color: var(--color-text); font-weight: 600; }
.woocommerce table.shop_table .amount { font-family: var(--font-mono); color: var(--color-text); }

/* Bestellübersicht und Zahlungsbereich */
.woocommerce-checkout #payment,
.woocommerce-checkout .woocommerce-checkout-review-order-table {
	border: 1px solid var(--b4-line);
	border-radius: var(--radius-card);
	background: var(--b4-card);
}

.woocommerce-checkout #payment ul.payment_methods {
	border-bottom: 1px solid var(--b4-line);
	padding: var(--space-md);
}

.woocommerce-checkout #payment ul.payment_methods li { list-style: none; }

.woocommerce-checkout #payment div.payment_box {
	margin: var(--space-xs) 0 0;
	padding: var(--space-sm) var(--space-md);
	border-radius: var(--radius-input);
	background: var(--color-surface);
	color: var(--color-text-muted);
}

.woocommerce-checkout #payment div.payment_box::before { display: none; }
.woocommerce-checkout #payment div.form-row { padding: var(--space-md); }

/* Kästchen und Punkte im Checkout — WooCommerce setzt `display: inline` auf
   `.input-checkbox`. Dabei ignoriert der Browser width und height: Das Kästchen
   schrumpft auf zwei Pixel und ist praktisch unsichtbar. Betroffen ist unter anderem
   die AGB- und Widerrufs-Pflichtbox von Germanized — sie muss unübersehbar sein. */
.woocommerce form .form-row input[type="checkbox"],
.woocommerce form .form-row input[type="radio"],
.woocommerce form .form-row .input-checkbox,
.woocommerce-checkout input[type="checkbox"],
.woocommerce-checkout input[type="radio"] {
	display: inline-block;
	width: 18px;
	height: 18px;
	margin: 0 var(--space-xs) 0 0;
	vertical-align: -3px;
}

/* ---------------------------------------------------------------------------
   Einleitung der Shop-Übersicht

   Der Bestandssatz aus ALT, den Phase 15 unter die Überschrift setzt. Er steht
   zwischen dem Seitenkopf und dem ersten Familienstreifen und braucht nur den
   Abstand dorthin — Größe und Farbe kommen aus `.lede` im Design.
   --------------------------------------------------------------------------- */

.shop-intro {
	margin: 0 0 var(--space-3xl);
}

/* ===========================================================================
   Produktkacheln — Shop-Übersicht, Kategorien, „ähnliche Produkte"
   ===========================================================================

   Das Design liefert für den Katalog keine Vorlage: Warenkorb, Kasse und Konto sind
   dort bewusst ausgespart, und eine Produktkachel gibt es ebenso wenig. Die Optik wird
   deshalb aus den vorhandenen Bausteinen abgeleitet — Kartenfläche, Haarlinie und
   Radius wie bei `.note-card` und `.variant`, Preis in Kupfer wie überall im Shop,
   Beschriftungen in der Label-Ebene.

   Was NICHT hier steht: Preis, MwSt.-Hinweis, Versandkosten-Link und Lieferzeit. Sie
   kommen aus WooCommerce und Germanized; hier werden sie nur gestaltet. Ungestylt kamen
   sie als olivgrüner Preis und grauer Systembutton — beides Fremdkörper auf diesem Grund.
   =========================================================================== */

.woocommerce ul.products {
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
	gap: var(--space-xl);
	margin: 0;
	padding: 0;
	list-style: none;
}

.woocommerce ul.products::before,
.woocommerce ul.products::after { content: none; }

/* WooCommerce legt die Kacheln als Floats mit fester Prozentbreite an. Im Raster ist
   beides schädlich: Die Breite überschreibt die Spalte, der Float bricht die Zeilen. */
.woocommerce ul.products li.product {
	float: none !important;
	width: auto !important;
	margin: 0 !important;
	display: flex;
	flex-direction: column;
	padding: var(--space-sm) var(--space-sm) var(--space-md);
	border: 1px solid var(--b4-line);
	border-radius: var(--radius-card);
	background: var(--color-surface-subtle);
	transition: border-color 220ms ease, transform 220ms ease;
}

.woocommerce ul.products li.product:hover {
	border-color: rgba(var(--accent-rgb), 0.45);
	transform: translateY(-2px);
}

.woocommerce ul.products li.product a img {
	width: 100%;
	height: auto;
	aspect-ratio: 4 / 3;
	object-fit: cover;
	margin: 0 0 var(--space-sm);
	border-radius: var(--radius-input);
	background: var(--color-surface);
}

.woocommerce ul.products li.product .woocommerce-loop-product__title {
	margin: 0 0 var(--space-xs);
	padding: 0;
	font-size: var(--fs-h6);
	font-weight: 600;
	letter-spacing: 0.06em;
	text-transform: uppercase;
	color: var(--color-text);
}

/* Die Produktart unter dem Modellcode (2026-08-26). Sie beantwortet auf der Übersicht
   die Frage, die der Code offenlässt: „AMB-MD1" — und was ist das? Bewusst zurückhaltend
   gesetzt: Fließtextfarbe, eine Stufe kleiner, keine Versalien. Der Code bleibt die
   Überschrift, die Art erklärt ihn nur. Der Abstand unter dem Titel wandert hierher,
   damit zwischen Titel und Art keine Lücke entsteht. */
.woocommerce ul.products li.product .loop-produktart {
	display: block;
	margin: 0 0 var(--space-xs);
	font-size: var(--fs-sm);
	color: var(--color-text-muted);
}

.woocommerce ul.products li.product .loop-produktart + .price,
.woocommerce ul.products li.product .woocommerce-loop-product__title:has(+ .loop-produktart) {
	margin-top: 0;
}

.woocommerce ul.products li.product .woocommerce-loop-product__title:has(+ .loop-produktart) {
	margin-bottom: var(--space-3xs);
}

/* Der Preis trägt dieselbe Farbe und denselben Schnitt wie in der Kaufbox — er ist
   dieselbe Aussage, nur an anderer Stelle. */
.woocommerce ul.products li.product .price {
	margin: 0 0 var(--space-xs);
	font-family: var(--font-mono);
	font-size: var(--fs-body);
	font-weight: 600;
	color: var(--color-accent);
}

.woocommerce ul.products li.product .price del {
	/* Siehe Kaufbox weiter oben: Dämpfung über die Farbe, nicht über die Deckkraft.
	   `opacity: 1` ist nötig, weil WooCommerce `del` von sich aus dämpft — die 0,7
	   standen in keinem unserer Stylesheets und blieben nach dem ersten Anlauf
	   übrig (3,94:1 statt der erwarteten 7:1). */
	font-weight: 400;
	color: var(--color-text-muted);
	opacity: 1;
}

.woocommerce ul.products li.product .price ins {
	text-decoration: none;
	background: none;
	color: var(--color-accent);
}

/* Die Pflichtangaben von Germanized: eine Größe, eine Farbe — wie im Textkonzept.
   Sie stehen dicht beieinander, damit sie als ein Block gelesen werden. */
.woocommerce ul.products li.product .wc-gzd-additional-info,
.woocommerce ul.products li.product .woocommerce-price-suffix,
.woocommerce ul.products li.product .wc-gzd-additional-info-loop {
	margin: 0 0 var(--space-2xs);
	font-size: var(--fs-xs);
	line-height: 1.5;
	color: var(--color-text-muted);
}

.woocommerce ul.products li.product .wc-gzd-additional-info a { color: var(--color-accent); }

/* Dieselben Pflichtangaben am redaktionellen Preis [b4_preis] (Start- und Landingseiten):
   klein und gedämpft wie in den Shop-Listen, hinter dem Preis im Fluss. Der Preis selbst
   steht in Mono und fett (.app-price, .fam-price) — davon erbt der Hinweis nichts. */
.b4-preis-hinweise {
	margin-left: var(--space-xs);
	font-family: var(--font-body);
	font-weight: 400;
	font-size: var(--fs-xs);
	letter-spacing: normal;
	font-variant-numeric: normal;
	color: var(--color-text-muted);
}

.b4-preis-hinweise a { color: var(--color-accent); }

/* In der Modellkarte und im Preisanker der Startseite eine eigene Zeile unter dem Preis,
   wie in der Shop-Liste; ein Zusatz der Startseite („je Modell") folgt als nächste Zeile. */
.fam-card .b4-preis-hinweise,
.app-price .b4-preis-hinweise { display: block; margin: var(--space-3xs) 0 0; }
.app-price .b4-preis-hinweise + .ap-note { display: block; margin-left: 0; }

/* In der Hinweiszeile unter dem Hero (.page-note) Teil des Satzes: dessen Größe. */
.page-note .b4-preis-hinweise { margin-left: 0; font-size: inherit; }

/* Der Button sitzt unten, egal wie lang der Titel darüber ist — sonst steht in einer
   Zeile mit unterschiedlich langen Namen jeder Button auf anderer Höhe. Aussehen und
   Maße kommen aus der gemeinsamen Buttonregel weiter unten. */
.woocommerce ul.products li.product .button {
	margin-top: auto;
	align-self: flex-start;
}

/* „Ansehen"-Link, den WooCommerce nach dem Hinzufügen einblendet: zweitrangig, deshalb
   in der Skelett-Ausführung des Designs. */
.woocommerce ul.products li.product .added_to_cart {
	margin-top: var(--space-xs);
	align-self: flex-start;
	background: var(--accent-faint);
	border-color: var(--color-accent);
	color: var(--color-accent);
	box-shadow: none;
}

.woocommerce ul.products li.product .added_to_cart:hover {
	background: var(--accent-fill);
	color: var(--color-accent);
}

/* ===========================================================================
   Buttons — eine Regel für alle WooCommerce-Schaltflächen
   ===========================================================================

   Spiegelt `.btn` + `.btn-primary` aus design/styles/site.css (Zeilen 105–125).
   WooCommerce erzeugt sein eigenes Markup mit der Klasse `button`; die Design-Klassen
   lassen sich also nicht anhängen, ihre Werte müssen hier stehen.

   **Eine Regel für alle**, weil es sonst auseinanderläuft: Der Bestellbutton der
   Produktseite war bereits nach Design gestaltet, die Kacheln der Übersicht bekamen
   später eigene Werte — 13,1 px statt 14,7 px, Schnitt 600 statt 700, das gedämpfte
   Kupfer statt des hellen. Nebeneinander sah man zwei verschiedene Buttons für dieselbe
   Handlung. Nachgemessen wurde gegen `dev/brandbook-shop.html`.

   Die **Beschriftungen** liefert WooCommerce (`single_add_to_cart_text`, „Zahlungspflichtig
   bestellen" im Checkout) — sie werden hier nie gesetzt, sie sind teils rechtlich
   vorgeschrieben.

   **`.button.alt` muss ausdrücklich mitgenannt werden.** WooCommerce vergibt diese Klasse
   an seine Hauptaktionen — „Weiter zur Kasse" und „Zahlungspflichtig bestellen" — und
   färbt sie über eine eigene, spezifischere Regel violett (#7f54b3). Ohne den Zusatz
   stand ausgerechnet der wichtigste Button des Warenkorbs in einer fremden Farbe und
   zwei Stufen zu groß. Gemessen, nicht vermutet.
   =========================================================================== */

.woocommerce ul.products li.product .button,
.woocommerce ul.products li.product .added_to_cart,
.woocommerce div.product form.cart button.single_add_to_cart_button,
.woocommerce a.button,
.woocommerce button.button,
.woocommerce input.button,
.woocommerce a.button.alt,
.woocommerce button.button.alt,
.woocommerce input.button.alt,
.woocommerce #respond input#submit,
.woocommerce-page a.button,
.woocommerce-page button.button,
.woocommerce-page input.button,
.woocommerce-page a.button.alt,
.woocommerce-page button.button.alt,
.woocommerce-page input.button.alt {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: 0.55em;
	padding: var(--space-xs) var(--space-xl);
	border: 1px solid transparent;
	border-radius: var(--radius-btn);
	background: var(--color-accent-bright);
	color: var(--color-text-on-accent);
	font-family: var(--font-body);
	font-weight: 700;
	font-size: var(--fs-sm);
	line-height: 1.5;
	letter-spacing: 0.04em;
	text-transform: uppercase;
	text-decoration: none;
	white-space: nowrap;
	cursor: pointer;
	box-shadow: 0 6px 22px -8px rgb(var(--accent-bright-rgb) / 0.7);
	transition: transform var(--mo-2) var(--ease), background var(--mo-1) ease,
		border-color var(--mo-1) ease, box-shadow var(--mo-2) var(--ease);
}

.woocommerce ul.products li.product .button:hover,
.woocommerce div.product form.cart button.single_add_to_cart_button:hover,
.woocommerce a.button:hover,
.woocommerce button.button:hover,
.woocommerce input.button:hover,
.woocommerce a.button.alt:hover,
.woocommerce button.button.alt:hover,
.woocommerce input.button.alt:hover,
.woocommerce #respond input#submit:hover,
.woocommerce-page a.button:hover,
.woocommerce-page button.button:hover,
.woocommerce-page input.button:hover,
.woocommerce-page a.button.alt:hover,
.woocommerce-page button.button.alt:hover,
.woocommerce-page input.button.alt:hover {
	background: var(--color-accent-bright);
	color: var(--color-text-on-accent);
	transform: translateY(-2px);
	box-shadow: 0 14px 40px -12px var(--accent-glow);
}

.woocommerce .button:active,
.woocommerce-page .button:active { transform: translateY(0); }

/* Der Bestellbutton der Produktseite füllt die Breite neben dem Mengenfeld. */
.woocommerce div.product form.cart button.single_add_to_cart_button { flex: 1 1 auto; }

/* Zweitrangige Schaltflächen in der Skelett-Ausführung: „Warenkorb aktualisieren" steht
   neben „Zur Kasse", „Gutschein einlösen" neben dem Bestellabschluss. Zwei gleich starke
   Buttons nebeneinander sagen nicht, welcher der Weg nach vorn ist. */
.woocommerce .cart button.button[name="update_cart"],
.woocommerce .coupon button.button,
.woocommerce .return-to-shop a.button,
.woocommerce-cart a.button.wc-backward,
.woocommerce-account a.woocommerce-Button--next {
	background: var(--accent-faint);
	border-color: var(--color-accent);
	color: var(--color-accent);
	box-shadow: none;
}

.woocommerce .cart button.button[name="update_cart"]:hover,
.woocommerce .coupon button.button:hover,
.woocommerce .return-to-shop a.button:hover,
.woocommerce-cart a.button.wc-backward:hover,
.woocommerce-account a.woocommerce-Button--next:hover {
	background: var(--accent-fill);
	color: var(--color-accent);
}

/* Deaktivierte Schaltflächen — WooCommerce sperrt „Warenkorb aktualisieren", solange
   nichts geändert wurde. Ohne eigene Regel bliebe sie in vollem Kupfer und sähe
   handlungsfähig aus. */
.woocommerce .button:disabled,
.woocommerce .button[disabled],
.woocommerce .button.disabled {
	opacity: 0.45;
	box-shadow: none;
	cursor: not-allowed;
	transform: none;
}

/* Das Angebot-Etikett.

   **Grün, oben links** — wie in ALT (dort `rgb(0,128,0)`, 84×32, oben links am Bild).
   Genommen wird aber nicht das Browser-Grün, sondern `--color-ok` (Verdigris): dasselbe
   Vorgehen wie beim „Immer aktiv" der Cookie-Richtlinie, wo #008000 aus der Materialwelt
   fiel. Kupfer wäre hier ohnehin falsch — es ist im Design der Kaufhandlung vorbehalten,
   und ein reduzierter Preis ist ein Zustand, keine Handlung.

   **`right: auto` ist Pflicht, nicht Kosmetik.** WooCommerce setzt `right: 0` auf das
   Etikett. Mit `left` **und** `right` streckt der Browser ein absolut positioniertes
   Element über die ganze Breite: In den Katalogkacheln war das Etikett gemessen 243 bis
   295 px breit — ein Balken über dem halben Produktfoto, mit zentrierter Schrift.

   **Der Bezugsrahmen musste erst geschaffen werden.** Auf der Produktseite steckt
   `span.onsale` in `div.pdp`, dem Raster aus Bild und Kaufbox, und keiner seiner Vorfahren
   war positioniert — `offsetParent` war schlicht `BODY`, das Etikett klebte oben links an
   der **Seite**. Der Bezug sitzt bewusst auf `.pdp` und nicht auf `div.product`: `.pdp`
   beginnt genau am Bild, `div.product` umfasst auch den Breadcrumb und die Reiter darunter.
   Dritter Fall an einem Tag, in dem die Frage „welcher Vorfahre ist der Bezugsrahmen?" die
   eigentliche Aufgabe war — nach dem Complianz-Hinweis und der Galerie-Schaltfläche.

   `.pdp` allein genügte noch nicht: Gemessen saß das Etikett damit 23 px **über** dem Bild,
   weil das Raster oben früher beginnt als der Bildbereich. Deshalb bekommt es die
   **Rasterzelle des Bildes** als Bezug (`grid-row`/`grid-column`, wie bei der
   Galerie-Schaltfläche). Beide Kanten müssen definit sein — `1 / 2`, nicht `1`: `grid-row: 1`
   heißt `1 / auto`, und damit greift der Zellenbezug nicht. */
.woocommerce div.product .pdp { position: relative; }

.woocommerce div.product .pdp > span.onsale {
	grid-row: 1 / 2;
	grid-column: 1 / 2;
}

/* In der Katalogkachel hängt das Etikett in `a.woocommerce-LoopProduct-link`, und der war
   nicht positioniert — es bezog sich damit auf `li.product` samt dessen 14 px Innenabstand
   und saß gemessen 1 px vor der Bildkante, also praktisch darauf. Der Link beginnt genau am
   Bild; mit ihm als Bezug misst der Abstand vom Bildrand statt vom Kachelrand. */
.woocommerce ul.products li.product a.woocommerce-LoopProduct-link { position: relative; }

.woocommerce ul.products li.product .onsale,
.woocommerce span.onsale {
	position: absolute;
	/* Minimaler Abstand zur Bildecke — das Etikett sitzt in der Ecke, nicht im Bild. */
	top: 6px;
	left: 6px;
	right: auto;
	bottom: auto;
	width: auto;
	min-height: 0;
	min-width: 0;
	margin: 0;
	padding: var(--space-2xs) var(--space-xs);
	border-radius: var(--radius-badge);
	/* Dunkle Fläche, grüne Schrift, grüne Haarlinie — dasselbe Muster, mit dem der Shop
	   jeden Zustand zeigt (WooCommerce-Meldungen, Verfügbarkeit): der Grund bleibt dunkel,
	   die Farbe steckt in Schrift und Kante.

	   Eine grüne Fläche wäre hier zu schwach: Verdigris gegen ein cremefarbenes Produktfoto
	   ergibt gemessen 2,15 : 1, das Etikett verschwamm mit dem Bild. Der dunkle Grund kommt
	   auf 16,1 : 1 und trägt damit auf jedem Foto — von cremefarben bis fast schwarz. Die
	   grüne Schrift darauf liegt bei 7,5 : 1. */
	background: rgba(5, 4, 4, 0.86);
	color: var(--color-ok);
	border: 1px solid var(--color-ok);
	font-size: var(--fs-small);
	font-weight: 600;
	letter-spacing: 0.08em;
	text-transform: uppercase;
	line-height: 1.4;
	text-align: center;
}

.woocommerce ul.products li.product { position: relative; }

/* Die Sektionsköpfe der Übersicht stehen im Seiteninhalt und brauchen denselben
   Innenabstand wie auf den Design-Seiten. */
.woocommerce .section .section-head { margin-bottom: var(--space-2xl); }
.woocommerce .section .section-head .lede { margin-bottom: 0; }

/* ===========================================================================
   Warenkorb — Aufteilung und Summe
   ===========================================================================
   WooCommerce stellt Tabelle und Summenblock untereinander und lässt den Platz neben
   der Tabelle leer. Nebeneinander ist die Zuordnung sofort lesbar: links, was im
   Warenkorb liegt, rechts, was es kostet.
   =========================================================================== */

/* Die Shop-Strecke braucht die volle Breite, nicht den Lesekorridor.
   ---------------------------------------------------------------------------
   `page.php` rendert jede Seite in `section.legal`, und `.legal .wrap` ist auf
   820 px begrenzt — die Lesebreite für Rechtstexte, wo lange Zeilen ermüden.
   Warenkorb, Kasse und Konto sind aber keine Fließtexte: Dort stehen eine
   Positionstabelle mit sechs Spalten und ein Summenblock nebeneinander.

   In 820 px minus Innenabstand bleiben 692 px. Davon nimmt der Summenblock seine
   Mindestbreite von 300, für die Tabelle blieben 349 — sie lief über ihren Kasten
   hinaus, die Spalte „Anzahl" war halb abgeschnitten und das Produktbild auf 8×8 px
   gequetscht (gemessen 2026-08-03, gefunden von pruefen/bin/verify-layout).

   Deshalb hier zurück auf die normale Seitenbreite. Betroffen sind nur die drei
   WooCommerce-Body-Klassen; Rechtstexte behalten ihren Korridor. */
.woocommerce-cart .legal .wrap,
.woocommerce-checkout .legal .wrap,
.woocommerce-account .legal .wrap {
	max-width: var(--b4-maxw);
}

@media (min-width: 900px) {
	.woocommerce-cart .woocommerce {
		display: grid;
		grid-template-columns: minmax(0, 1.6fr) minmax(300px, 1fr);
		gap: clamp(24px, 3vw, 44px);
		align-items: start;
	}

	/* Meldungen und das Formular mit der Positionstabelle laufen über beide Spalten,
	   der Summenblock steht rechts daneben. */
	.woocommerce-cart .woocommerce > form.woocommerce-cart-form { grid-column: 1; }
	.woocommerce-cart .woocommerce > .cart-collaterals { grid-column: 2; width: auto; }
	.woocommerce-cart .woocommerce > .woocommerce-notices-wrapper { grid-column: 1 / -1; }
}

/* Das Positionsbild im Warenkorb.
   WooCommerce gibt der Miniatur ohne eigene Regel nur den Platz, den die Zelle
   übrig lässt — gemessen waren das 26×20 px. Bei dieser Größe ist ein Produktfoto
   keine Wiedererkennung mehr, sondern ein Fleck. 72 px ist die Kantenlänge, bei der
   die Bag Rider im Warenkorb noch auseinanderzuhalten sind. */
.woocommerce-cart td.product-thumbnail { width: 96px; }

.woocommerce-cart td.product-thumbnail img {
	width: 72px;
	height: auto;
	max-width: none;
	border-radius: var(--radius-badge);
	display: block;
}

.woocommerce-cart .cart-collaterals .cart_totals { width: 100%; float: none; }

.woocommerce-cart .cart-collaterals .cart_totals h2 {
	font-size: var(--fs-h4);
	margin: 0 0 var(--space-md);
}

.woocommerce-cart table.shop_table td,
.woocommerce-cart table.shop_table th {
	border-color: var(--b4-line);
	color: var(--color-text-muted);
}

.woocommerce-cart table.shop_table th { color: var(--color-text); }

/* Das Entfernen-Kreuz: WooCommerce setzt ein kräftiges Rot. Der Zustand „weg damit" ist
   hier kein Fehler, sondern eine gewöhnliche Handlung — deshalb in der Textfarbe, und
   erst beim Zeigen in der Warnfarbe. */
.woocommerce-cart table.shop_table td.product-remove a.remove {
	color: var(--color-text-muted) !important;
	font-size: var(--fs-h3);
	line-height: 1;
}

.woocommerce-cart table.shop_table td.product-remove a.remove:hover {
	background: transparent;
	color: var(--color-error) !important;
}

/* ===========================================================================
   Germanized-Fußhinweise
   ===========================================================================
   „Vertrag widerrufen" führt zum Widerrufsformular und muss auffindbar sein — aber es
   ist keine Kaufhandlung. Als voller Kupferbutton stand es in der Fußzeile stärker da
   als „Weiter zur Kasse" im Warenkorb darüber und lud zum Widerruf ein, bevor überhaupt
   bestellt wurde. In der Skelett-Ausführung bleibt es gleich gut erreichbar.
   =========================================================================== */

.wc-gzd-additional-footer-info .button,
.woocommerce-page .site-footer .button,
a.wc-gzd-revocation-form-link.button {
	background: var(--accent-faint);
	border-color: var(--color-accent);
	color: var(--color-accent);
	box-shadow: none;
}

.wc-gzd-additional-footer-info .button:hover,
a.wc-gzd-revocation-form-link.button:hover {
	background: var(--accent-fill);
	color: var(--color-accent);
}

/* Die Spaltenüberschriften auf „Mein Konto" („Anmelden", „Neues Kundenkonto anlegen")
   kommen als h2 und standen damit auf der Stufe einer Seitenüberschrift — die längere
   brach über drei Zeilen. Sie beschriften zwei Formulare nebeneinander und gehören auf
   die Label-nahe Stufe. */
.woocommerce-account .u-column1 > h2,
.woocommerce-account .u-column2 > h2 {
	font-size: var(--fs-h4);
	margin: 0 0 var(--space-md);
}

/* ===========================================================================
   Eingebettete Videos
   ===========================================================================
   Auf `/service/` steht ein YouTube-Video als roher `<iframe>` mit `width="1200"` im
   Absatz — ein Überbleibsel der Elementor-Migration. Bei 1400 px Viewport ragte es
   154 px über den rechten Rand hinaus und erzeugte waagerechtes Scrollen auf der
   ganzen Seite. Auf einem Telefon wäre es unbenutzbar.

   Die Regel gilt für alle Einbettungen, auch die beiden Videos der CG-PRO-Landing:
   volle Spaltenbreite, Seitenverhältnis 16:9, kein Überlauf. `aspect-ratio` statt des
   alten Padding-Tricks — das Markup kommt aus dem Inhalt und lässt sich nicht umbauen.

   `.cmplz-placeholder-element` ist der Platzhalter, den Complianz vor der Einwilligung
   anstelle des Videos zeigt; er braucht dieselbe Fläche, sonst springt das Layout beim
   Zustimmen.
   =========================================================================== */

.legal iframe[src*="youtube"],
.legal iframe[src*="youtu.be"],
.legal iframe[src*="vimeo"],
.wp-block-embed iframe,
.section iframe[src*="youtube"],
.section iframe[src*="youtube-nocookie"],
.section iframe[src*="vimeo"],
.cmplz-placeholder-element {
	display: block;
	width: 100%;
	max-width: 100%;
	height: auto;
	aspect-ratio: 16 / 9;
	border: 0;
	border-radius: var(--radius-card);
	background: var(--color-surface);
}

/* ---------------------------------------------------------------------------
   Der Hinweis auf dem blockierten Video
   ---------------------------------------------------------------------------
   Vor der Einwilligung legt Complianz eine Schaltfläche über das Vorschaubild:
   „Klicken Sie, um Marketing Cookies zu akzeptieren und diesen Inhalt zu aktivieren."
   Ungestaltet kommt sie in Arial 14 px, weiß auf halbdurchsichtigem Schwarz, ohne Rundung
   und ohne Rand — sie liest sich wie eine Fehlermeldung, nicht wie ein Angebot. Auf der
   CG-PRO-Landing standen dort deshalb scheinbar zwei kaputte Videos.

   Gespiegelt wird die Kette des Plugins (0,2,0) statt sie mit `!important` zu überbieten —
   dasselbe Vorgehen wie bei der Cookie-Richtlinie.
   --------------------------------------------------------------------------- */

.cmplz-blocked-content-container .cmplz-blocked-content-notice,
.cmplz-wp-video .cmplz-blocked-content-notice {
	/* Maße selbst setzen, statt sie von Complianz zu erben.

	   Das Plugin schreibt `width: 100%` und begrenzt mit `max-width: 300px`. Wessen
	   100 % das sind, hängt daran, welcher Vorfahre gerade der Bezugsrahmen ist — und
	   das kann eine einzige `filter`- oder `backdrop-filter`-Regel irgendwo darüber
	   verschieben. Gemeldet wurde genau dieser Ausfall: eine leere Kachel mit einem
	   2 px schmalen Streifen am rechten Rand. Feste Breite, feste Position, kein
	   Bezugsrahmen, auf den man sich verlassen müsste. */
	position: absolute;
	top: 50%;
	left: 50%;
	transform: translate(-50%, -50%);
	width: min(320px, calc(100% - 32px));
	max-width: none;
	box-sizing: border-box;

	padding: var(--space-md) var(--space-lg);
	border: 1px solid var(--color-accent);
	border-radius: var(--radius-card);
	background: rgb(var(--glass-rgb) / 0.92);
	color: var(--color-text);
	font-family: var(--font-body);
	font-size: var(--fs-nav);
	line-height: 1.5;
	cursor: pointer;
	transition: border-color var(--mo-1) ease, background var(--mo-1) ease, color var(--mo-1) ease;
}

.cmplz-blocked-content-container .cmplz-blocked-content-notice:hover,
.cmplz-wp-video .cmplz-blocked-content-notice:hover {
	border-color: var(--color-accent-bright);
	background: rgb(var(--glass-rgb) / 0.96);
	color: var(--color-accent-bright);
}

.cmplz-blocked-content-container .cmplz-blocked-content-notice:focus-visible,
.cmplz-wp-video .cmplz-blocked-content-notice:focus-visible {
	outline: none;
	border-color: var(--color-accent);
	box-shadow: 0 0 0 3px var(--accent-ring);
}

/* Das Vorschaubild abdunkeln, damit die Schaltfläche darauf lesbar bleibt — die
   YouTube-Miniaturen sind hell und bunt. */
.video-frame.cmplz-blocked-content-container::after {
	content: '';
	position: absolute;
	inset: 0;
	background: rgb(var(--glass-rgb) / 0.45);
	border-radius: inherit;
	pointer-events: none;
}

/* Sicherheitsnetz: Kein Inhalt aus dem Editor darf die Seite waagerecht sprengen —
   auch nicht ein Bild oder eine Tabelle, die jemand später einfügt. */
.legal img,
.legal video,
.legal iframe { max-width: 100%; }

.legal :is(table, pre) {
	display: block;
	max-width: 100%;
	overflow-x: auto;
}

/* ===========================================================================
   Fußzeile — fünfte Spalte
   ===========================================================================
   Das Design legt vier Spalten an (Marke, Produkte, Rechtliches, Konto). Der Shop hat
   eine weitere Gruppe, die es im Entwurf noch nicht gab: die Inhaltsseiten (Engineering,
   Service …). Ohne eigene Spalte wäre `/engineering/` nur über einen einzigen Verweis auf
   der Startseite erreichbar gewesen.

   Die Marken-Spalte gibt dafür etwas Breite ab.

   Die Regel steht bewusst in einer Media Query, obwohl sie ohne auskäme: `style.css` wird
   **nach** `site.css` geladen, und bei gleicher Spezifität gewinnt die spätere Regel — auch
   gegen eine, die in einer Media Query steht. Unbedingt notiert hat diese eine Zeile
   deshalb die Umbrüche des Designs bei 900 px (zwei Spalten) und 560 px (eine Spalte)
   ausgehebelt: Die fünf Spalten blieben bis aufs Handy stehen und schoben die Seite
   380 px über den Rand hinaus — waagerechtes Scrollen auf **jeder** Seite, bei 390 px
   Viewport gemessen.
   =========================================================================== */

@media (min-width: 901px) {
	.footer-grid { grid-template-columns: 1.4fr repeat(4, 1fr); }
}

/* Zwischenstufe: Bei fünf Spalten wird es früher eng als bei vier. Drei Spalten halten
   die längeren Produktnamen noch in zwei Zeilen. */
@media (max-width: 1240px) and (min-width: 901px) {
	.footer-grid { grid-template-columns: repeat(3, 1fr); }
	.footer-brand { grid-column: 1 / -1; }
}

/* ===========================================================================
   Suchergebnisse
   ===========================================================================
   Produkte kommen als Katalogkacheln (siehe oben), Seiten als Liste. Die Trennung ist
   Absicht: Ein Rechtstext braucht keinen Preis, ein Produkt keine Textvorschau.
   =========================================================================== */

.b4-suchliste {
	display: grid;
	gap: var(--space-lg);
}

.b4-suchtreffer {
	padding: var(--space-md) var(--space-lg);
	border: 1px solid var(--b4-line);
	border-radius: var(--radius-card);
	background: var(--color-surface-subtle);
}

.b4-suchtreffer h3 {
	margin: 0 0 var(--space-xs);
	font-size: var(--fs-h5);
}

.b4-suchtreffer h3 a {
	color: var(--color-text);
	text-decoration: none;
}

.b4-suchtreffer h3 a:hover { color: var(--color-accent); }

.b4-suchtreffer p {
	margin: 0;
	font-size: var(--fs-body);
	color: var(--color-text-muted);
}

/* Das Suchfeld im Kopf ist seit der Anbindung ein <form>; ohne diese Zeile bricht das
   Flex-Layout der Kopfleiste, weil Formulare als Block laufen. */
.header-search { display: flex; align-items: center; }

/* ===========================================================================
   Cookie-Richtlinie (Complianz)
   ===========================================================================
   Der Shortcode `[cmplz-document]` erzeugt die Cookie-Erklärung mitsamt eigenen Styles —
   für ein helles Theme gedacht. Auf diesem Grund war das Ergebnis unbrauchbar:
   467 Elemente mit hellem Hintergrund (weiß, #f7f7f7, #dadada) trugen die helle
   Textfarbe des Designs. Die Kategorieangaben in den Aufklappern („Funktional",
   „Marketing") standen hell auf hell und waren nicht zu lesen.

   Die Cookie-Erklärung ist eine Pflichtinformation nach DSGVO und TTDSG — sie muss
   lesbar sein, nicht nur vorhanden. Gestaltet wird in derselben Sprache wie die
   WooCommerce-Meldungen: dunkler Grund, Haarlinie, Zustand über die Kante.

   **Die Selektoren sind gespiegelt, nicht überboten.** Complianz arbeitet mit
   ID-Ketten wie `#cmplz-cookies-overview .cmplz-dropdown .cookies-per-purpose div`
   (Spezifität 1,2,1). Zwei Versuche mit kürzeren Klassenselektoren blieben wirkungslos —
   die Flächen waren unverändert weiß. Hier steht deshalb dieselbe Kette; `!important`
   bleibt der Ausnahme vorbehalten, sonst ist die Rangfolge später nicht mehr lesbar.

   **Das Rasterprinzip bleibt erhalten:** Der Container trägt die Linienfarbe, die Zellen
   den Grund, und der 1-px-Abstand dazwischen wird zur Trennlinie. Das ist die Mechanik
   des Plugins — nur die beiden Farben werden getauscht.
   =========================================================================== */

/* --- Die Cookie-Angaben je Zweck (Raster aus Divs, keine Tabelle) ---------- */

#cmplz-cookies-overview .cmplz-dropdown .cookies-per-purpose,
#cmplz-document .cmplz-dropdown .cookies-per-purpose {
	border: 1px solid var(--b4-line);
	border-radius: var(--radius-input);
	background-color: var(--b4-line);
	overflow: hidden;
}

#cmplz-cookies-overview .cmplz-dropdown .cookies-per-purpose div,
#cmplz-document .cmplz-dropdown .cookies-per-purpose div {
	padding: var(--space-sm) var(--space-md);
	background-color: var(--color-surface);
	color: var(--color-text-muted);
}

/* Beschriftung auf Label-Ebene, Wert im Fließtext — dieselbe Trennung wie im
   Datenblatt der Produktseite. */
#cmplz-cookies-overview .cmplz-dropdown .cookies-per-purpose .name-header,
#cmplz-cookies-overview .cmplz-dropdown .cookies-per-purpose .retention-header,
#cmplz-cookies-overview .cmplz-dropdown .cookies-per-purpose .function-header,
#cmplz-document .cmplz-dropdown .cookies-per-purpose .name-header,
#cmplz-document .cmplz-dropdown .cookies-per-purpose .retention-header,
#cmplz-document .cmplz-dropdown .cookies-per-purpose .function-header {
	font-size: var(--fs-xs);
	font-weight: 600;
	letter-spacing: 0.08em;
	text-transform: uppercase;
	color: var(--color-text-muted);
	background-color: var(--color-surface-subtle);
}

/* Der Zweck steht als Kopf über dem Raster. */
#cmplz-cookies-overview .cmplz-dropdown .cookies-per-purpose .purpose,
#cmplz-document .cmplz-dropdown .cookies-per-purpose .purpose {
	color: var(--color-text);
	font-weight: 600;
	background-color: var(--color-surface-subtle);
}

/* Cookie-Namen sind technische Angaben — Monospace, wie überall im Design. */
#cmplz-cookies-overview .cmplz-dropdown .cookies-per-purpose .name,
#cmplz-document .cmplz-dropdown .cookies-per-purpose .name {
	font-family: var(--font-mono);
	font-size: var(--fs-h6);
	color: var(--color-text);
	word-break: break-word;
}

/* --- Die Aufklapper je Dienst --------------------------------------------- */

/* Auch hier die Kette des Plugins: `#cmplz-cookies-overview .cmplz-dropdown` bzw.
   `… .cmplz-dropdown summary`. Die kürzere Fassung `.legal details.cmplz-dropdown`
   blieb auf dem hellen Grau des Plugins sitzen. */
#cmplz-cookies-overview .cmplz-dropdown,
#cmplz-document .cmplz-dropdown {
	background-color: var(--color-surface-subtle);
}

#cmplz-cookies-overview .cmplz-dropdown summary,
#cmplz-document .cmplz-dropdown summary {
	background-color: transparent;
	color: var(--color-text);
}

.legal details.cmplz-dropdown {
	margin: 0 0 var(--space-xs);
	border: 1px solid var(--b4-line);
	border-radius: var(--radius-card);
	background: var(--color-surface-subtle);
	overflow: hidden;
}

.legal summary.cmplz-service-header {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: var(--space-md);
	padding: var(--space-sm) var(--space-md);
	background: transparent;
	color: var(--color-text);
	font-weight: 600;
	cursor: pointer;
	list-style: none;
}

.legal summary.cmplz-service-header::-webkit-details-marker { display: none; }
.legal summary.cmplz-service-header:hover { color: var(--color-accent); }

/* Die Kategorie rechts im Kopf war hell auf hell. Als Label-Ebene bleibt sie
   zurückhaltend, aber lesbar. */
.legal .cmplz-service-header span:not(.cmplz-service-title) {
	font-size: var(--fs-xs);
	font-weight: 500;
	letter-spacing: 0.08em;
	text-transform: uppercase;
	color: var(--color-text-muted);
}

.legal .cmplz-service-desc { padding: 0 var(--space-md) var(--space-md); background: transparent; }

/* --- Die Einwilligungsverwaltung am Ende der Erklärung --------------------- */

#cmplz-manage-consent-container.cmplz-manage-consent-container .cmplz-categories .cmplz-category {
	background-color: var(--color-surface-subtle);
	border: 1px solid var(--b4-line);
	border-radius: var(--radius-input);
	margin-bottom: var(--space-xs);
}

#cmplz-manage-consent-container.cmplz-manage-consent-container .cmplz-categories .cmplz-category .cmplz-category-header {
	background-color: transparent;
	color: var(--color-text);
	padding: var(--space-sm) var(--space-md);
}

/* „Immer aktiv" ist ein Zustand, kein Hinweis — Verdigris statt des Browser-Grüns,
   das aus der Materialwelt fällt. */
#cmplz-manage-consent-container.cmplz-manage-consent-container .cmplz-always-active,
.legal .cmplz-status-on {
	color: var(--color-ok);
}

/* Auf Kupfer ist das dunkle Espresso des Designs die lesbarere Wahl als Weiß
   (Kontrast 8,4:1 statt 3,1:1). */
.legal input.cmplz-accept-service { color: var(--color-text-on-accent); }

/* --- Die Aufklapp-Pfeile --------------------------------------------------
   Complianz setzt sie als Hintergrundbild (`chevron-down.svg` aus dem Plugin) — eine
   dunkel gezeichnete Grafik, die auf diesem Grund praktisch verschwindet. Ein
   Hintergrundbild lässt sich nicht über `color` einfärben.

   Deshalb dieselbe Lösung wie bei der Lupe der Produktgalerie (siehe D2): Die Form
   kommt als CSS-Maske, die Farbe über `background-color`. Damit folgt der Pfeil der
   Textfarbe, wird beim Zeigen kupfern und dreht sich weiterhin beim Aufklappen — die
   Drehung steckt in `transform`, das unberührt bleibt.
   ------------------------------------------------------------------------- */

#cmplz-cookies-overview .cmplz-dropdown summary div::after,
#cmplz-document .cmplz-dropdown summary div::after {
	background-image: none;
	background-color: var(--color-text-muted);
	-webkit-mask: var(--b4-icon-chevron) center / contain no-repeat;
	mask: var(--b4-icon-chevron) center / contain no-repeat;
	transition: background-color 200ms ease, transform 500ms ease;
}

#cmplz-cookies-overview .cmplz-dropdown summary:hover div::after,
#cmplz-document .cmplz-dropdown summary:hover div::after {
	background-color: var(--color-accent);
}

/* Der geöffnete Zustand ist eine Aussage — er trägt die Akzentfarbe. */
#cmplz-cookies-overview .cmplz-dropdown[open] summary div::after,
#cmplz-document .cmplz-dropdown[open] summary div::after {
	background-color: var(--color-accent);
}

/* Die Umschalter der Einwilligungsverwaltung nutzen dieselbe Grafik. */
#cmplz-manage-consent-container .cmplz-category-header .cmplz-icon::after,
#cmplz-manage-consent-container .cmplz-category-header .cmplz-category-toggle::after {
	background-image: none;
	background-color: var(--color-text-muted);
	-webkit-mask: var(--b4-icon-chevron) center / contain no-repeat;
	mask: var(--b4-icon-chevron) center / contain no-repeat;
}

/* Die Pfeile der Einwilligungsverwaltung sind Inline-SVGs ohne `fill`-Angabe — und der
   Standardwert von `fill` ist Schwarz. Auf diesem Grund waren sie praktisch unsichtbar,
   obwohl das umgebende Element die helle Textfarbe trug: `color` allein erreicht ein SVG
   nicht, solange `fill` nicht darauf verweist.

   `currentColor` koppelt beides. Damit folgen die Icons der Textfarbe und färben sich beim
   Zeigen mit — ohne dass hier eine Farbe steht, die später auseinanderlaufen kann. Die
   Regel gilt bewusst für alle Complianz-SVGs, auch für die, die noch dazukommen. */
.legal .cmplz-icon svg,
.legal .cmplz-category-toggle svg,
#cmplz-manage-consent-container svg,
#cmplz-cookies-overview svg {
	fill: currentColor;
	color: var(--color-text-muted);
	transition: color 200ms ease;
}

.legal .cmplz-category-toggle:hover svg,
#cmplz-manage-consent-container .cmplz-category-toggle:hover svg { color: var(--color-accent); }

/* „Immer aktiv" kam im Browser-Grün (#008000) — es fällt aus der Materialwelt des
   Designs. `--color-ok` ist Verdigris, oxidiertes Kupfer, und gehört zur Familie.
   Die ID-Kette ist nötig: Complianz setzt die Farbe über eine eigene Variable in
   derselben Tiefe. */
#cmplz-manage-consent-container.cmplz-manage-consent-container .cmplz-categories .cmplz-category .cmplz-category-header .cmplz-always-active,
.legal .cmplz-always-active {
	color: var(--color-ok);
	font-size: var(--fs-xs);
	font-weight: 600;
	letter-spacing: 0.06em;
}

/* ============================================================
   Gutenberg-Blöcke aus dem Editor
   ============================================================ */

/* Die Schaltfläche des Button-Blocks trug WordPress-Voreinstellungen: #32373c als
   Grund, Kupfer als Schrift — 3,3:1 und damit unter WCAG 2.1 AA (gefunden von
   pruefen/bin/verify-a11y). Die Farbe steht in keinem Token; sie kam mit der
   Elementor-Übernahme in den Inhalt (`b4:aus-elementor-uebernommen`).
   Der Block übernimmt jetzt die Rolle der Design-Schaltfläche `.btn-primary`, die
   denselben Test besteht. Das gilt auch für Buttons, die künftig redaktionell im
   Editor entstehen — deshalb hier und nicht im Inhalt. */
.wp-block-button__link,
.wp-block-button .wp-element-button {
	display: inline-flex;
	align-items: center;
	gap: 0.55em;
	font-family: var(--font-body);
	font-weight: 700;
	text-transform: uppercase;
	letter-spacing: 0.04em;
	font-size: var(--fs-sm);
	text-decoration: none;
	border-radius: var(--radius-btn);
	border: 1px solid transparent;
	background: var(--color-accent-bright);
	color: var(--color-text-on-accent);
	padding: var(--space-xs) var(--space-xl);
	box-shadow: 0 6px 22px -8px rgb(var(--accent-bright-rgb) / 0.7);
	transition: transform var(--mo-2) var(--ease), background var(--mo-1) ease;
}
.wp-block-button__link:hover,
.wp-block-button .wp-element-button:hover { transform: translateY(-2px); }
