/*
 * Kaart D en het productgrid (deelproject 7 van het blokthema). Zie
 * docs/superpowers/specs/2026-09-27-blokthema-4-7-winkel-en-kaart.md,
 * "Opbouw en maten".
 *
 * Grid en kaart staan samen, zoals in de spec: kolombreedte, inset en het
 * aantal fotootjes hangen van elkaar af, en het grid bestaat alleen waar
 * kaarten staan.
 *
 * Maten komen uit tokens: vaste uit --wp--preset--* en --wp--custom--*, die
 * per breedte schakelen uit --dg-* van het thema. Wat alleen de kaart per
 * breedte kent (de maat van een fotootje, het ritme in de kaart, hoeveel
 * varianten er staan), schakelt hier, op een breakpoint van DreamGlow, in de
 * vorm van WordPress en met waarden uit de schaal. Lijnen en ringen komen uit
 * custom.lijn en custom.focus; een letterlijk getal staat er alleen voor het
 * visueel verbergen (1px, 50%), het vullen van een vlak (100%), de regel
 * "grootte + 8" (1em), de gedraaide sticker (-4deg), de lagen (z-index 0
 * en 1, binnen de kaart) en de plaats in het subgrid (rijnummers). Elk
 * getal alleen in de eigenschap van zijn doel: CssRegelsTest in
 * devenv/tests/test_blok_winkel.py bewaakt dat.
 */

/*
 * Het grid: Product Template met de klasse dg-productgrid. De uitloop staat
 * op deze ul, een laag onder de Product Collection: op een direct kind van
 * een constrained groep zet WordPress de zijmarges op auto !important. Tot
 * en met 450 px loopt het grid zo van rand tot rand; daarboven staat het
 * gelijk met titel en werkbalk. Woo geeft de lijst max-width: 100%; die gaat
 * eraf, anders houdt hij de uitloop tegen.
 *
 * Elke kaart beslaat vijf rijen van het grid: beeld, varianten, naam,
 * prijsregel en foutmelding. Het item, de kaart en het tekstdeel geven die
 * rijen door met subgrid. Zo hebben de kaarten in een rij dezelfde
 * rijhoogtes, en liggen namen en prijsregels op één lijn, ook als één kaart
 * een oude prijs heeft of een variantnaam op twee regels (spec, "Maten en
 * letters"). De rijafstand staat daarom niet als row-gap op het grid (die
 * viel ook tussen de rijen binnen een kaart), maar onder elke kaart. Onder de
 * laatste rij trekt het grid hem weer terug.
 */
.wp-block-woocommerce-product-collection .wc-block-product-template.dg-productgrid {
	display: grid;
	grid-template-columns: repeat(var(--dg-grid-kolommen), minmax(0, 1fr));
	column-gap: var(--dg-grid-kolomafstand);
	row-gap: 0;
	max-inline-size: none;
	margin-block: 0 calc(0px - var(--dg-grid-rijafstand));
	margin-inline: var(--dg-grid-uitloop);
	padding: 0;
}

.wp-block-woocommerce-product-collection .wc-block-product-template.dg-productgrid > .wc-block-product {
	display: grid;
	grid-row: span 5;
	grid-template-rows: subgrid;
	margin: 0 0 var(--dg-grid-rijafstand);
	inline-size: auto;
	max-inline-size: none;
}

/* De kaart in het grid: dezelfde vijf rijen, in de volgorde van beeld tot
   foutmelding. De varianten staan zo boven de naam zonder order. Buiten het
   grid (een carrousel, een losse kaart) blijft de kaart een flexkolom. */
.dg-productgrid .dg-kaart {
	display: grid;
	grid-row: span 5;
	grid-template-rows: subgrid;
	grid-template-columns: minmax(0, 1fr);
}

.dg-productgrid .dg-kaart__beeld {
	grid-row: 1;
}

.dg-productgrid .dg-kaart__koop {
	display: grid;
	grid-row: 2 / span 4;
	grid-template-rows: subgrid;
	grid-template-columns: minmax(0, 1fr);
}

.dg-productgrid .dg-kaart__varianten {
	grid-row: 1;
}

.dg-productgrid .dg-kaart__naam {
	grid-row: 2;
}

/* De prijsregel vult zijn rij: alle prijsregels van een rij even hoog, met
   prijs en tasje op de onderkant (zie .dg-kaart__prijsregel). */
.dg-productgrid .dg-kaart__prijsregel {
	grid-row: 3;
	margin-block-start: 0;
}

.dg-productgrid .dg-kaart__fout {
	grid-row: 4;
}

/* De kaart. */
.dg-kaart {
	--dg-kaart-fotootje: var(--wp--preset--spacing--32);
	--dg-kaart-vlak: var(--dg-raakvlak);
	--dg-kaart-ritme-varianten: var(--wp--preset--spacing--8);
	--dg-kaart-ritme-naam: var(--wp--preset--spacing--4);
	position: relative;
	isolation: isolate;
	display: flex;
	flex-direction: column;
	inline-size: 100%;
	color: var(--wp--preset--color--ink);
}

@media (width > 1023px) {
	.dg-kaart {
		--dg-kaart-fotootje: var(--wp--preset--spacing--40);
		--dg-kaart-vlak: var(--wp--preset--spacing--48);
		--dg-kaart-ritme-varianten: var(--wp--preset--spacing--16);
		--dg-kaart-ritme-naam: var(--wp--preset--spacing--8);
	}
}

/* Het beeldvlak: 4:5, beige (jade), gelijk aan de achtergrond van de
   productfoto's: die sluiten er naadloos op aan (besluit van de eigenaar,
   13-10-2026; was crème met multiply, 4/7 Q2). */
.dg-kaart__beeld {
	position: relative;
	aspect-ratio: var(--wp--preset--aspect-ratio--product);
	overflow: hidden;
	border-radius: var(--wp--custom--radius--standaard);
	background: var(--wp--preset--color--jade);
}

/* De foto vult het hele vlak en staat er met contain in het midden in. Met
   één klasse won Woo's .woocommerce img { height: auto } (0,1,1), en stond
   een vierkante foto bovenaan het 4:5-vlak (vergelijking met de
   Rituals-analyse, 13-10-2026, C-33). Twee klassen: 0,2,0. */
.dg-kaart__beeld > .dg-kaart__foto {
	position: absolute;
	inset: 0;
	display: block;
	inline-size: 100%;
	block-size: 100%;
	object-fit: contain;
}

/* Labels linksboven: links op de inset, 16 van boven, 8 ertussen. Zonder
   eigen laag: de link van de naam ligt eroverheen, dus een klik op een label
   gaat ook naar het product, net als een klik op de foto. */
.dg-kaart__labels {
	position: absolute;
	inset-block-start: var(--wp--preset--spacing--16);
	inset-inline-start: var(--dg-kaart-inset);
	display: flex;
	flex-wrap: wrap;
	gap: var(--wp--preset--spacing--8);
	margin: 0;
	padding: 0;
	list-style: none;
}

.dg-kaart__label {
	padding-block: var(--wp--preset--spacing--4);
	padding-inline: var(--wp--preset--spacing--8);
	border-radius: var(--wp--custom--radius--standaard);
	box-shadow: var(--wp--preset--shadow--klein);
	font-family: var(--wp--preset--font-family--body);
	font-size: var(--wp--preset--font-size--xs);
	line-height: var(--wp--custom--leading--xs);
	letter-spacing: var(--wp--custom--spatie--kapitaal-klein);
	text-transform: uppercase;
	/* De gedraaide sticker: de signatuur van de labels van het oude thema (.onsale). */
	transform: rotate(-4deg);
}

.dg-kaart__label[hidden] {
	display: none;
}

.dg-kaart__label--sale {
	background: var(--wp--preset--color--moss);
	color: var(--wp--preset--color--paper);
}

.dg-kaart__label--eigen {
	background: var(--wp--preset--color--grain);
	color: var(--wp--preset--color--ink);
}

.dg-kaart__label--uitverkocht {
	background: var(--wp--preset--color--paper);
	color: var(--wp--preset--color--ink);
}

/* Het tekstdeel, met de inset rondom. */
.dg-kaart__koop {
	display: flex;
	flex: 1 1 auto;
	flex-direction: column;
	margin: 0;
	padding: var(--dg-kaart-inset);
}

/* De varianten staan in de DOM na de naam (tabvolgorde naam, varianten, +N,
   tasje) en in beeld erboven. De rij houdt ook zonder varianten zijn hoogte,
   zodat de namen in een rij gelijk beginnen. */
.dg-kaart__varianten {
	order: -1;
	display: flex;
	align-items: center;
	gap: var(--wp--preset--spacing--4);
	min-inline-size: 0;
	min-block-size: var(--dg-kaart-vlak);
	margin: 0 0 var(--dg-kaart-ritme-varianten);
	padding: 0;
	border: 0;
}

/* Een raakvlak per variant. Het krimpt als het moet, tot de maat van het
   fotootje: zo loopt de rij nooit uit de kaart ("Nooit te breed"), ook niet
   met het raakvlak van 44 op een tablet. */
.dg-kaart__optie {
	position: relative;
	z-index: 1;
	display: inline-flex;
	flex: 0 1 var(--dg-kaart-vlak);
	align-items: center;
	justify-content: center;
	min-inline-size: var(--dg-kaart-fotootje);
	block-size: var(--dg-kaart-vlak);
	cursor: pointer;
}

/* Woo geeft elk label een marge van 0,7em onder (.woocommerce-page label,
   0,1,1): 11,2, de enige maat buiten het raster van 4, en de reden dat een
   kaart zonder varianten in de carrousel 11 hoger stond (13-10-2026, L-28 en
   C-53). Twee klassen: 0,2,0. */
.dg-kaart .dg-kaart__optie {
	margin: 0;
}

/* Rond een tekstknopje 4 opzij: de focusring om het raakvlak wordt zo een
   tweede, ruimere ring naast de ring van de keuze. */
.dg-kaart--maat .dg-kaart__optie {
	flex: 0 1 auto;
	min-inline-size: 0;
	padding-inline: var(--wp--preset--spacing--4);
}

/* "+N": een link naar het product, in een raakvlak van minstens 24 breed
   (WCAG 2.5.8), met de tekst in het midden. */
.dg-kaart__meer {
	position: relative;
	z-index: 1;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-inline-size: var(--wp--preset--spacing--24);
	min-block-size: var(--dg-kaart-vlak);
	padding-inline: var(--wp--preset--spacing--4);
	font-size: var(--wp--preset--font-size--s);
	line-height: var(--wp--custom--leading--s);
	color: var(--wp--preset--color--ink-soft);
	text-decoration: underline;
	white-space: nowrap;
}

/* Hoeveel varianten er staan: kleuren 2, vanaf 640 3; maten 2, vanaf 1024 3.
   "+N" telt de rest. Na de regel voor .dg-kaart__meer: bij gelijke
   specificiteit wint de laatste, en anders stond "+4" naast "+5". */
.dg-kaart__optie--derde,
.dg-kaart__meer--3 {
	display: none;
}

@media (width > 639px) {
	.dg-kaart--kleur .dg-kaart__optie--derde,
	.dg-kaart--kleur .dg-kaart__meer--3 {
		display: inline-flex;
	}

	.dg-kaart--kleur .dg-kaart__meer--2 {
		display: none;
	}
}

@media (width > 1023px) {
	.dg-kaart--maat .dg-kaart__optie--derde,
	.dg-kaart--maat .dg-kaart__meer--3 {
		display: inline-flex;
	}

	.dg-kaart--maat .dg-kaart__meer--2 {
		display: none;
	}
}

/* Het keuzerondje is onzichtbaar maar bereikbaar: het label is het vlak. */
.dg-kaart__rondje {
	position: absolute;
	inline-size: 1px;
	block-size: 1px;
	margin: 0;
	overflow: hidden;
	clip-path: inset(50%);
	white-space: nowrap;
	opacity: 0;
}

.dg-kaart__fotootje {
	display: block;
	flex: none;
	inline-size: var(--dg-kaart-fotootje);
	block-size: var(--dg-kaart-fotootje);
	overflow: hidden;
	border-radius: var(--wp--custom--radius--standaard);
	background: var(--wp--preset--color--jade);
}

.dg-kaart__fotootje img {
	display: block;
	inline-size: 100%;
	block-size: 100%;
	object-fit: contain;
}

/* Het tekstknopje: 32 hoog (40 vanaf 1024), de rand inbegrepen. */
.dg-kaart__maat {
	box-sizing: border-box;
	display: inline-flex;
	align-items: center;
	block-size: var(--dg-kaart-fotootje);
	padding-inline: var(--wp--preset--spacing--8);
	border: var(--wp--custom--lijn--dun) solid var(--wp--preset--color--line);
	border-radius: var(--wp--custom--radius--standaard);
	font-size: var(--wp--preset--font-size--s);
	line-height: var(--wp--custom--leading--s);
	white-space: nowrap;
}

/* De ring staat er altijd, transparant: dan verloopt alleen zijn kleur, in
   300 ms op de standaardcurve, zoals de ring op de productpagina (spec 1b,
   "Beweging"; 13-10-2026, C-14). */
.dg-kaart__fotootje,
.dg-kaart__maat {
	outline: var(--wp--custom--lijn--dik) solid transparent;
	outline-offset: var(--wp--custom--focus--afstand);
	transition: outline-color var(--wp--custom--duur--standaard) var(--wp--custom--curve);
}

@media (prefers-reduced-motion: reduce) {
	.dg-kaart__fotootje,
	.dg-kaart__maat {
		transition: none;
	}
}

/* Uitverkocht: dezelfde markering als op de productpagina
   (blocks/variantkeuze/style.css, 5e): over een fotootje een schuine lijn in
   ink-soft, een maatknopje doorgestreept. De naam van het rondje zegt het ook
   ("uitverkocht"). Besluit eigenaar 13-10-2026 (C-15). */
.dg-kaart__fotootje {
	position: relative;
}

.dg-kaart__optie.is-uitverkocht .dg-kaart__fotootje::before {
	content: "";
	position: absolute;
	inset: 0;
	z-index: 1;
	background: var(--wp--preset--color--ink-soft);
	clip-path: polygon(0 calc(100% - var(--wp--custom--lijn--dun)), calc(100% - var(--wp--custom--lijn--dun)) 0, 100% 0, 100% var(--wp--custom--lijn--dun), var(--wp--custom--lijn--dun) 100%, 0 100%);
	pointer-events: none;
}

.dg-kaart__optie.is-uitverkocht .dg-kaart__maat {
	color: var(--wp--preset--color--ink-soft);
	text-decoration-line: line-through;
}

/* Gekozen: een ring van 2 px in moss, 2 px van de foto af: de afstand van de
   focusring. */
.dg-kaart__rondje:checked + .dg-kaart__fotootje,
.dg-kaart__rondje:checked + .dg-kaart__maat {
	outline: var(--wp--custom--lijn--dik) solid var(--wp--preset--color--moss);
	outline-offset: var(--wp--custom--focus--afstand);
}

@media (hover: hover) {
	.dg-kaart__optie:hover .dg-kaart__rondje:not(:checked) + .dg-kaart__fotootje,
	.dg-kaart__optie:hover .dg-kaart__rondje:not(:checked) + .dg-kaart__maat {
		outline: var(--wp--custom--lijn--dik) solid var(--wp--preset--color--metadata);
		outline-offset: var(--wp--custom--focus--afstand);
	}
}

/* Focus: de ring uit het ontwerpsysteem om het hele raakvlak. */
.dg-kaart__optie:has(.dg-kaart__rondje:focus-visible) {
	outline: var(--wp--custom--focus-ring);
	outline-offset: var(--wp--custom--focus--afstand);
}

/* De naam: de enige link die de hele kaart dekt. Ook bij aanwijzen in de
   kleur kop: de hover-kleur van links uit theme.json (ink) geldt hier niet. */
.dg-kaart__naam {
	margin: 0 0 var(--dg-kaart-ritme-naam);
	font-family: var(--wp--preset--font-family--display);
	font-size: var(--dg-rol-productnaam);
	font-weight: 500;
	line-height: calc(1em + var(--wp--preset--spacing--8));
	letter-spacing: var(--wp--custom--spatie--krap);
	color: var(--wp--preset--color--kop);
}

.dg-kaart__naam a,
.dg-kaart__naam a:hover {
	color: inherit;
	text-decoration: none;
}

.dg-kaart__naam a::after {
	content: "";
	position: absolute;
	inset: 0;
	z-index: 0;
}

@media (hover: hover) {
	.dg-kaart:hover .dg-kaart__naam a {
		text-decoration: underline;
	}
}

/* De prijsregel staat onderaan. In het grid vult hij zijn rij van het
   subgrid (hierboven); daarbuiten duwt margin-top: auto hem naar beneden.
   Prijs en tasje staan op zijn onderkant: zo liggen de huidige prijzen van
   een rij op één lijn, ook naast een kaart met een oude prijs erboven. */
.dg-kaart__prijsregel {
	display: flex;
	align-items: end;
	justify-content: space-between;
	gap: var(--wp--preset--spacing--8);
	margin-block-start: auto;
}

/* Onder de prijs de helft van wat het tasje hoger is dan de regel van de
   prijs ("grootte + 8"): zo staat het tasje midden op die regel, ook als er
   een oude prijs boven staat. */
.dg-kaart__prijs {
	flex: 1 1 auto;
	min-inline-size: 0;
	margin: 0;
	padding-block-end: calc((var(--dg-raakvlak) - (var(--dg-rol-productnaam) + var(--wp--preset--spacing--8))) / 2);
	font-family: var(--wp--preset--font-family--display);
	font-size: var(--dg-rol-productnaam);
	font-weight: 500;
	line-height: calc(1em + var(--wp--preset--spacing--8));
	letter-spacing: var(--wp--custom--spatie--krap);
	color: var(--wp--preset--color--kop);
}

/* Een prijsoptie: de oude prijs op een eigen regel erboven, dan de huidige
   prijs met de variantnaam ernaast, op één regel: de onderste. Zo liggen de
   huidige prijzen van een rij op één lijn. */
.dg-kaart__prijsoptie {
	display: flex;
	flex-wrap: wrap;
	align-items: baseline;
	column-gap: var(--wp--preset--spacing--4);
}

.dg-kaart__prijsoptie[hidden] {
	display: none;
}

/*
 * Zonder JavaScript: na een keuze de prijs van het gekozen rondje, niet die
 * van de standaardvariant (afwijkingen 4/7, taak 5). Rondjes en prijsopties
 * staan in dezelfde volgorde, die van de getoonde varianten (hooguit drie,
 * dreamglow_kaart_zichtbaar()). Met JavaScript zegt hidden hetzelfde:
 * view.js houdt het gekozen rondje en de getoonde prijs gelijk. Een kaart
 * zonder rondjes houdt zijn enige prijsoptie.
 */
.dg-kaart:has(.dg-kaart__rondje:checked) .dg-kaart__prijsoptie {
	display: none;
}

.dg-kaart:has(.dg-kaart__optie:nth-of-type(1) > .dg-kaart__rondje:checked) .dg-kaart__prijsoptie:nth-of-type(1),
.dg-kaart:has(.dg-kaart__optie:nth-of-type(2) > .dg-kaart__rondje:checked) .dg-kaart__prijsoptie:nth-of-type(2),
.dg-kaart:has(.dg-kaart__optie:nth-of-type(3) > .dg-kaart__rondje:checked) .dg-kaart__prijsoptie:nth-of-type(3) {
	display: flex;
}

/* De oude prijs: kleiner, ink-soft, doorgestreept, op een eigen regel boven
   de prijs. */
.dg-kaart__prijs del {
	display: block;
	flex-basis: 100%;
	font-size: var(--dg-rol-oude-prijs);
	line-height: var(--wp--custom--leading--m);
	letter-spacing: 0;
	color: var(--wp--preset--color--ink-soft);
	text-decoration: line-through;
}

.dg-kaart__prijs ins {
	text-decoration: none;
}

/* De variantnaam in de rol klein: Jost 400, niet de 500 van de prijs
   (ontwerpsysteem, regel 3). */
/* Past de variantnaam niet naast de prijs ("Zwart/paars" op 390, 640 en
   700), dan kort hij af met een beletselteken. Op een tweede regel zou de
   prijs niet meer onderaan staan, en hij breekt alleen na "·": dan bleef er
   een losse punt boven de naam staan. De hele naam blijft in de tekst voor
   schermlezers, en in de naam van het keuzerondje. */
.dg-kaart__variantnaam {
	flex: 1 1 0;
	min-inline-size: 0;
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
	font-family: var(--wp--preset--font-family--body);
	font-weight: normal;
	font-size: var(--wp--preset--font-size--s);
	line-height: var(--wp--custom--leading--s);
	letter-spacing: 0;
	color: var(--wp--preset--color--ink-soft);
}

/* Het tasje: rond, moss met een wit icoon (5,4:1); 40, en 44 bij aanraken. */
/* Een knop, of een link bij een product dat de kaart niet zelf in de
   winkelwagen legt (extern, gegroepeerd, zonder prijs; codereview V16). */
.dg-kaart__tas {
	position: relative;
	z-index: 1;
	display: inline-grid;
	flex: none;
	place-items: center;
	inline-size: var(--dg-raakvlak);
	block-size: var(--dg-raakvlak);
	padding: 0;
	border: 0;
	border-radius: var(--wp--custom--radius--rond);
	background: var(--wp--preset--color--moss);
	color: var(--wp--preset--color--paper);
	text-decoration: none;
	cursor: pointer;
	transition: background-color var(--wp--custom--duur--standaard) var(--wp--custom--curve);
}

.dg-kaart__tas svg {
	inline-size: var(--wp--preset--spacing--24);
	block-size: var(--wp--preset--spacing--24);
}

@media (hover: hover) {
	.dg-kaart__tas:hover {
		background: var(--wp--preset--color--knop-hover);
	}
}

/* Uitverkocht: een stiller vlak; een klik doet niets (view.js). De server
   rendert het tasje neutraal; view.js zet deze klasse bij de hydratatie. */
.dg-kaart__tas.is-uitverkocht {
	background: var(--wp--preset--color--line);
	color: var(--wp--preset--color--ink-soft);
	cursor: not-allowed;
}

.dg-kaart__tas[aria-busy="true"] {
	cursor: progress;
}

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

.dg-kaart__fout {
	margin: var(--wp--preset--spacing--8) 0 0;
	font-size: var(--wp--preset--font-size--s);
	line-height: var(--wp--custom--leading--s);
	color: var(--wp--preset--color--error);
}

.dg-kaart__fout[hidden] {
	display: none;
}
