/*
Theme Name: Flouncy
Theme URI: https://flouncyshop.com/
Author: Flouncy
Description: Thème bloc de la boutique Flouncy — accessoires de mode cousus main.
Requires at least: 7.1
Tested up to: 7.1
Requires PHP: 8.4
Version: 0.1.0
License: Proprietary
Text Domain: flouncy
*/

/*
 * theme.json porte les tokens et la quasi-totalité des styles.
 * Ce fichier ne contient que ce que theme.json ne sait pas exprimer.
 */

/*
 * Soulignement de focus : `:focus-visible`, jamais `:focus`.
 *
 * `theme.json` ne sait écrire que `:focus` (WordPress n'accepte pas
 * `:focus-visible` dans les pseudo-sélecteurs d'un élément), et `:focus` se
 * déclenche AUSSI au clic souris. Le lien gardait donc son soulignement une fois
 * le pointeur parti — deux barres sous la page courante du menu, qui en porte
 * déjà une. Le soulignement vit ici, où la distinction clavier/souris s'écrit.
 *
 * Même forme que la règle de `theme.json` (`:root :where(…)`, spécificité 0-1-0)
 * pour que les neuf composants qui posent déjà `text-decoration: none` sur leurs
 * propres états continuent de gagner. La feuille du thème est chargée après les
 * styles globaux : à spécificité égale, c'est l'ordre qui tranche.
 */
:root :where(a:where(:not(.wp-element-button)):focus-visible) {
	text-decoration: underline;
}

/*
 * Même piège sur le bouton : `theme.json` posait le rose du survol sur `:focus`,
 * et « Offrir une carte cadeau » restait rose une fois la souris partie. Les
 * composants qui ont leur propre anneau de focus gardent la main — comme pour
 * le lien, la spécificité 0-1-0 les laisse passer devant.
 */
:root :where(.wp-element-button:focus-visible, .wp-block-button__link:focus-visible) {
	background-color: var(--wp--preset--color--pink);
	color: var(--wp--custom--color--on-pink);
}

/*
 * Le curseur de la maquette : une pastille rose qui suit le pointeur et double
 * de taille au-dessus de ce qui se clique. `mix-blend-mode: multiply` la fait
 * foncer sur les aplats au lieu de les masquer — c'est ce qui la rend lisible
 * sur l'olive comme sur le crème.
 *
 * `cursor: none` n'est posé QUE si `flcy-curseur-pose` est là, et cette classe
 * est ajoutée par le module une fois la pastille en place. Masquer le curseur
 * système depuis une feuille statique reviendrait à promettre un remplacement
 * que seul le JavaScript sait dessiner : s'il ne charge pas, la cliente n'a
 * plus aucun pointeur. Le module s'abstient aussi sur pointeur grossier et en
 * `forced-colors`.
 */
.flcy-curseur-pose,
.flcy-curseur-pose * {
	cursor: none;
}

#flcy-curseur {
	position: fixed;
	inset-block-start: 0;
	inset-inline-start: 0;
	z-index: 9999;
	width: var(--wp--custom--cursor--size);
	height: var(--wp--custom--cursor--size);
	margin-block-start: calc(var(--wp--custom--cursor--size) / -2);
	margin-inline-start: calc(var(--wp--custom--cursor--size) / -2);
	border-radius: var(--wp--custom--radius--pill);
	background: var(--wp--preset--color--pink-light);
	mix-blend-mode: multiply;
	pointer-events: none;

	/*
	 * Le grossissement est un `scale` (57,2 px de la maquette ÷ 26), pas une
	 * largeur : animer `width` et `margin` recalculait la mise en page à chaque
	 * survol. Le module pose la position en `translate` et non en `transform`,
	 * parce que `transform` s'applique avant `scale` : le déplacement aurait été
	 * multiplié par 2,2, et la pastille serait partie loin du pointeur.
	 */
	transition: scale 180ms ease;
	will-change: translate, scale;
}

#flcy-curseur.is-link {
	scale: var(--wp--custom--cursor--link-scale);
}

/* La pastille suit le pointeur au pixel : ce n'est pas du mouvement décoratif,
   et la couper priverait de tout curseur. Seul son grossissement s'arrête. */
@media (prefers-reduced-motion: reduce) {

	#flcy-curseur {
		transition: none;
	}
}

/*
 * En-tête fixe qui se compacte au défilement.
 *
 * `fixed` et non `sticky` : en compactant, un en-tête sticky rend 45 px au flux
 * et TOUT le contenu remonte. Un défilement n'ouvre pas la fenêtre de grâce du
 * CLS — seule une interaction discrète le fait — donc ce saut compterait contre
 * le budget. La maquette résout la même chose de la même façon : elle sort
 * l'en-tête du flux et réserve sa hauteur ÉTENDUE, une bonne fois.
 *
 * La réserve est un jeton et non une mesure JS : mesurer après le premier
 * rendu, c'est décaler la page une fois le module chargé. `tests/e2e` vérifie
 * que le jeton vaut bien la hauteur rendue — l'invariant échoue en CI plutôt
 * que de dériver en silence.
 */
.wp-site-blocks {
	box-sizing: border-box;
	padding-block-start: var(--wp--custom--header--height);
}

.wp-site-blocks > header {
	position: fixed;
	inset-block-start: 0;
	inset-inline: 0;
	z-index: 60;
}

/*
 * La bascule redéfinit les JETONS, elle ne repose pas les propriétés : la part
 * pose son `padding` en `style=` inline, qu'une règle de classe ne peut écraser
 * sans `!important` (ADR 0001). Redéclarer la variable sur l'élément lui-même, si.
 */
.flouncy-header {
	/*
	 * L'en-tête étendu remplit sa réserve au pixel près. Sa hauteur naturelle suit
	 * la police fluide de la pilule du panier — 221 px sous 782 px de large, 223
	 * au-delà — alors que la réserve est un jeton fixe : sans ce plancher, deux
	 * pixels de fond de page passaient entre l'en-tête et la vague, en trait gris.
	 */
	min-height: var(--wp--custom--header--height);
	transition: padding 200ms ease;
}

/*
 * Compacté, l'en-tête reste en COLONNE : logo centré, barre dessous. Le
 * `headerDir: row` du code de la maquette ne vise que le conteneur du logo, qui
 * ne porte que l'image — lu comme la disposition de l'en-tête, il avait mis
 * logo et barre sur une ligne, et la barre s'écrasait sur un téléphone.
 */
.flouncy-header.is-compact {
	--wp--custom--header--pad-top: var(--wp--custom--header--pad-top-compact);
	--wp--custom--header--pad-bottom: var(--wp--custom--header--pad-bottom-compact);
	--wp--custom--header--bar-gap: var(--wp--custom--header--bar-gap-compact);
	--wp--custom--header--logo: var(--wp--custom--header--logo-compact);
	min-height: 0;
}

/*
 * Le logo de la maquette est cadré en HAUTEUR, sa largeur suit. Quand la
 * largeur bute sur `max-width` (320 px), `contain` garde ses proportions au lieu
 * de l'écraser.
 */
.flouncy-header__logo .wp-block-site-logo img {
	height: var(--wp--custom--header--logo);
	width: auto;
	max-width: 100%;
	object-fit: contain;
	transition: height 200ms ease;
}

@media (prefers-reduced-motion: reduce) {
	.flouncy-header,
	.flouncy-header__logo .wp-block-site-logo img {
		transition: none;
	}
}


/*
 * Cartes produit — habillage des blocs WooCommerce.
 * Sélecteurs alignés sur la spécificité de WooCommerce, sans !important (ADR 0001).
 */
/*
 * Socle commun aux cartes verticales et aux cartes de cross-sell. Chacune pose
 * ensuite sa gouttière, son fond, son rayon et ses retraits : un `padding-bottom`
 * laissé ici s'ajoutait aux 18 px du pied des cartes verticales — 44 px sous
 * « Voir la fiche » au lieu de 18 (26/09).
 */
.wp-block-woocommerce-product-template > li {
	position: relative;
	display: flex;
	flex-direction: column;
	overflow: hidden;
	padding: 0;
	box-shadow: var(--wp--custom--shadow--sm);
}

.wp-block-woocommerce-product-template > li .wc-block-components-product-image {
	margin: 0 0 var(--wp--preset--spacing--14);
	padding-inline: 0;
}

/* Le badge ne touche jamais le bord droit : sans borne, il allait jusqu'à l'arrondi
   de la carte, que `overflow: hidden` rognait. */
.wp-block-woocommerce-product-template > li .flouncy-stock-badge {
	position: absolute;
	inset-block-start: var(--wp--preset--spacing--14);
	inset-inline-start: var(--wp--preset--spacing--14);
	z-index: 1;
	max-width: calc(100% - 2 * var(--wp--preset--spacing--14));
	padding-inline: var(--wp--preset--spacing--14);
}

/*
 * « Les préférées de l'atelier » : une carte par ligne sur téléphone (décision du
 * 26/09). La colonne minimale est celle qui porte le badge long sur une ligne —
 * « Édition limitée · 20 pièces restantes », 205 px, plus ses deux retraits de
 * 14 — au lieu des 150 px de WooCommerce, qui rangeaient deux cartes de 168 px à
 * 390 px et cassaient le badge sur deux lignes. Même `auto-fill` que WooCommerce,
 * même terme de gouttière : pas de media query, la grille passe d'elle-même à deux
 * colonnes sous ~825 px de fenêtre et à une seule sous ~545 (mesuré le 26/09) —
 * à 782 px, trois colonnes de 227 px auraient encore cassé le badge. La boutique
 * garde ses deux colonnes mobiles, comme l'écran Mobile de la maquette : son badge
 * court y tient.
 */
.flouncy-preferees .wc-block-product-template__responsive.columns-3 {
	grid-template-columns: repeat(auto-fill, minmax(max(var(--wp--custom--product--card-min), calc(33.33333% - 0.83333em)), 1fr));
}

/*
 * Réseaux sociaux — en-tête et pied.
 *
 * La maquette en fait des cercles de 44 px portant une icône de 26 px, et pose
 * une pastille colorée au survol. Le rendu du cœur donnait une cible de 16 px,
 * sous les 24 px exigés par « Taille de cible (minimum) » (WCAG 2.2 AA, 2.5.8) :
 * axe ne mesure pas ce critère, et c'est pour cela que le lot 8 l'a laissé passer.
 */
.wp-block-social-links.is-style-logos-only {
	gap: var(--wp--custom--social--gap);
}

.wp-block-social-links.is-style-logos-only .wp-social-link {
	border-radius: var(--wp--custom--radius--pill);
}

.wp-block-social-links.is-style-logos-only .wp-block-social-link-anchor {
	display: flex;
	align-items: center;
	justify-content: center;
	width: var(--wp--custom--social--target);
	height: var(--wp--custom--social--target);
	padding: 0;
}

.wp-block-social-links.is-style-logos-only .wp-block-social-link-anchor svg {
	width: var(--wp--custom--social--icon);
	height: var(--wp--custom--social--icon);
}

/*
 * Les trois icônes de la maquette sont TRACÉES, pas remplies : `Site\Social_Icons`
 * échange les logos du cœur, et le remplissage doit suivre — sinon l'appareil
 * photo et la devanture se bouchent. Le point de l'objectif, lui, porte son
 * propre `fill` en attribut de présentation : il reste plein.
 *
 * Le sélecteur est long parce que le cœur écrit `fill: currentColor` sur le SVG
 * avec quatre classes empilées, et qu'une règle CSS prime sur l'attribut
 * `fill="none"` du balisage. Il faut donc passer devant lui — d'où la classe
 * `flouncy-social-icon`, posée par le filtre, qui ajoute le cran qui manque.
 */
.wp-block-social-links.is-style-logos-only .wp-social-link .wp-block-social-link-anchor svg.flouncy-social-icon {
	fill: none;
	stroke: currentcolor;
}

/*
 * Le cœur agrandit l'icône de 10 % au survol. L'agrandissement n'est pas dans la
 * maquette et il pousse ses voisines ; la pastille, elle, ne déplace rien.
 */
.wp-block-social-links.is-style-logos-only .wp-social-link:hover,
.wp-block-social-links.is-style-logos-only .wp-social-link:focus-within {
	background: var(--wp--preset--color--blush);
	transform: none;
}

.flouncy-header__actions .wp-block-social-links.is-style-logos-only .wp-social-link:hover,
.flouncy-header__actions .wp-block-social-links.is-style-logos-only .wp-social-link:focus-within {
	background: var(--wp--preset--color--pink-light);
}

/*
 * La teinte se pose sur l'ANCRE, pas sur le SVG : le bloc écrit sa couleur en
 * style en ligne sur le `li`, hors de portée d'une règle de classe — l'ancre,
 * elle, n'en porte pas. Le tracé et le point de l'objectif suivent alors tous
 * les deux `currentColor`, au lieu de se désolidariser au survol.
 */
.wp-block-social-links.is-style-logos-only .wp-social-link:hover .wp-block-social-link-anchor,
.wp-block-social-links.is-style-logos-only .wp-social-link:focus-within .wp-block-social-link-anchor {
	color: var(--wp--custom--color--plum-strong);
}

/* Pied de page. La rangée logo + réseaux vient de la mise en page flex du groupe. */
.flouncy-footer__brand .wp-block-site-logo img {
	width: var(--wp--custom--footer--logo);
	max-width: 100%;
	height: auto;
}

/*
 * Liens légaux du pied de page : une liste de navigation, pas une énumération.
 * L'alignement vit ici : ni la colonne ni la liste ne prennent en charge
 * `typography.textAlign`, et l'écrire dans leur commentaire les rendait
 * invalides à l'ouverture de l'éditeur de site.
 */
.flouncy-footer__links {
	list-style: none;
	margin: 0;
	padding: 0;
	text-align: end;
}

/*
 * Ajout au panier depuis une grille : WooCommerce démasque un lien « Voir le
 * panier » sous le bouton. Mesuré le 19/09 : la carte passait de 531 à 566 px,
 * sa voisine de rangée grandissait avec elle, et le bouton de la carte cliquée
 * remontait de 17 px — deux boutons côte à côte, plus alignés.
 *
 * L'information est déjà donnée deux fois : le bouton devient « 1 dans le
 * panier », et la pastille de l'en-tête compte les pièces et mène au panier.
 * Réserver la place du lien creuserait un vide sous chaque carte, que la
 * maquette ne montre pas.
 */
.wp-block-woocommerce-product-template .wc-block-components-product-button > span:has(> .added_to_cart),
.wp-block-woocommerce-product-template .wc-block-components-product-button .added_to_cart {
	display: none;
}

/*
 * Tri du catalogue. WooCommerce rend un menu déroulant nu : au milieu d'une page
 * dessinée, il était le seul élément à ressembler à un formulaire de navigateur.
 * Valeurs relevées sur la maquette le 19/09 — pilule crème, filet d'encre à 16 %,
 * 9/16 de retrait. Le libellé « Trier par » vit dans le gabarit, à côté : le
 * menu, lui, garde son propre nom accessible.
 */
.flouncy-tri .wc-block-catalog-sorting select,
.flouncy-tri select {
	padding: var(--wp--preset--spacing--8) var(--wp--preset--spacing--18);
	border: 1px solid var(--wp--custom--color--hairline);
	border-radius: var(--wp--custom--radius--pill);
	background: var(--wp--custom--color--card);
	color: var(--wp--preset--color--ink);
	font-family: var(--wp--preset--font-family--body);
	font-size: var(--wp--preset--font-size--small);
	cursor: pointer;
}

.flouncy-tri select:hover {
	border-color: var(--wp--custom--color--hairline-strong);
}

.flouncy-tri select:focus-visible {
	outline: 2px solid var(--wp--preset--color--plum);
	outline-offset: 2px;
}

.flouncy-tri > p {
	margin: 0;
	color: var(--wp--custom--color--muted);
}

/* Catalogue — la maquette borde les cartes d'un pointillé rose. */
.flouncy-catalogue .wp-block-woocommerce-product-template > li {
	border: 1px dashed var(--wp--preset--color--pink);
	box-shadow: none;
}

/*
 * Une carte produit se soulève au survol — c'est le seul retour que la maquette
 * donne sur une carte, sur l'accueil comme au catalogue. Elle n'a aucun état
 * ici depuis le lot 2 : le comparateur mesure des faits au repos, et personne ne
 * survolait. La règle du catalogue vient après et coupe l'ombre : sa variante
 * survolée doit donc être écrite ici, après elle.
 */
.wp-block-woocommerce-product-template > li:hover,
.flouncy-catalogue .wp-block-woocommerce-product-template > li:hover {
	box-shadow: var(--wp--custom--shadow--md);
}

/* Prix et bouton alignés d'une carte à l'autre, quelle que soit la longueur du titre. */
.flouncy-catalogue .wc-block-product > .wp-block-group {
	margin-block-start: auto;
	padding-block-start: var(--wp--preset--spacing--14);
}

/*
 * Recherche : la maquette pose une pilule beige comme CONTENEUR, avec un bouton
 * transparent à l'intérieur — et non l'inverse. Le conteneur se déploie au clic,
 * le bouton garde sa taille.
 */
.flouncy-search .wp-block-search__inside-wrapper {
	/* Le retrait de 4 px est DANS les 40 px, comme dans la maquette. En
	   `content-box` il s'y ajoutait : la pilule sortait à 44 px de large et la
	   loupe se retrouvait à 2 px du centre. */
	box-sizing: border-box;
	gap: var(--wp--preset--spacing--8);
	align-items: center;
	height: var(--wp--custom--search--height);
	width: var(--wp--custom--search--width);
	padding: 0 0 0 4px;
	border: 0;
	border-radius: var(--wp--custom--radius--pill);
	background: var(--wp--preset--color--base);
	overflow: hidden;
	transition: width 0.25s;
}

/*
 * Le déploiement de la pilule est la seule transition du site. La maquette
 * l'écrit `width 0.25s` — une largeur, que le skill `motion` proscrit au profit
 * de `transform`/`opacity`. L'exception est assumée : une pilule qui s'ouvre en
 * `transform` étirerait la loupe et le texte qu'elle contient. La durée reste
 * sous les 300 ms, et le mouvement se coupe pour qui le demande.
 */
@media (prefers-reduced-motion: reduce) {

	.flouncy-search .wp-block-search__inside-wrapper {
		transition: none;
	}
}

/*
 * Le cœur rend le CHAMP avant le BOUTON ; la maquette pose la loupe à gauche et
 * le champ à sa droite. C'est l'ordre visuel qu'on inverse, pas l'ordre du DOM :
 * le focus doit continuer d'atteindre le bouton après le champ.
 */
.flouncy-search .wp-block-search__inside-wrapper {
	flex-direction: row-reverse;
	justify-content: flex-end;
}

/* Replié : la pilule est un rond de la taille du bouton. Les 4 px de retrait
   autour de la loupe font partie de la cible — sans cette ligne, le bord du rond
   rendait la flèche par défaut alors que tout le rond a l'air cliquable. */
.flouncy-search.wp-block-search__searchfield-hidden .wp-block-search__inside-wrapper {
	width: var(--wp--custom--search--height);
	cursor: pointer;
}

/*
 * Le champ ne porte NI fond, NI bordure, NI rayon : la pilule est le conteneur.
 * Sans cela, l'anneau de focus du navigateur dessinait une seconde pilule bleue
 * à l'intérieur de la première, et le champ dépassait la pilule d'un pixel.
 */
.flouncy-search .wp-block-search__input:focus {
	outline: 0;
}

/* Le retour de focus appartient donc à la pilule, pas au champ. */
.flouncy-search .wp-block-search__inside-wrapper:focus-within {
	outline: 2px solid var(--wp--preset--color--plum);
	outline-offset: 2px;
}

/*
 * Le bouton CENTRE sa loupe. Sans `flex`, le SVG se pose sur la ligne de base du
 * bouton : il sortait collé en haut des 32 px, et l'icône paraissait décalée
 * dans la pilule. La maquette pose `display:flex; align-items:center;
 * justify-content:center` sur ce même bouton.
 */
.flouncy-search .wp-block-search__button {
	display: flex;
	align-items: center;
	justify-content: center;
	width: var(--wp--custom--search--button);
	height: var(--wp--custom--search--button);
	min-width: var(--wp--custom--search--button);
	padding: 0;
	border: 0;
	border-radius: var(--wp--custom--radius--pill);
	background: transparent;
	color: var(--wp--preset--color--plum);
}

.flouncy-search .wp-block-search__button:hover,
.flouncy-search .wp-block-search__button:focus-visible {
	background: var(--wp--preset--color--pink-light);
}

/* La classe est reprise pour passer devant la règle du cœur, qui pose 24px
   à spécificité égale et se charge après — aucun !important n'est nécessaire. */
.flouncy-search .wp-block-search__button svg.search-icon {
	width: var(--wp--custom--search--icon);
	height: var(--wp--custom--search--icon);
	min-width: var(--wp--custom--search--icon);
	min-height: var(--wp--custom--search--icon);

	/* La loupe de la maquette est TRACÉE, pas remplie : `Site\Search` échange le
	   SVG du cœur, et le remplissage doit suivre — sinon le cercle se bouche. */
	fill: none;
	stroke: currentcolor;
}

.flouncy-search .wp-block-search__input {
	min-width: 0;
	height: auto;
	border: 0;
	border-radius: 0;
	background: transparent;
	padding-inline: 0;
	font-size: var(--wp--preset--font-size--x-small);
	color: var(--wp--custom--color--secondary);
}

.flouncy-search .wp-block-search__input::placeholder {
	color: var(--wp--custom--color--muted);
	opacity: 1;
}

/* Page courante dans la navigation : un soulignement, pas seulement une couleur. */
.flouncy-header__nav .wp-block-navigation-item.current-menu-item a,
.flouncy-header__nav .wp-block-navigation-item a[aria-current='page'] {
	border-bottom: 2px solid var(--wp--preset--color--pink);
}

/*
 * Survol du menu : la maquette assombrit le prune et ne souligne jamais. Le
 * soulignement de `elements.link` est bon pour un lien de prose, faux ici — il
 * dessine une deuxième barre sous celle qui marque la page courante, à deux
 * pixels de distance. Le prune que la maquette réservait à son survol est devenu
 * notre couleur de base à l'ADR 0004 : `plum-strong` reprend l'écart d'un cran.
 */
.flouncy-header__nav .wp-block-navigation-item a:hover,
.flouncy-header__nav .wp-block-navigation-item a:focus-visible {
	color: var(--wp--custom--color--plum-strong);
	text-decoration: none;
}

/*
 * La colonne de gauche est bornée : dans la maquette le paragraphe tient sur
 * trois lignes courtes, pas sur toute la largeur de la carte.
 */
.flouncy-gift-card__text {
	flex: 1 1 var(--wp--custom--gift--col-width);
	max-width: var(--wp--custom--gift--col-width);
}

.flouncy-gift-card__text > p {
	max-width: var(--wp--custom--gift--text-width);
	margin: 0;
}

/*
 * Carte produit : la maquette lui donne un fond crème, un rayon de 28 px, et
 * resserre son pied à 16/18. Les trois valeurs manquaient — les cartes sortaient
 * sur le fond de la section, sans limite visible.
 */
:not(.flouncy-cross-sell__grille) > .wp-block-woocommerce-product-template > li.wc-block-product {
	border-radius: var(--wp--custom--radius--lg);
	background: var(--wp--preset--color--base);
	overflow: hidden;
}

:not(.flouncy-cross-sell__grille) > .wp-block-woocommerce-product-template > li.wc-block-product > :not(.wc-block-components-product-image):not(.flouncy-stock-badge) {
	padding-inline: var(--wp--custom--product--pad-x);
}

:not(.flouncy-cross-sell__grille) > .wp-block-woocommerce-product-template > li.wc-block-product > :last-child {
	padding-bottom: var(--wp--custom--product--pad-bottom);
}

:not(.flouncy-cross-sell__grille) > .wp-block-woocommerce-product-template > li.wc-block-product {
	gap: var(--wp--custom--product--body-gap);
}

/* Zone photo des cartes produit : proportion fixe, pour que la grille tienne
   même quand les photos manquent encore. */
.wp-block-woocommerce-product-template .wc-block-components-product-image {
	aspect-ratio: 4 / 5;
	overflow: hidden;
	background: var(--wp--preset--color--surface);
}

/*
 * WooCommerce enveloppe la photo dans un lien, et pose `aspect-ratio: 1/1` en
 * style en ligne sur l'image. Le `height: 100%` ci-dessous se résolvait donc
 * contre un lien de hauteur automatique, et l'image restait carrée dans une zone
 * au format 4/5 : une bande blanche de 73 px sous chaque photo du catalogue,
 * mesurée le 19/09. Le lien doit remplir la zone pour que l'image le puisse.
 */
.wp-block-woocommerce-product-template .wc-block-components-product-image > a {
	display: block;
	height: 100%;
}

.wp-block-woocommerce-product-template .wc-block-components-product-image img {
	width: 100%;
	height: 100%;
	object-fit: cover;
}

/*
 * En-tête, contenu et pied se touchent : les bandeaux pleine largeur et leurs
 * vagues n'ont de sens que jointifs. L'espacement de bloc reste actif partout
 * ailleurs — c'est seulement la racine du site qui n'en veut pas.
 */
.wp-site-blocks > * + * {
	margin-block-start: 0;
}

/*
 * Pied de page collé au bas de la fenêtre sur une page courte. Sans cela, le
 * suivi de commande laissait 327 px de crème sous un pied blanc, et la FAQ 96 —
 * mesuré le 19/09. Le contenu prend la place restante, le pied ne la prend pas.
 */
.wp-site-blocks {
	display: flex;
	flex-direction: column;
	min-height: 100vh;
}

/* Ce qui n'est ni l'en-tête ni le pied grandit — et non « le `main` » : WooCommerce
   enveloppe le gabarit de la fiche produit, si bien que le `main` n'y est plus un
   enfant direct. Le comparateur l'a dit dès que le fait a existé. */
.wp-site-blocks > :not(header):not(footer) {
	display: flex;
	flex: 1 0 auto;
	flex-direction: column;
}

/*
 * Conséquence de la colonne flex ci-dessus, et du passage de `contentSize` à 100 %
 * (la maquette n'a pas de colonne centrée, elle a 46 px de gouttière).
 *
 * WordPress donne `max-width: contentSize` ET des marges automatiques aux enfants
 * d'un conteneur contraint. À 100 %, ces marges ne centrent plus rien — mais elles
 * suffisent à désactiver l'étirement du flex, et l'enfant se réduit alors à son
 * contenu : le titre de la boutique sortait à 720 px de large, centré à 360 px de
 * la gauche, au lieu de la pleine colonne de 1348. Mesuré le 19/09.
 *
 * Les blocs `alignfull` sont exclus : leur largeur vient de marges négatives, et
 * leur imposer 100 % les ferait déborder.
 */
.wp-site-blocks > :not(header):not(footer).is-layout-constrained > :not(.alignfull) {
	width: 100%;
}

/*
 * Et la place gagnée revient à la section, pas à la fin du `main` : posée en bout,
 * elle décollait la vague de clôture du pied de 96 px sur la FAQ — une bande crème
 * entre une vague et le pied qu'elle est censée toucher. La vague garde donc sa
 * hauteur, la section prend le reste.
 */
.wp-site-blocks > :not(header):not(footer) > :not(.flouncy-wave) {
	flex: 1 0 auto;
}


/*
 * Fiche produit.
 *
 * Valeurs relevées dans le navigateur sur la maquette (docs/maquette.md, § du 17/09),
 * sélecteurs relevés dans le DOM rendu. Rien n'est supposé : la feuille de WooCommerce
 * cible ses propres classes, on s'aligne sur sa spécificité sans !important (ADR 0001).
 */

/* Galerie : vignettes en colonne à gauche, image principale au reste de la place.
   Les règles de proportion de WooCommerce ne couvrent pas le 4/5 de la maquette :
   on pose la géométrie nous-mêmes plutôt que de tordre un ratio approchant. */
.flouncy-galerie {
	gap: var(--wp--custom--gallery--gap);
}

.flouncy-galerie .wc-block-product-gallery-thumbnails__scrollable {
	gap: var(--wp--preset--spacing--14);
}

/*
 * Exception assumée à « aucune media query pour la mise en page » (CLAUDE.md §9),
 * et la seule du projet. WooCommerce calcule lui-même la largeur des vignettes à
 * partir de `thumbnailSize`, mais uniquement pour une liste fermée de proportions
 * d'image : auto, 4/3, 3/4, 3/2, 2/3, 16/9. La maquette est en 4/5, absent de la
 * liste, donc sa règle ne s'applique jamais et les vignettes prennent 196 px.
 *
 * Le seuil est **celui de WooCommerce** (601 px), pas celui du thème : au-dessous, le
 * cœur met les vignettes sous l'image, et forcer leur largeur y laissait une seule
 * vignette visible à 390 px. En inventer un autre désynchroniserait les deux bascules.
 */
@media (min-width: 601px) {
	.flouncy-galerie:not(.is-vertical) .wc-block-product-gallery-thumbnails {
		/* `flex-shrink: 0` : sans lui la colonne se fait raboter à 64 px par l'image. */
		flex: 0 0 var(--wp--custom--gallery--thumb);
	}
}

.flouncy-galerie .wc-block-product-gallery-thumbnails__thumbnail {
	border: 1px solid var(--wp--custom--color--hairline);
	border-radius: var(--wp--custom--radius--md);
	overflow: hidden;
}

.flouncy-galerie .wc-block-product-gallery-large-image .wc-block-components-product-image {
	aspect-ratio: var(--wp--custom--gallery--ratio);
	border-radius: var(--wp--custom--radius--lg);
	overflow: hidden;
	background: var(--wp--preset--color--surface);
}

/* La note : la maquette met les étoiles en orange, reste du gabarit de canvas
   (ledger, décision du 16/09). On les passe au prune de la marque. */
.flouncy-note {
	display: flex;
	align-items: center;
	gap: var(--wp--preset--spacing--14);
}

.flouncy-note .wc-block-components-product-rating__stars,
.flouncy-note .wc-block-components-product-rating__stars span::before {
	color: var(--wp--preset--color--plum);
}

/* Le résumé garde une mesure lisible : 38ch, soit les 457 px mesurés. */
.flouncy-fiche__resume {
	max-width: var(--wp--custom--measure--summary);
	color: var(--wp--custom--color--body);
}

.flouncy-fiche__resume strong {
	color: var(--wp--custom--color--secondary);
}

/* Nuanciers : pastilles natives de WooCommerce, ramenées aux dimensions de la
   maquette. L'anneau rose marque la sélection ; il ne remplace pas `aria-checked`,
   que le cœur pose déjà — la couleur n'est jamais le seul signal. */
.flouncy-nuanciers .wc-block-product-filter-chips__items {
	gap: var(--wp--preset--spacing--14);
}

.flouncy-nuanciers .wc-block-product-filter-chips__item {
	width: var(--wp--custom--swatch--size);
	height: var(--wp--custom--swatch--size);
	padding: var(--wp--preset--spacing--4);
	border: var(--wp--custom--swatch--ring) solid transparent;
	border-radius: var(--wp--custom--radius--pill);
	background: none;
}

.flouncy-nuanciers .wc-block-product-filter-chips__item[aria-checked='true'] {
	border-color: var(--wp--preset--color--pink);
}

/* Le choix du tissu est la commande principale de la fiche, et elle ne répondait
   pas au survol : l'anneau reste transparent tant que la pastille n'est pas
   choisie, donc rien ne bougeait sous la souris. Un filet neutre, et non du rose :
   le rose plein marque la sélection, le prune marque le focus, et un survol ne
   doit se confondre avec ni l'un ni l'autre. Le rose clair, lui, ne donnait que
   1,25:1 sur le fond de page — un anneau qu'il fallait deviner. La règle de la
   pastille choisie, plus spécifique, continue de l'emporter. */
.flouncy-nuanciers .wc-block-product-filter-chips__item:hover {
	border-color: var(--wp--custom--color--hairline-strong);
}

.flouncy-nuanciers .wc-block-product-filter-chips__swatch {
	width: var(--wp--custom--swatch--dot);
	height: var(--wp--custom--swatch--dot);
	border-radius: var(--wp--custom--radius--pill);
	background-size: cover;
}

/* WooCommerce éteint le contour de ses pastilles et des boutons de quantité : au
   clavier, rien ne montrait où l'on se trouvait. Le prune décalé se distingue de
   l'anneau rose de sélection — focus et état choisi ne doivent pas se confondre.
   Le second sélecteur reprend la classe du conteneur pour dépasser d'un cran la
   spécificité de WooCommerce, sans !important (ADR 0001). */
.flouncy-nuanciers .wc-block-product-filter-chips__item:focus-visible,
.flouncy-achat .wc-block-components-quantity-selector .wc-block-components-quantity-selector__button:focus-visible {
	outline: 2px solid var(--wp--preset--color--plum);
	outline-offset: 2px;
}

/* Le nom du tissu vit dans la pastille, pour le lecteur d'écran et pour le titre
   au survol. Seul celui de la pastille choisie s'affiche, sous la rangée. */
.flouncy-nuanciers .wc-block-product-filter-chips__text {
	position: absolute;
	clip-path: inset(50%);
	width: 1px;
	height: 1px;
	overflow: hidden;
}

/* Quantité et ajout au panier partagent une ligne (mise en page flex du groupe) :
   la pilule de quantité garde sa largeur, le bouton prend le reste. */
.flouncy-achat .wc-block-components-quantity-selector {
	gap: var(--wp--preset--spacing--14);
	padding: var(--wp--preset--spacing--8) var(--wp--preset--spacing--18);
	border: 1px solid var(--wp--custom--color--hairline);
	border-radius: var(--wp--custom--radius--pill);
	background: none;
}

/* Les deux boutons et le chiffre du sélecteur de quantité : les mêmes sur la
   fiche et dans le panier. */
:is(.flouncy-achat, .flouncy-panier) .wc-block-components-quantity-selector__button {
	height: auto;
	min-height: 0;
	padding: 0 var(--wp--preset--spacing--8);
	border: 0;
	background: none;
	color: var(--wp--preset--color--plum);
	font-size: var(--wp--preset--font-size--medium-large);
	line-height: 1.2;
}

:is(.flouncy-achat, .flouncy-panier) .wc-block-components-quantity-selector__input {
	width: 3ch;
	height: auto;
	min-height: 0;
	padding: 0;
	border: 0;
	background: none;
	font-weight: 700;
	line-height: 1.2;
}

.flouncy-achat .wc-block-components-product-button {
	flex: 1 1 auto;
}

/*
 * Le bouton d'achat de la fiche est plus grand que celui des cartes : 16 px,
 * 15 × 24 de retrait et le `border: 1px solid transparent` du `.btn` de la
 * maquette, soit 51 px de haut — on en mesurait 45,7 (26/09). `.flouncy-fiche`
 * passe devant WooCommerce, qui écrit `border-style: none` à spécificité égale.
 */
.flouncy-fiche .flouncy-achat .wc-block-components-product-button .wp-block-button__link {
	padding: var(--wp--custom--button--buy-pad-y) var(--wp--preset--spacing--24);
	border: 1px solid transparent;
	font-size: var(--wp--preset--font-size--medium);
	line-height: 1.2;
}

/*
 * Le bouton d'achat de la maquette : rose poudré, texte prune sombre, Caprasimo.
 * Le lot 4 l'avait réservé à la fiche, en supposant « deux rôles distincts » — la
 * mesure dit l'inverse : la maquette le pose aussi sur les cartes de l'accueil et
 * du catalogue — le rose de la palette, texte prune sombre, 8/14 de retrait. Notre
 * catalogue était le seul écran à le rendre prune plein. Relevé le 19/09.
 * Le bouton global du thème, lui, reste prune : il n'ajoute pas au panier.
 */
.flouncy-fiche .wc-block-components-product-button .wp-block-button__link {
	width: 100%;
	background: var(--wp--preset--color--pink);
	color: var(--wp--custom--color--on-pink);
}

.wp-block-woocommerce-product-template > li .wc-block-components-product-button .wp-block-button__link {
	padding: var(--wp--preset--spacing--8) var(--wp--preset--spacing--14);
	background: var(--wp--preset--color--pink);
	color: var(--wp--custom--color--on-pink);
}

.flouncy-fiche .wc-block-components-product-button .wp-block-button__link:hover,
.flouncy-fiche .wc-block-components-product-button .wp-block-button__link:focus-visible,
.wp-block-woocommerce-product-template > li .wc-block-components-product-button .wp-block-button__link:hover,
.wp-block-woocommerce-product-template > li .wc-block-components-product-button .wp-block-button__link:focus-visible {
	background: var(--wp--preset--color--pink-light);
	color: var(--wp--custom--color--on-pink);
}

/*
 * Accordéons de la fiche et de la FAQ : la question porte la police d'affichage,
 * le marqueur natif est masqué — la maquette n'affiche pas de triangle. Sur
 * <details>, la police descendrait aussi sur la réponse : elle appartient à la
 * question (défaut du lot 4, trouvé par le comparateur au lot 6).
 */
:is(.flouncy-accordeons, .flouncy-faq) .wp-block-details > summary {
	list-style: none;
	font-family: var(--wp--preset--font-family--display);
	cursor: pointer;
}

:is(.flouncy-accordeons, .flouncy-faq) .wp-block-details > summary::marker,
:is(.flouncy-accordeons, .flouncy-faq) .wp-block-details > summary::-webkit-details-marker {
	display: none;
	content: '';
}

/* Fiche : filet haut sur chacun, filet bas sur le dernier. */
.flouncy-accordeons .wp-block-details {
	padding: var(--wp--preset--spacing--18) 0;
	border-top: 1px solid var(--wp--custom--color--hairline);
}

.flouncy-accordeons .wp-block-details:last-child {
	border-bottom: 1px solid var(--wp--custom--color--hairline);
}

/* Une question est une commande : sans retour au survol, rien ne dit qu'elle
   s'ouvre. La maquette n'en définit aucun — un accordéon muet reste un défaut. */
.flouncy-accordeons .wp-block-details > summary:hover {
	color: var(--wp--preset--color--plum);
}

/* Cartes d'avis dans l'accordéon. */
.flouncy-avis__carte {
	padding: var(--wp--preset--spacing--18) var(--wp--preset--spacing--18);
	border-radius: var(--wp--custom--radius--md);
	background: var(--wp--custom--color--card);
}

.flouncy-avis .wp-block-woocommerce-product-review-rating {
	color: var(--wp--preset--color--plum);
}

/* Cross-sell : la carte est horizontale — photo à gauche, texte à droite.
   Retrait 14 px et gouttière 16 px : relevés sur la maquette, qui pose
   `padding: 14px; gap: 16px` autour d'une photo de 88 × 110. La carte fait
   alors 138 px de haut, ce que le comparateur vérifie. */
.flouncy-cross-sell__grille .wp-block-woocommerce-product-template > li {
	display: flex;
	flex-direction: row;
	gap: var(--wp--preset--spacing--16);
	align-items: flex-start;
	padding: var(--wp--preset--spacing--14);
	border: 0;
	border-radius: var(--wp--custom--radius--lg);
	background: var(--wp--custom--color--card);
}

/* La carte de grille verticale pose une marge sous la photo et un retrait
   intérieur sur ses enfants : la carte horizontale n'en veut ni l'un ni l'autre. */
.flouncy-cross-sell__grille .wp-block-woocommerce-product-template > li > * {
	padding-inline: 0;
}

.flouncy-cross-sell__grille .wp-block-woocommerce-product-template > li .wc-block-components-product-image {
	margin: 0;
	flex: 0 0 88px;
	aspect-ratio: var(--wp--custom--gallery--ratio);
	border-radius: var(--wp--custom--radius--md);
	overflow: hidden;
}

/* Le titre de carte est en encre dans la maquette ; le lien qu'il contient
   hériterait sinon du prune des liens. */
.flouncy-cross-sell__grille .wp-block-post-title a {
	color: inherit;
}

.flouncy-cross-sell__grille .wp-block-woocommerce-product-template > li > .wp-block-group {
	flex: 1 1 auto;
	align-items: flex-start;
}

.flouncy-cross-sell__grille .wc-block-components-product-button {
	margin-top: var(--wp--preset--spacing--8);
}

.flouncy-cross-sell__grille .wc-block-components-product-button .wp-block-button__link {
	width: auto;
	padding: var(--wp--preset--spacing--8) var(--wp--preset--spacing--14);
}

/*
 * Panier.
 *
 * Valeurs relevées dans le navigateur sur la maquette (docs/maquette.md, § Panier) ;
 * sélecteurs ET spécificités relevés dans la feuille servie par WooCommerce, pas
 * supposés. Quatre choses qu'il a fallu constater avant d'écrire une ligne :
 *
 * 1. WooCommerce pose `background: none !important` sur chaque cellule. Le fond de
 *    carte va donc sur la RANGÉE, que rien ne verrouille — et les cellules laissent
 *    voir à travers.
 * 2. Sa mise en page de ligne existe en deux versions : une grille compacte sous
 *    `@container (max-width: 699px)`, une vraie ligne de tableau au-dessus.
 * 3. **La géométrie de bureau doit donc vivre dans la requête de conteneur de
 *    WooCommerce**, sinon elle écrase aussi sa version compacte : au premier jet, le
 *    titre de pièce sortait à une lettre par ligne sur un téléphone. Le seuil est le
 *    sien (700 px), jamais un seuil inventé — même raison qu'à la galerie produit.
 * 4. Ses règles de ligne pèsent (0,3,1). Les nôtres montent à (0,4,1) en reprenant sa
 *    propre chaîne de sélecteurs — jamais un !important (ADR 0001).
 */

/* WooCommerce plafonne le titre des pages panier, commande et compte à 1000 px.
   La maquette lui donne toute la colonne. */
.woocommerce-cart .flouncy-panier .wp-block-post-title {
	max-width: none;
}

/* Les lignes sont des cartes détachées : `separate` est la seule façon d'espacer des
   rangées sans casser la sémantique de tableau dont le lecteur d'écran a besoin. */
.flouncy-panier .wc-block-cart-items {
	border-collapse: separate;
	border-spacing: 0 var(--wp--preset--spacing--14);
}

/* L'en-tête « Produit / Total » n'existe pas dans la maquette. Masquer n'est pas
   supprimer : il reste lu par les technologies d'assistance. */
.flouncy-panier .wc-block-cart-items thead {
	position: absolute;
	width: 1px;
	height: 1px;
	overflow: hidden;
	clip-path: inset(50%);
}

/* Le filet de séparation de WooCommerce n'a plus lieu d'être entre deux cartes
   détachées. Sa règle pèse (0,5,1) : on reprend sa chaîne, `:not()` compris, et la
   classe de page fait la différence — toujours sans !important. */
.flouncy-panier .wc-block-cart table.wc-block-cart-items:not(.wc-block-mini-cart-items):not(:last-child) .wc-block-cart-items__row,
.flouncy-panier .wc-block-cart-items__row {
	border-bottom: 0;
	border-radius: var(--wp--custom--radius--lg);
	background: var(--wp--custom--color--card);
}

.flouncy-panier .wc-block-cart-item__image img {
	max-width: 100%;
	aspect-ratio: var(--wp--custom--gallery--ratio);
	border-radius: var(--wp--custom--radius--md);
	object-fit: cover;
}

.flouncy-panier table.wc-block-cart-items .wc-block-cart-items__row .wc-block-components-product-name {
	color: var(--wp--preset--color--plum);
	font-family: var(--wp--preset--font-family--display);
	font-size: var(--wp--preset--font-size--large);
	font-weight: 400;
	text-decoration: none;
}

/*
 * La maquette n'affiche qu'un prix par ligne, celui de droite, et un récit de pièce
 * n'a rien à faire dans un panier. Le prix unitaire manque donc dès qu'une quantité
 * dépasse 1 — écart assumé, noté dans docs/maquette.md, à retrancher d'une ligne.
 */
.flouncy-panier table.wc-block-cart-items .wc-block-cart-items__row .wc-block-cart-item__prices,
.flouncy-panier .wc-block-components-product-metadata .wc-block-components-product-metadata__description {
	display: none;
}

/* Le tissu choisi, lui, reste : c'est ce qui distingue deux lignes identiques. */
.flouncy-panier .wc-block-components-product-metadata .wc-block-components-product-details {
	margin: 0;
	padding: 0;
	color: var(--wp--custom--color--muted);
	list-style: none;
}

.flouncy-panier .wc-block-components-quantity-selector {
	gap: var(--wp--preset--spacing--14);
	width: auto;
	min-width: 0;
	padding: var(--wp--preset--spacing--8) var(--wp--preset--spacing--18);
	border: 1px solid var(--wp--custom--color--hairline);
	border-radius: var(--wp--custom--radius--pill);
	background: var(--wp--preset--color--base);
}

.flouncy-panier .wc-block-cart-item__remove-link {
	font-size: var(--wp--preset--font-size--x-small);

	/* Un `<button>` n'hérite pas du curseur d'un lien : celui-ci ressemblait à un
	   lien, soulignement compris, et pointait la flèche par défaut. */
	cursor: pointer;
}

/*
 * La couleur du retrait était écrite depuis le lot 5a, mais WooCommerce la
 * reposait plus spécifiquement : le lien est resté encre pendant trois lots. Et
 * il perdait son soulignement au survol, l'inverse de ce qu'un lien fait.
 * Spécificité alignée sur celle de WooCommerce, sans !important (ADR 0001).
 */
.flouncy-panier table.wc-block-cart-items .wc-block-cart-items__row .wc-block-cart-item__remove-link {
	color: var(--wp--preset--color--plum);
}

.flouncy-panier table.wc-block-cart-items .wc-block-cart-items__row .wc-block-cart-item__remove-link:hover {
	color: var(--wp--custom--color--plum-strong);
	text-decoration: underline;
}

/* WooCommerce éteint le contour de ses boutons : au clavier, plus rien ne montrait
   où l'on se trouvait dans le panier. */
.flouncy-panier .wc-block-components-quantity-selector__button:focus-visible,
.flouncy-panier .wc-block-cart-item__remove-link:focus-visible {
	outline: 2px solid var(--wp--preset--color--plum);
	outline-offset: 2px;
}

.flouncy-panier table.wc-block-cart-items .wc-block-cart-items__row .wc-block-cart-item__total {
	align-items: center;
	color: var(--wp--preset--color--olive-deep);
	font-family: var(--wp--preset--font-family--display);
	font-size: var(--wp--preset--font-size--large);
}

/* Encart carte cadeau : le pointillé rose de la maquette, et son jeton de filet. */
.flouncy-panier__cadeau {
	gap: var(--wp--preset--spacing--18);
	margin-top: var(--wp--preset--spacing--14);
	padding: var(--wp--preset--spacing--18) var(--wp--preset--spacing--26);
	border: var(--wp--custom--cart--dotted) dotted var(--wp--custom--color--hairline-pink);
	border-radius: var(--wp--custom--radius--lg);
}

.flouncy-panier__cadeau-texte {
	flex: 1 1 24ch;
	margin: 0;
}

/*
 * Vichy vert de la vignette : deux dégradés croisés, teintés à la palette. C'est du
 * décor — il n'a ni texte alternatif ni sens, et un aplat ne coûte aucune requête.
 */
.flouncy-panier__pastille {
	flex: 0 0 var(--wp--custom--cart--gift);
	height: var(--wp--custom--cart--gift);
	border-radius: var(--wp--custom--radius--pill);
	background-color: color-mix(in srgb, var(--wp--preset--color--olive) 18%, var(--wp--preset--color--surface));
	background-image:
		linear-gradient(90deg, color-mix(in srgb, var(--wp--preset--color--olive) 24%, transparent) 50%, transparent 50%),
		linear-gradient(color-mix(in srgb, var(--wp--preset--color--olive) 24%, transparent) 50%, transparent 50%);
	background-size: 14px 14px;
}

.flouncy-panier__cadeau-bouton .wp-block-button__link {
	background: var(--wp--preset--color--pink);
	color: var(--wp--custom--color--on-pink);
}

.flouncy-panier__cadeau-bouton .wp-block-button__link:hover,
.flouncy-panier__cadeau-bouton .wp-block-button__link:focus-visible {
	background: var(--wp--preset--color--pink-light);
	color: var(--wp--custom--color--on-pink);
}

/* Récapitulatif : un panneau, à toutes les largeurs. */
.flouncy-panier .wc-block-cart__sidebar {
	padding: var(--wp--preset--spacing--26);
	border-radius: var(--wp--custom--radius--lg);
	background: var(--wp--custom--color--card);
}

.flouncy-panier .wc-block-cart__totals-title {
	margin: 0 0 var(--wp--preset--spacing--18);
	padding: 0;
	color: var(--wp--preset--color--olive-deep);
	font-family: var(--wp--preset--font-family--display);
	font-size: var(--wp--preset--font-size--panel-title);
	font-weight: 400;
	letter-spacing: var(--wp--custom--tracking--tight);
	text-transform: none;
}

.flouncy-panier .wc-block-components-totals-wrapper {
	padding: 0;
	border: 0;
}

.flouncy-panier .wc-block-components-totals-item {
	padding: var(--wp--preset--spacing--4) 0;
	font-size: var(--wp--preset--font-size--small);
}

/* WooCommerce crie « GRATUIT » quand le port tombe à zéro. La maquette dit
   « offerte », sur le même ton que le reste de la page. */
.flouncy-panier .wc-block-components-totals-shipping .wc-block-components-totals-item strong {
	font-weight: 400;
	text-transform: none;
}

/* Le filet au-dessus du total, mesuré à 1 px d'encre à 16 %. */
.flouncy-panier .wc-block-cart .wc-block-components-totals-footer-item {
	margin-top: var(--wp--preset--spacing--14);
	padding-top: var(--wp--preset--spacing--14);
	border-top: 1px solid var(--wp--custom--color--hairline);
}

.flouncy-panier .wc-block-components-totals-footer-item .wc-block-components-totals-item__label,
.flouncy-panier .wc-block-components-totals-footer-item .wc-block-components-totals-item__value {
	color: var(--wp--preset--color--ink);
	font-family: var(--wp--preset--font-family--display);
	font-size: var(--wp--preset--font-size--panel-title);
	font-weight: 400;
}

.flouncy-panier .wc-block-cart .wc-block-cart__submit-container {
	padding: 0;
	margin-top: var(--wp--preset--spacing--26);
}

/* Le bouton de commande : rose poudré, texte prune sombre — du blanc sur ce rose
   tombe à 2,1:1, sous le seuil AA (décision du 17/09). */
.flouncy-panier .wc-block-cart__submit-button {
	width: 100%;
	padding: var(--wp--preset--spacing--18);
	border-radius: var(--wp--custom--radius--pill);
	background: var(--wp--preset--color--pink);
	color: var(--wp--custom--color--on-pink);
	font-family: var(--wp--preset--font-family--display);
	font-size: var(--wp--preset--font-size--medium);
	font-weight: 400;
}

.flouncy-panier .wc-block-cart__submit-button:hover,
.flouncy-panier .wc-block-cart__submit-button:focus-visible {
	background: var(--wp--preset--color--pink-light);
	color: var(--wp--custom--color--on-pink);
}

.flouncy-panier__mentions {
	margin-top: var(--wp--preset--spacing--14);
}

.flouncy-panier__mentions p {
	margin: 0;
	color: var(--wp--custom--color--muted);
}

/*
 * Géométrie de bureau. Enfermée dans LA requête de conteneur de WooCommerce — son
 * seuil, son conteneur (`.wp-block-woocommerce-cart` porte `container-type`). En
 * dessous, sa grille compacte reprend la main sans qu'on écrive une seule règle
 * mobile : c'est ce que demande CLAUDE.md §9, et c'est ce qui manquait au premier jet.
 */
@container (min-width: 700px) {
	/* Deux colonnes : 65,22 % / 34,78 % de la place restante une fois la gouttière
	   ôtée. Les jetons sont des nombres nus, pas des pourcentages : CSS ne sait pas
	   multiplier une longueur par un pourcentage, et le `calc` invalide retombait
	   silencieusement sur `auto` — la barre latérale passait sous les lignes. */
	.flouncy-panier .wc-block-components-sidebar-layout {
		gap: var(--wp--preset--spacing--36);
		align-items: flex-start;
	}

	.flouncy-panier .wc-block-components-sidebar-layout .wc-block-cart__main {
		flex: 0 1 calc(
			(100% - var(--wp--preset--spacing--36)) * var(--wp--custom--cart--main)
		);
		width: auto;
		padding: 0;
	}

	.flouncy-panier .wc-block-components-sidebar-layout .wc-block-cart__sidebar {
		flex: 0 1 calc(
			(100% - var(--wp--preset--spacing--36)) * var(--wp--custom--cart--aside)
		);
		width: auto;
	}

	.flouncy-panier .wc-block-cart__main .wc-block-cart-items td {
		padding: var(--wp--preset--spacing--18) 0;
		border: 0;
		vertical-align: middle;
	}

	.flouncy-panier .wc-block-cart__main .wc-block-cart-items td:first-child {
		padding-left: var(--wp--preset--spacing--26);
	}

	.flouncy-panier .wc-block-cart__main .wc-block-cart-items td:last-child {
		padding-right: var(--wp--preset--spacing--26);
	}

	.flouncy-panier .wc-block-cart__main .wc-block-cart-items .wc-block-cart-item__image {
		width: var(--wp--custom--cart--visual);
		padding-right: var(--wp--preset--spacing--26);
	}

	.flouncy-panier table.wc-block-cart-items .wc-block-cart-items__row .wc-block-cart-item__image img {
		width: var(--wp--custom--cart--visual);
	}

	/*
	 * La ligne de la maquette tient sur un rang : pièce et tissu à gauche, pilule de
	 * quantité à droite, « Retirer » sous le tissu. WooCommerce les empile.
	 * `display: contents` sur le bloc de quantité fait de ses deux enfants des cases
	 * de la grille : c'est ce qui permet de les séparer sans toucher à son balisage.
	 */
	.flouncy-panier table.wc-block-cart-items .wc-block-cart-items__row .wc-block-cart-item__wrap {
		display: grid;
		grid-template-columns: 1fr auto;
		gap: var(--wp--preset--spacing--4) var(--wp--preset--spacing--26);
		align-items: center;
	}

	.flouncy-panier table.wc-block-cart-items .wc-block-cart-items__row .wc-block-cart-item__quantity {
		display: contents;
	}

	.flouncy-panier table.wc-block-cart-items .wc-block-cart-items__row .wc-block-components-product-name,
	.flouncy-panier table.wc-block-cart-items .wc-block-cart-items__row .wc-block-components-product-metadata {
		grid-column: 1;
	}

	.flouncy-panier table.wc-block-cart-items .wc-block-cart-items__row .wc-block-components-quantity-selector {
		grid-row: 1 / -1;
		grid-column: 2;
	}

	.flouncy-panier table.wc-block-cart-items .wc-block-cart-items__row .wc-block-cart-item__quantity .wc-block-cart-item__remove-link {
		grid-column: 1;
		justify-self: start;
	}
}

/*
 * Rangée compacte, sous le seuil de WooCommerce. Sa grille suppose une pilule de
 * quantité de sa taille à lui ; la nôtre, reprise sur la maquette, est plus large et
 * poussait la ligne à 381 px dans 342 disponibles — le prix sortait de l'écran. On
 * ramène donc la rangée à deux colonnes, visuel puis tout le reste, et on empile.
 * La maquette ne montre pas de panier mobile : cette mise en page est une décision,
 * pas un relevé.
 */
@container (max-width: 699px) {
	.flouncy-panier .wc-block-cart table.wc-block-cart-items .wc-block-cart-items__row {
		grid-template-columns: var(--wp--custom--cart--visual) minmax(0, 1fr);
		padding: var(--wp--preset--spacing--18);
	}

	.flouncy-panier .wc-block-cart table.wc-block-cart-items .wc-block-cart-items__row > * {
		grid-column: 2;
		padding-right: 0;
	}

	.flouncy-panier .wc-block-cart table.wc-block-cart-items .wc-block-cart-items__row .wc-block-cart-item__image {
		grid-row: 1 / -1;
		grid-column: 1;
		padding-right: var(--wp--preset--spacing--18);
	}

	.flouncy-panier .wc-block-cart table.wc-block-cart-items .wc-block-cart-items__row .wc-block-cart-item__total {
		grid-row: 2;
		justify-content: flex-start;
	}
}

/*
 * Commande.
 *
 * Pas de relevé possible : la maquette n'a pas d'écran de commande. Ce qui suit est
 * donc une **décision**, prise pour que le tunnel ne dépayse pas — mêmes jetons, même
 * panneau que le récapitulatif du panier.
 *
 * Le thème ne reprend PAS `page-checkout.html` : l'en-tête minimal de WooCommerce est
 * conservé, c'est la décision 3 de l'ADR 0001 (commande sans distraction). Tout ce qui
 * suit passe donc par la feuille, à spécificité alignée sur la sienne, sans !important.
 * Les champs pèsent (0,3,1) chez elle : on scope par `.wc-block-checkout` pour monter
 * d'un cran plutôt que de compter sur l'ordre de chargement.
 */

.wc-block-checkout .wc-block-components-form .wc-block-components-text-input input[type='email'],
.wc-block-checkout .wc-block-components-form .wc-block-components-text-input input[type='text'],
.wc-block-checkout .wc-block-components-form .wc-block-components-text-input input[type='tel'],
.wc-block-checkout .wc-block-components-form .wc-block-components-text-input input[type='number'],
.wc-block-checkout .wc-blocks-components-select .wc-blocks-components-select__select {
	border: 1px solid var(--wp--custom--color--hairline);
	border-radius: var(--wp--custom--radius--md);
	color: var(--wp--preset--color--ink);
}

.wc-block-checkout .wc-block-components-form .wc-block-components-text-input input:focus,
.wc-block-checkout .wc-blocks-components-select .wc-blocks-components-select__select:focus {
	border-color: var(--wp--preset--color--plum);
	outline: 2px solid var(--wp--preset--color--plum);
	outline-offset: 1px;
}

.wc-block-checkout .wc-block-components-text-input label,
.wc-block-checkout .wc-blocks-components-select__label {
	color: var(--wp--custom--color--muted);
}

/* Les intitulés d'étape suivent la famille d'affichage du site plutôt que la police
   éditoriale : on est dans un formulaire, pas dans un récit. */
.wc-block-checkout .wc-block-components-checkout-step__title {
	color: var(--wp--preset--color--ink);
	font-family: var(--wp--preset--font-family--display);
	font-size: var(--wp--preset--font-size--large);
	font-weight: 400;
}

/* Le panneau de droite est le même objet que le récapitulatif du panier : même fond,
   même rayon. Une cliente qui passe de l'un à l'autre doit reconnaître la boîte. */
.wc-block-checkout .wp-block-woocommerce-checkout-order-summary-block {
	padding: var(--wp--preset--spacing--26);
	border: 0;
	border-radius: var(--wp--custom--radius--lg);
	background: var(--wp--custom--color--card);
}

.wc-block-checkout .wp-block-woocommerce-checkout-order-summary-block .wc-block-components-checkout-order-summary__title-text {
	color: var(--wp--preset--color--olive-deep);
	font-family: var(--wp--preset--font-family--display);
	font-size: var(--wp--preset--font-size--panel-title);
	font-weight: 400;
	letter-spacing: var(--wp--custom--tracking--tight);
}

/* Livraison et paiement : des cartes à choisir, pas des cases d'administration.
   L'anneau rose marque la sélection — il double `aria-checked`, il ne le remplace pas. */
.wc-block-checkout .wc-block-components-radio-control--highlight-checked .wc-block-components-radio-control-accordion-option,
.wc-block-checkout .wc-block-components-radio-control--highlight-checked label.wc-block-components-radio-control__option {
	border-radius: var(--wp--custom--radius--md);
	box-shadow: inset 0 0 0 1px var(--wp--custom--color--hairline);
}

.wc-block-checkout .wc-block-components-radio-control--highlight-checked .wc-block-components-radio-control-accordion-option--checked-option-highlighted,
.wc-block-checkout .wc-block-components-radio-control--highlight-checked label.wc-block-components-radio-control__option--checked-option-highlighted {
	box-shadow: inset 0 0 0 2px var(--wp--preset--color--pink);
}

/* L'en-tête sans distraction de WooCommerce affiche le nom du site en texte : au moins
   qu'il soit dans la voix de la marque. Le gabarit, lui, reste le sien (ADR 0001). */
.woocommerce-checkout header .wp-block-site-title a {
	color: var(--wp--preset--color--plum);
	font-family: var(--wp--preset--font-family--display);
	font-size: var(--wp--preset--font-size--medium-large);
	text-decoration: none;
}

/*
 * Confirmation de commande.
 *
 * Ici le gabarit de WooCommerce reprend l'en-tête et le pied du thème : la cliente
 * revient dans le site, et la page doit en porter la voix. Mêmes titres que le panier,
 * mêmes boîtes que le récapitulatif — rien de neuf, seulement de la cohérence.
 */
.woocommerce-order-received main h1 {
	color: var(--wp--preset--color--olive-deep);
	font-family: var(--wp--preset--font-family--display);
	font-size: var(--wp--preset--font-size--page-title);
	font-weight: 400;
	letter-spacing: var(--wp--custom--tracking--tight);
}

.woocommerce-order-received main h2 {
	color: var(--wp--preset--color--ink);
	font-family: var(--wp--preset--font-family--display);
	font-size: var(--wp--preset--font-size--large);
	font-weight: 400;
}

.woocommerce-order-received .wc-block-order-confirmation-totals__table,
.woocommerce-order-received .wc-block-order-confirmation-shipping-address address,
.woocommerce-order-received .wc-block-order-confirmation-billing-address address {
	border: 0;
	border-radius: var(--wp--custom--radius--lg);
	background: var(--wp--custom--color--card);
	font-style: normal;
}

.woocommerce-order-received .wc-block-order-confirmation-totals__table th,
.woocommerce-order-received .wc-block-order-confirmation-totals__table td {
	border-color: var(--wp--custom--color--hairline);
}


/*
 * Pages éditoriales — CGV, mentions légales, cookies, FAQ, L'atelier.
 *
 * Un seul squelette à deux colonnes pour les quatre premières ; seule la colonne
 * de droite change de nature (texte figé ou accordéon). L'atelier reprend la même
 * idée avec d'autres proportions. Les tailles de titre viennent des attributs de
 * bloc ; ne vivent ici que la géométrie de marque et ce que theme.json ne dit pas.
 */

/*
 * Caprasimo n'existe qu'en 400 : les graisses 500 de l'élément « heading » et
 * 600 du `h2` de theme.json y sont synthétisées, et la maquette ne les montre
 * nulle part. La règle générale couvre tout titre qui choisit la famille par sa
 * classe — le « Ça irait très bien ensemble » de la fiche sortait en faux gras.
 * Les titres ci-dessous la reçoivent de la feuille, d'où leur propre remise.
 */
:root :is(h1, h2, h3, h4, h5, h6).has-display-font-family {
	font-weight: 400;
}

.flouncy-editorial h1,
.flouncy-atelier h1,
.flouncy-contact h1,
.flouncy-suivi h1 {
	margin-block: 0 var(--wp--preset--spacing--14);
	font-weight: 400;
	letter-spacing: var(--wp--custom--tracking--tight);
}

.flouncy-editorial__aside p {
	margin-block: 0 var(--wp--preset--spacing--14);
	color: var(--wp--custom--color--secondary);
}

.flouncy-editorial__aside .wp-block-buttons {
	margin-block-start: var(--wp--preset--spacing--14);
}

/* Le bouton d'appel : rose clair, texte prune sombre. Le prune moyen de la maquette
   ne donne que 4,40:1 sur ce rose — sous le seuil AA pour du 13 px. Le prune sombre
   déjà retenu pour tout texte sur rose (17/09) donne 8,8:1. Valeurs dans
   docs/maquette.md ; ici, seuls des jetons. */
.flouncy-editorial__cta .wp-block-button__link {
	padding: var(--wp--preset--spacing--8) var(--wp--preset--spacing--18);
	background-color: var(--wp--preset--color--pink-light);
	color: var(--wp--custom--color--on-pink);
	font-size: var(--wp--preset--font-size--x-small);
	font-weight: 400;
}

.flouncy-editorial__cta .wp-block-button__link:hover,
.flouncy-editorial__cta .wp-block-button__link:focus-visible {
	background-color: var(--wp--preset--color--pink);
	color: var(--wp--custom--color--on-pink);
}

/* Les cartes de section : le fond `card` est celui du panier et du cross-sell. */
.flouncy-editorial__sections > * + * {
	margin-block-start: var(--wp--custom--editorial--card-gap);
}

.flouncy-editorial__card {
	padding: var(--wp--custom--editorial--card-pad);
	border-radius: var(--wp--custom--radius--lg);
	background: var(--wp--custom--color--card);
}

.flouncy-editorial__card h2 {
	margin-block: 0 var(--wp--preset--spacing--8);
	font-size: var(--wp--preset--font-size--medium-large);
	font-weight: 400;
	letter-spacing: normal;
	line-height: 1.55;
}

.flouncy-editorial__card p {
	margin-block: 0;
	color: var(--wp--custom--color--secondary);
	font-size: var(--wp--preset--font-size--small);
}

/* FAQ : même carte, en accordéon natif. */
.flouncy-faq > * + * {
	margin-block-start: var(--wp--custom--editorial--faq-gap);
}

.flouncy-faq .wp-block-details {
	padding: var(--wp--custom--editorial--faq-pad);
	border-radius: var(--wp--custom--radius--lg);
	background: var(--wp--custom--color--card);
}

.flouncy-faq .wp-block-details > summary {
	display: flex;
	justify-content: space-between;
	gap: var(--wp--preset--spacing--26);
	color: var(--wp--preset--color--plum);
	font-size: var(--wp--preset--font-size--medium-large);
	line-height: 1.55;
}

.flouncy-faq .wp-block-details > summary:hover {
	color: var(--wp--custom--color--plum-strong);
}

/*
 * Le marqueur. La maquette garde « + » une fois l'accordéon ouvert : le signe ne
 * dit alors plus rien de l'état. Il passe à « − ». Le `/ ''` laisse son texte de
 * remplacement vide — c'est de la décoration, l'état réel est déjà porté par
 * <details>, qu'un lecteur d'écran annonce tout seul.
 */
.flouncy-faq .wp-block-details > summary::after {
	content: '+' / '';
}

.flouncy-faq .wp-block-details[open] > summary::after {
	content: '−' / '';
}

/*
 * Réponse ouverte : 12 px sous la question, comme la maquette. Le paragraphe ne
 * remet à zéro que sa marge BASSE — `margin-block: 0`, de même spécificité et
 * écrit plus bas, annulait cet écart et collait la réponse à sa question.
 */
.flouncy-faq .wp-block-details > summary + * {
	margin-block-start: var(--wp--preset--spacing--12);
}

.flouncy-faq .wp-block-details p {
	margin-block-end: 0;
	color: var(--wp--custom--color--secondary);
	font-size: var(--wp--preset--font-size--small);
}

/* L'atelier — le récit. */
.flouncy-atelier h1 {
	margin-block-end: var(--wp--preset--spacing--18);
}

.flouncy-atelier__recit > p {
	margin-block: 0 var(--wp--preset--spacing--14);
}

.flouncy-atelier__valeurs {
	margin-block-start: var(--wp--preset--spacing--36);
}

.flouncy-atelier__valeurs .flouncy-valeur {
	padding: var(--wp--custom--editorial--value-pad);
	border: var(--wp--custom--cart--dotted) dotted var(--wp--custom--color--hairline-pink);
	border-radius: var(--wp--custom--radius--lg);
	background: var(--wp--custom--color--card);
}

/*
 * Le bouton de mercerie qui coiffe chaque valeur : un cercle percé de quatre trous.
 * Dessiné en masque plutôt qu'en SVG téléversé — un SVG téléversé est un document
 * exécutable, donc un vecteur XSS (§8.6). Un masque ne porte aucune couleur : la
 * teinte reste un jeton, et le décor suit la palette comme le ferait `currentColor`.
 */
.flouncy-valeur::before {
	content: '';
	display: block;
	width: var(--wp--custom--editorial--value-icon);
	height: var(--wp--custom--editorial--value-icon);
	margin: 0 auto var(--wp--preset--spacing--18);
	background: var(--wp--preset--color--pink);
	mask: url("data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2046%2046'%3E%3Cpath%20fill='white'%20fill-rule='evenodd'%20d='M23%202a21%2021%200%201%200%200%2042%2021%2021%200%201%200%200-42ZM18.5%2016.2a2.3%202.3%200%201%200%200%204.6%202.3%202.3%200%201%200%200-4.6ZM27.5%2016.2a2.3%202.3%200%201%200%200%204.6%202.3%202.3%200%201%200%200-4.6ZM18.5%2025.2a2.3%202.3%200%201%200%200%204.6%202.3%202.3%200%201%200%200-4.6ZM27.5%2025.2a2.3%202.3%200%201%200%200%204.6%202.3%202.3%200%201%200%200-4.6Z'/%3E%3C/svg%3E") center / contain no-repeat;
}

.flouncy-valeur h3 {
	margin-block: 0 var(--wp--preset--spacing--8);
	font-weight: 400;
	letter-spacing: normal;
	line-height: 1.55;
}

.flouncy-valeur p {
	margin-block: 0;
	color: var(--wp--custom--color--secondary);
}

/* L'atelier — les visuels. */
.flouncy-atelier__visuels > * + * {
	margin-block-start: var(--wp--custom--editorial--card-gap);
}

.flouncy-atelier__visuel.wp-block-image img {
	display: block;
	width: 100%;
	border-radius: var(--wp--custom--radius--lg);
}

.flouncy-atelier__visuels > .flouncy-atelier__visuel:first-child img {
	box-shadow: var(--wp--custom--shadow--sm);
}

/*
 * Contact et suivi de commande.
 *
 * Valeurs relevées dans le navigateur sur la maquette (docs/maquette.md, § du 18/09) ;
 * ici, seuls des jetons. Le chrome des champs, lui, vit dans le style des deux blocs :
 * il n'appartient pas au thème, il appartient aux formulaires.
 */

/* L'introduction est bornée : en pleine colonne elle tiendrait en deux lignes et la
   maquette en montre trois, ce qui pose le rythme de toute la page. */
.flouncy-contact__main > p {
	margin-block: 0 var(--wp--preset--spacing--14);
	max-width: var(--wp--custom--contact--intro-width);
	color: var(--wp--custom--color--secondary);
}

.flouncy-contact__aside > * + * {
	margin-block-start: var(--wp--custom--editorial--card-gap);
}

.flouncy-contact__card {
	padding: var(--wp--custom--contact--card-pad);
	border-radius: var(--wp--custom--radius--lg);
	background: var(--wp--custom--color--card);
}

/* Le second encart est posé sur le fond de page : seul un filet le détache. */
.flouncy-contact__card--contour {
	border: 1px solid var(--wp--custom--color--hairline);
	background: var(--wp--preset--color--base);
}

.flouncy-contact__card h2 {
	margin-block: 0 var(--wp--preset--spacing--8);
	font-size: var(--wp--preset--font-size--card-title);
	font-weight: 400;
	letter-spacing: normal;
	line-height: 1.55;
}

.flouncy-contact__card p {
	margin-block: 0;
	color: var(--wp--custom--color--secondary);
	font-size: var(--wp--preset--font-size--small);
}

.flouncy-suivi > p {
	margin-block: 0;
	color: var(--wp--custom--color--secondary);
}

/*
 * Les deux liens de la case d'acceptation — CGV et confidentialité.
 *
 * Ils vivent au milieu d'une phrase, en prune sur de l'encre : 2,23:1 entre les deux
 * textes, là où WCAG 1.4.1 en exige 3:1 dès lors que la couleur est le seul indice.
 * Le soulignement lève la condition sans toucher à la palette. Défaut apparu en
 * assombrissant le prune : la couleur du lien s'est rapprochée de celle du texte.
 */
.wc-block-checkout .wc-block-components-checkbox__label a {
	text-decoration: underline;
}
