/*
Theme Name: Cahier de jeux
Theme URI: https://www.cahierdejeux.fr
Author: Clément Quatravaux
Description: Thème sur mesure de cahierdejeux.fr. Monochrome intégral, une
             seule famille typographique, esthétique crayon sur papier. La
             hiérarchie ne vient que de la valeur, de la graisse et du blanc.
Version: 2.0.0
Requires at least: 6.5
Requires PHP: 8.1
Text Domain: cahierdejeux
Tags: e-commerce, custom-menu, translation-ready
*/

/* ═══════════════════════════════════════════════════════════════════════
   1 · POLICE

   Familjen Grotesk, variable de 400 à 700, auto-hébergée. Une seule
   ressource couvre les trois graisses employées : 400, 500 et 600.

   Servie depuis le site et non depuis fonts.gstatic.com : aucune adresse IP
   de visiteur ne part chez un tiers, et la police arrive sur la même
   connexion que le reste de la page.

   Pas de fichier italique. Le thème n'en emploie que pour les citations,
   assez rares pour que l'oblique synthétisée par le navigateur suffise :
   18 Ko de plus ne se justifient pas.
   ═══════════════════════════════════════════════════════════════════════ */

@font-face {
	font-family: "Familjen Grotesk";
	font-style: normal;
	font-weight: 400 700;
	font-display: swap;
	src: url("assets/polices/familjen-grotesk-latin.woff2") format("woff2");
	/* Latin de base : c'est le seul fichier que charge une page en français. */
	unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6,
	               U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F,
	               U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
	font-family: "Familjen Grotesk";
	font-style: normal;
	font-weight: 400 700;
	font-display: swap;
	src: url("assets/polices/familjen-grotesk-latin-ext.woff2") format("woff2");
	/* Latin étendu : téléchargé seulement si un caractère l'exige. */
	unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7,
	               U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF,
	               U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0,
	               U+2113, U+2C60-2C7F, U+A720-A7FF;
}

/* ═══════════════════════════════════════════════════════════════════════
   2 · JETONS

   Les noms sont ceux du système, à la lettre. Aucune couleur n'existe en
   dehors de cette liste : toute valeur écrite en dur ailleurs dans le
   fichier est une erreur.
   ═══════════════════════════════════════════════════════════════════════ */

:root {
	/* ── Valeurs ─────────────────────────────────────────────────────── */
	--papier: #FBF9F5;  /* fond général, texte sur fonds sombres. Ivoire.  */
	--9b:     #12110F;  /* titres, boutons pleins, prix, logo              */
	--6b:     #2E2C29;  /* survol des boutons pleins, états actifs         */
	--4b:     #504E4A;  /* texte courant                                   */
	--2b:     #6F6C67;  /* texte secondaire, libellés, méta, fil d'Ariane  */
	--hb:     #B4B0A9;  /* traits esquissés, cadres. JAMAIS de texte.      */
	--2h:     #E3DFD8;  /* filets droits, bordures d'inputs, fonds alternés */

	/* Seul écart coloré du système, et seulement pour une erreur de saisie. */
	--erreur: #8A2B1E;

	/* ── Typographie ─────────────────────────────────────────────────── */
	--police: "Familjen Grotesk", "Helvetica Neue", Arial, sans-serif;

	--display-t: 49px;  --display-i: 52px;  --display-l: -0.03em;
	--h1-t:      39px;  --h1-i:      44px;  --h1-l:      -0.02em;
	--h2-t:      31px;  --h2-i:      36px;  --h2-l:      -0.02em;
	--h3-t:      25px;  --h3-i:      30px;  --h3-l:      -0.01em;
	--h4-t:      20px;  --h4-i:      26px;  --h4-l:      0;
	--corps-t:   16px;  --corps-i:   26px;
	--petit-t:   13px;  --petit-i:   19px;
	--micro-t:   11px;  --micro-i:   16px;  --micro-l:   0.02em;

	/* ── Espacement, base 4 ──────────────────────────────────────────── */
	--e1:   4px;
	--e2:   8px;
	--e3:  12px;
	--e4:  16px;
	--e5:  24px;
	--e6:  32px;
	--e7:  48px;
	--e8:  64px;
	--e9:  96px;
	--e10: 128px;

	/* ── Grille ──────────────────────────────────────────────────────── */
	--conteneur: 1200px;
	--marge: 32px;
	--gouttiere: 24px;
	--entre-sections: 96px;

	/* La mesure de lecture : 70 signes au maximum, jamais davantage. */
	--mesure: 70ch;

	/* ── Mouvement ───────────────────────────────────────────────────── */
	--transition: 140ms ease-out;
	--transition-ouverture: 200ms ease-out;
}

/* ═══════════════════════════════════════════════════════════════════════
   3 · TRAITS DESSINÉS

   L'effet crayon ne vient pas d'un filtre posé sur la page : il vient de
   traits réellement dessinés, en nombre limité. Ils vivent ici sous forme
   de motifs répétables, ce qui évite d'alourdir le HTML d'un SVG par
   occurrence. Les tracés uniques (cadres, coches, flèches) sont produits en
   PHP par inc/dessins.php.

   Le dièse des couleurs est encodé %23 : c'est le seul caractère qu'une
   adresse de données ne tolère pas tel quel.
   ═══════════════════════════════════════════════════════════════════════ */

/*
   Ces motifs se répètent : leur tracé doit donc PARTIR DU BORD GAUCHE ET
   FINIR AU BORD DROIT, à la même hauteur. Un tracé qui s'arrête à 226 sur
   240 laisse quatorze pixels de vide entre chaque répétition, et le filet
   se lit alors comme une suite de petits traits séparés au lieu d'une
   ligne continue. Vérifié à l'écran : la première version avait ce défaut.
*/
:root {
	/* Filet de séparation. Période de 240px, amplitude d'un peu plus d'un
	   pixel : à l'œil, une ligne tirée à main levée qui hésite. */
	--trait-filet: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' width='240' height='9' viewBox='0 0 240 9'><path d='M0 5C30 3.4 58 6.6 88 5.1S146 3.2 176 4.9 218 6.2 240 5' fill='none' stroke='%23B4B0A9' stroke-width='1.4' stroke-linecap='round'/></svg>");

	/* Soulignement des liens. Période courte, pour qu'un mot seul en porte
	   déjà une ondulation complète. */
	--trait-souligne: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' width='64' height='6' viewBox='0 0 64 6'><path d='M0 3.5C10 2.2 22 4.8 32 3.4S54 2.2 64 3.5' fill='none' stroke='%23B4B0A9' stroke-width='1.4' stroke-linecap='round'/></svg>");

	/* Le même trait, en --4b : c'est l'état de survol des liens et des
	   boutons secondaires. Une adresse de données ne peut pas hériter de
	   currentColor, d'où ce doublon assumé. */
	--trait-souligne-fonce: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' width='64' height='6' viewBox='0 0 64 6'><path d='M0 3.5C10 2.2 22 4.8 32 3.4S54 2.2 64 3.5' fill='none' stroke='%23504E4A' stroke-width='1.4' stroke-linecap='round'/></svg>");

	/* Le même, en --papier : pied de page, où le fond est sombre. */
	--trait-souligne-clair: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' width='64' height='6' viewBox='0 0 64 6'><path d='M0 3.5C10 2.2 22 4.8 32 3.4S54 2.2 64 3.5' fill='none' stroke='%23FBF9F5' stroke-width='1.4' stroke-linecap='round'/></svg>");

	/* Le chevron du menu déroulant de tri, dessiné comme les autres. */
	--trait-chevron: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 16 16'><path d='M2.6 5.4C4.4 7.4 6.2 9.2 8.1 10.8 9.8 9 11.6 7.2 13.6 5.6' fill='none' stroke='%23B4B0A9' stroke-width='1.4' stroke-linecap='round' stroke-linejoin='round'/></svg>");

	/*
	   Les quatre traits d'un cadre esquissé.

	   Ce sont des motifs répétables et non un rectangle dessiné d'un bloc,
	   pour une raison de fond : un SVG unique doit être étiré à la taille de
	   l'image, et l'étirement déforme tout. Sur une couverture de 610px de
	   large, un cadre dessiné pour 300 unités voyait son ondulation doublée
	   et son inclinaison passer de deux à six pixels. Le même cadre était
	   juste sur une carte et de travers sur une fiche.

	   En motif répété, l'ondulation garde sa taille réelle quelle que soit
	   l'image : un trait de crayon ne s'épaissit pas parce que la feuille
	   est plus grande.
	*/
	--cadre-h: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' width='120' height='5' viewBox='0 0 120 5'><path d='M0 2.4C18 1.5 34 3.4 52 2.6S86 1.6 104 2.9 120 2.4 120 2.4' fill='none' stroke='%23B4B0A9' stroke-width='1.2' stroke-linecap='round'/></svg>");
	--cadre-v: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' width='5' height='120' viewBox='0 0 5 120'><path d='M2.6 0C1.7 18 3.6 34 2.8 52S1.8 86 3.1 104 2.6 120 2.6 120' fill='none' stroke='%23B4B0A9' stroke-width='1.2' stroke-linecap='round'/></svg>");

	/* Les mêmes en --4b : le survol d'une carte produit. */
	--cadre-h-fonce: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' width='120' height='5' viewBox='0 0 120 5'><path d='M0 2.4C18 1.5 34 3.4 52 2.6S86 1.6 104 2.9 120 2.4 120 2.4' fill='none' stroke='%23504E4A' stroke-width='1.2' stroke-linecap='round'/></svg>");
	--cadre-v-fonce: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' width='5' height='120' viewBox='0 0 5 120'><path d='M2.6 0C1.7 18 3.6 34 2.8 52S1.8 86 3.1 104 2.6 120 2.6 120' fill='none' stroke='%23504E4A' stroke-width='1.2' stroke-linecap='round'/></svg>");

	/* Grain du papier. feTurbulence en bruit fractal, trois octaves, posé en
	   produit sur le fond général et sur lui seul. */
	--grain: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' width='180' height='180'><filter id='g'><feTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='3' stitchTiles='stitch'/></filter><rect width='180' height='180' filter='url(%23g)'/></svg>");
}

/* ═══════════════════════════════════════════════════════════════════════
   4 · REMISE À ZÉRO
   ═══════════════════════════════════════════════════════════════════════ */

*,
*::before,
*::after {
	box-sizing: border-box;
	/* Rayon nul partout, sans exception. La règle est posée une fois ici
	   plutôt que composant par composant : c'est le seul moyen qu'elle tienne
	   quand WooCommerce ajoutera ses propres boutons. */
	border-radius: 0;
}

body,
h1, h2, h3, h4, h5, h6,
p, figure, blockquote,
dl, dd, ul, ol {
	margin: 0;
}

ul[class],
ol[class] {
	padding: 0;
	list-style: none;
}

img, picture, svg, video {
	display: block;
	max-width: 100%;
	height: auto;
}

input, button, textarea, select {
	font: inherit;
	color: inherit;
}

button {
	cursor: pointer;
	background: none;
	border: 0;
	padding: 0;
}

table {
	border-collapse: collapse;
	width: 100%;
}

/* Aucune ombre portée, aucun dégradé, nulle part. */
* {
	box-shadow: none;
	text-shadow: none;
}

/* ═══════════════════════════════════════════════════════════════════════
   5 · FONDATIONS
   ═══════════════════════════════════════════════════════════════════════ */

html {
	-webkit-text-size-adjust: 100%;
	scroll-behavior: smooth;
}

body {
	position: relative;
	background: var(--papier);
	color: var(--4b);
	font-family: var(--police);
	font-size: var(--corps-t);
	line-height: var(--corps-i);
	font-weight: 400;
	font-synthesis: none;
	-webkit-font-smoothing: antialiased;
	text-rendering: optimizeLegibility;
}

/* Le grain, en surimpression du fond général et de rien d'autre. Fixé au
   cadre de vue pour que le motif ne défile pas avec le contenu : un papier
   ne glisse pas sous ce qu'on écrit dessus. */
body::before {
	content: "";
	position: fixed;
	inset: 0;
	z-index: 1;
	background-image: var(--grain);
	opacity: 0.05;
	mix-blend-mode: multiply;
	pointer-events: none;
}

/* Tout le contenu passe au-dessus du grain. */
.site-entete,
.site-corps,
.site-pied {
	position: relative;
	z-index: 2;
}

/* ── Échelle typographique ───────────────────────────────────────────── */

.display,
.entete-accueil h1 {
	font-size: var(--display-t);
	line-height: var(--display-i);
	letter-spacing: var(--display-l);
	font-weight: 600;
	color: var(--9b);
}

h1, .h1 {
	font-size: var(--h1-t);
	line-height: var(--h1-i);
	letter-spacing: var(--h1-l);
	font-weight: 600;
	color: var(--9b);
}

h2, .h2 {
	font-size: var(--h2-t);
	line-height: var(--h2-i);
	letter-spacing: var(--h2-l);
	font-weight: 600;
	color: var(--9b);
}

h3, .h3 {
	font-size: var(--h3-t);
	line-height: var(--h3-i);
	letter-spacing: var(--h3-l);
	font-weight: 500;
	color: var(--9b);
}

h4, .h4 {
	font-size: var(--h4-t);
	line-height: var(--h4-i);
	letter-spacing: var(--h4-l);
	font-weight: 500;
	color: var(--9b);
}

h5, h6 {
	font-size: var(--corps-t);
	line-height: var(--corps-i);
	font-weight: 500;
	color: var(--9b);
}

.petit {
	font-size: var(--petit-t);
	line-height: var(--petit-i);
	font-weight: 400;
}

.micro {
	font-size: var(--micro-t);
	line-height: var(--micro-i);
	letter-spacing: var(--micro-l);
	font-weight: 500;
}

/* Le texte courant ne dépasse jamais la mesure. La règle vise le contenu
   rédigé, pas les conteneurs de mise en page. */
.page-contenu > p,
.article-contenu > p,
.introduction,
.produit-description > p {
	max-width: var(--mesure);
}

p + p {
	margin-top: var(--e4);
}

/* Titres : jamais de mot isolé mis en avant. Si un gras se glisse dans un
   titre malgré la règle éditoriale, il ne se voit pas. */
h1 strong, h2 strong, h3 strong, h4 strong,
h1 b, h2 b, h3 b, h4 b {
	font-weight: inherit;
}

/* Pas d'italique, hormis les citations. */
em, i {
	font-style: normal;
}

blockquote em,
blockquote i,
cite {
	font-style: italic;
}

blockquote {
	margin: var(--e6) 0;
	padding-left: var(--e5);
	border-left: 1px solid var(--2h);
	color: var(--2b);
	max-width: var(--mesure);
}

/* ── Liens ───────────────────────────────────────────────────────────── */

a {
	color: var(--9b);
	text-decoration: none;
}

/* Un lien dans du texte courant porte le trait ondulé : c'est le
   soulignement du système, et il remplace celui du navigateur. */
.page-contenu a:not([class]),
.article-contenu a:not([class]),
.produit-description a:not([class]),
.introduction a:not([class]) {
	background-image: var(--trait-souligne);
	background-repeat: repeat-x;
	background-position: 0 calc(100% + 4px);
	background-size: 64px 6px;
	padding-bottom: 5px;
	transition: background-image var(--transition);
}

.page-contenu a:not([class]):hover,
.article-contenu a:not([class]):hover,
.produit-description a:not([class]):hover,
.introduction a:not([class]):hover {
	background-image: var(--trait-souligne-fonce);
}

/* ── Accès ───────────────────────────────────────────────────────────── */

:focus-visible {
	outline: 2px solid var(--9b);
	outline-offset: 2px;
}

.evitement {
	position: absolute;
	left: -9999px;
}

.evitement:focus {
	position: fixed;
	top: var(--e2);
	left: var(--e2);
	z-index: 100;
	padding: var(--e3) var(--e4);
	background: var(--9b);
	color: var(--papier);
	font-size: var(--petit-t);
	font-weight: 500;
}

.lecture-ecran {
	position: absolute;
	width: 1px;
	height: 1px;
	overflow: hidden;
	clip-path: inset(50%);
	white-space: nowrap;
}

/* ═══════════════════════════════════════════════════════════════════════
   6 · STRUCTURE
   ═══════════════════════════════════════════════════════════════════════ */

.contenant {
	width: 100%;
	max-width: calc(var(--conteneur) + var(--marge) * 2);
	margin-inline: auto;
	padding-inline: var(--marge);
}

.site-corps {
	padding-block: var(--e7) var(--entre-sections);
	min-height: 60vh;
}

.section + .section {
	margin-top: var(--entre-sections);
}

/* Le filet dessiné, seul séparateur de section autorisé, et un seul par
   section. Il est décoratif : aria-hidden côté balisage. */
.filet {
	height: 9px;
	margin-block: var(--e7);
	background-image: var(--trait-filet);
	background-repeat: repeat-x;
	background-position: 0 50%;
	background-size: 240px 9px;
}

/* Filet droit, celui des séparations internes : accordéons, lignes de
   tableau, bordures. Le trait dessiné est réservé aux sections. */
.filet-droit {
	height: 1px;
	background: var(--2h);
	border: 0;
	margin-block: var(--e5);
}

/* ═══════════════════════════════════════════════════════════════════════
   7 · EN-TÊTE
   ═══════════════════════════════════════════════════════════════════════ */

.site-entete {
	background: var(--papier);
	border-bottom: 1px solid var(--2h);
}

.entete-interieur {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: var(--e6);
	height: 72px;
}

/* Le titre du site.

   Le système prévoyait un logo composé en texte, 22/600 en --9b. Le vrai
   logo l'a remplacé : même encre #12110F, même absence de couleur. Les
   valeurs typographiques restent ici, parce qu'elles servent de repli
   quand le fichier du logo manque. */
.site-titre {
	font-size: 22px;
	line-height: 1;
	font-weight: 600;
	letter-spacing: -0.02em;
	color: var(--9b);
	margin: 0;
}

.site-titre a {
	display: inline-flex;
	align-items: center;
	min-height: 44px;   /* cible tactile */
	color: inherit;
}

/* Le lockup fait 284 × 43, soit un rapport de 6,6 : sa hauteur suffit à le
   dimensionner. 26px dans une en-tête de 72px laisse le logo respirer sans
   qu'il domine la navigation. */
.site-logo {
	width: auto;
	height: 26px;
}

.navigation-principale {
	margin-inline-start: auto;
}

.menu-principal {
	display: flex;
	align-items: center;
	gap: var(--e5);
	margin: 0;
}

.menu-principal a {
	display: inline-flex;
	align-items: center;
	min-height: 44px;   /* cible tactile */
	font-size: 15px;
	font-weight: 400;
	color: var(--4b);
	transition: color var(--transition);
}

.menu-principal a:hover,
.menu-principal .current-menu-item > a {
	color: var(--9b);
}

/* ── Panier ──────────────────────────────────────────────────────────── */

.entete-panier {
	display: inline-flex;
	align-items: center;
	gap: var(--e2);
	min-height: 44px;
	min-width: 44px;
	color: var(--4b);
	transition: color var(--transition);
}

.entete-panier:hover {
	color: var(--9b);
}

.entete-panier svg {
	width: 22px;
	height: 22px;
}

.panier-compteur {
	display: inline-grid;
	place-items: center;
	width: 16px;
	height: 16px;
	border-radius: 50%;   /* seule courbe du système : c'est un cercle, pas un angle arrondi */
	background: var(--9b);
	color: var(--papier);
	font-size: var(--micro-t);
	line-height: 1;
	letter-spacing: var(--micro-l);
	font-weight: 500;
}

.panier-compteur:empty,
.panier-compteur[data-vide="1"] {
	display: none;
}

/* ═══════════════════════════════════════════════════════════════════════
   8 · FIL D'ARIANE
   ═══════════════════════════════════════════════════════════════════════ */

.fil-ariane,
.rank-math-breadcrumb {
	font-size: var(--petit-t);
	line-height: var(--petit-i);
	color: var(--2b);
	margin-bottom: var(--e5);
}

.fil-ariane a,
.rank-math-breadcrumb a {
	color: var(--2b);
	transition: color var(--transition);
}

.fil-ariane a:hover,
.rank-math-breadcrumb a:hover {
	color: var(--9b);
}

.fil-ariane .separateur,
.rank-math-breadcrumb .separator {
	color: var(--hb);
	margin-inline: var(--e2);
}

.fil-ariane .dernier,
.rank-math-breadcrumb .last {
	color: var(--4b);
}

/* ═══════════════════════════════════════════════════════════════════════
   9 · BOUTONS
   ═══════════════════════════════════════════════════════════════════════ */

.bouton,
.woocommerce button.button.alt,
.woocommerce a.button.alt,
.woocommerce input.button.alt,
.woocommerce button.button,
.woocommerce a.button,
.woocommerce input.button,
.woocommerce #respond input#submit {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	height: 48px;
	padding: 0 28px;
	background: var(--9b);
	color: var(--papier);
	font-family: var(--police);
	font-size: 16px;
	font-weight: 500;
	line-height: 1;
	border: 0;
	text-decoration: none;
	transition: background-color var(--transition);
}

.bouton:hover,
.woocommerce button.button.alt:hover,
.woocommerce a.button.alt:hover,
.woocommerce input.button.alt:hover,
.woocommerce button.button:hover,
.woocommerce a.button:hover,
.woocommerce input.button:hover,
.woocommerce #respond input#submit:hover {
	background: var(--6b);
	color: var(--papier);
}

.bouton:focus-visible {
	outline: 2px solid var(--9b);
	outline-offset: 2px;
}

.bouton[disabled],
.bouton.desactive,
.woocommerce button.button:disabled,
.woocommerce button.button:disabled[disabled],
.woocommerce a.button.disabled {
	background: var(--hb);
	color: var(--papier);
	cursor: not-allowed;
	opacity: 1;
}

.bouton--large {
	width: 100%;
}

/* Bouton secondaire : ni fond, ni bordure. Rien que le texte et son trait. */
.bouton-secondaire {
	display: inline-block;
	min-height: 44px;
	padding-block: var(--e3);
	background-color: transparent;
	background-image: var(--trait-souligne);
	background-repeat: repeat-x;
	background-position: 0 calc(100% - 8px);
	background-size: 64px 6px;
	color: var(--9b);
	font-size: 16px;
	font-weight: 500;
	transition: background-image var(--transition);
}

.bouton-secondaire:hover {
	background-image: var(--trait-souligne-fonce);
}

/* ═══════════════════════════════════════════════════════════════════════
   10 · CHAMPS DE SAISIE
   ═══════════════════════════════════════════════════════════════════════ */

.champ {
	display: block;
	margin-bottom: var(--e5);
}

.champ label,
.woocommerce form .form-row label,
.woocommerce-page form .form-row label {
	display: block;
	margin-bottom: var(--e1);
	font-size: var(--petit-t);
	line-height: var(--petit-i);
	font-weight: 500;
	color: var(--2b);
}

/* L'astérisque des champs obligatoires.

   WooCommerce la met en rouge vif. Le système n'admet de rouge que pour un
   message d'erreur, et une astérisque n'est pas une erreur : elle annonce
   une contrainte avant même que l'utilisateur ait écrit quoi que ce soit.
   Elle reprend donc la valeur du libellé. */
.woocommerce form .form-row .required,
.woocommerce form .form-row abbr.required {
	color: var(--2b);
	border: 0;
	text-decoration: none;
}

/* « (facultatif) » est une information, pas un ornement : il prend donc la
   valeur des libellés et non celle des traits. */
.woocommerce form .form-row .optional {
	color: var(--2b);
}

input[type="text"],
input[type="email"],
input[type="url"],
input[type="password"],
input[type="search"],
input[type="number"],
input[type="tel"],
input[type="date"],
select,
textarea,
.woocommerce form .form-row input.input-text,
.woocommerce form .form-row textarea,
.woocommerce form .form-row select,
.select2-container .select2-selection--single {
	width: 100%;
	height: 48px;
	padding: 0;
	background: transparent;
	border: 0;
	border-bottom: 1px solid var(--2h);
	color: var(--4b);
	font-family: var(--police);
	font-size: 16px;
	font-weight: 400;
	line-height: 48px;
	transition: border-color var(--transition);
}

textarea,
.woocommerce form .form-row textarea {
	height: auto;
	min-height: 120px;
	padding-block: var(--e3);
	line-height: var(--corps-i);
	resize: vertical;
}

/* Tout menu déroulant reçoit le chevron dessiné. La flèche du système
   d'exploitation serait le seul dessin de la page à ne pas avoir été
   tracé, et elle change d'aspect d'un appareil à l'autre. */
select,
.woocommerce form .form-row select {
	padding-right: var(--e5);
	appearance: none;
	background-image: var(--trait-chevron);
	background-repeat: no-repeat;
	background-position: right center;
	background-size: 16px 16px;
	cursor: pointer;
}

input:focus,
select:focus,
textarea:focus {
	outline: none;
	border-bottom: 1.5px solid var(--9b);
}

/* Le contour de mise au point reste visible au clavier, en plus du trait. */
input:focus-visible,
select:focus-visible,
textarea:focus-visible {
	outline: 2px solid var(--9b);
	outline-offset: 2px;
}

/* Un texte d'aide dans un champ reste du texte : il prend --2b, la valeur
   la plus claire que le système autorise pour être lu. --hb tomberait à
   2,05:1 sur le papier, illisible pour une bonne part des acheteurs. */
::placeholder {
	color: var(--2b);
	opacity: 1;
}

/* ── Erreur : le seul endroit du site où une couleur apparaît ─────────── */

.champ--erreur input,
.champ--erreur select,
.champ--erreur textarea,
.woocommerce form .form-row.woocommerce-invalid input.input-text,
.woocommerce form .form-row.woocommerce-invalid select {
	border-bottom-color: var(--erreur);
}

.champ-erreur {
	display: block;
	margin-top: var(--e1);
	font-size: var(--petit-t);
	line-height: var(--petit-i);
	font-weight: 400;
	color: var(--erreur);
}

/* ── Cases à cocher dessinées ────────────────────────────────────────── */

.case,
.woocommerce form .form-row-wide label.checkbox {
	display: flex;
	align-items: flex-start;
	gap: var(--e3);
	min-height: 44px;
	padding-block: var(--e3);
	font-size: 15px;
	font-weight: 500;
	color: var(--4b);
	cursor: pointer;
}

.case input[type="checkbox"],
.case input[type="radio"] {
	position: absolute;
	opacity: 0;
	width: 0;
	height: 0;
}

/* Le carré esquissé, dessiné en SVG par inc/dessins.php et posé en fond. */
.case-marque {
	position: relative;
	flex: 0 0 auto;
	width: 18px;
	height: 18px;
	margin-top: 3px;
}

.case-marque svg {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
}

/* La coche n'apparaît qu'une fois la case cochée. */
.case-marque .coche {
	opacity: 0;
	transition: opacity var(--transition);
}

.case input:checked ~ .case-marque .coche {
	opacity: 1;
}

.case input:focus-visible ~ .case-marque {
	outline: 2px solid var(--9b);
	outline-offset: 2px;
}

/* ═══════════════════════════════════════════════════════════════════════
   11 · CARTE PRODUIT ET GRILLE
   ═══════════════════════════════════════════════════════════════════════ */

.grille-produits,
.woocommerce ul.products {
	display: grid;
	grid-template-columns: repeat(4, 1fr);
	column-gap: var(--e6);
	row-gap: var(--e7);
	margin: 0;
	padding: 0;
	list-style: none;
}

/* Ceinture, en plus du retrait de woocommerce-layout : toute extension qui
   poserait un clearfix sur cette liste lui offrirait une cellule de grille
   vide en tête. Un pseudo-élément décoratif n'a rien à faire dans une
   grille de produits. */
.woocommerce ul.products::before,
.woocommerce ul.products::after {
	display: none;
}

/* La carte s'étire sur toute la hauteur de sa cellule, et le lien qui
   l'enveloppe absorbe l'espace disponible. Sans cela, une carte au titre
   d'une seule ligne remonte son bouton de 26px et la rangée perd son
   alignement — le défaut se voit immédiatement sur une grille de quatre. */
.carte-produit,
.woocommerce ul.products li.product {
	position: relative;
	display: flex;
	flex-direction: column;
	margin: 0;
	padding: 0;
	width: auto;
	float: none;
	text-align: left;
}

/* `:not(.button)` n'est pas une précaution : le bouton d'ajout est lui
   aussi un <a> enfant direct de la carte. Sans l'exclure, il héritait du
   `flex: 1` et s'étirait sur toute la hauteur restante — c'est ce qui
   faisait remonter et grossir le bouton des cartes à titre court.

   `flex: 1 1 auto` et non `flex: 1` : la base à zéro fait mal calculer la
   hauteur d'une image à `aspect-ratio`. */
.carte-produit > a:not(.button) {
	display: flex;
	flex-direction: column;
	flex: 1 1 auto;
	color: inherit;
}

.carte-produit .carte-corps {
	flex: 1 1 auto;
}

/* Le bouton garde sa hauteur propre, quoi qu'il arrive. */
.woocommerce ul.products li.product .button,
.woocommerce ul.products li.product .added_to_cart {
	flex: 0 0 auto;
}

/* L'image et son cadre esquissé. Le cadre est un SVG posé par-dessus, en
   dehors du flux : il n'occupe pas de place et ne déplace donc rien quand
   ses traits dépassent des coins.

   Les éléments de la carte sont des <span> et non des <div> : la carte
   entière est un lien, et un lien ne peut pas contenir de contenu de type
   bloc. Il faut donc leur rendre explicitement leur affichage. */
.carte-image {
	display: block;
	position: relative;
	aspect-ratio: 3 / 4;
	background: var(--papier);
	overflow: visible;
}

.carte-niveau,
.carte-prix,
.carte-titre {
	display: block;
}

.carte-image img {
	width: 100%;
	height: 100%;
	object-fit: cover;
}

/* Le cadre esquissé.

   Quatre traits posés en couches de fond, un par bord. Le cadre déborde de
   4px sur chaque côté : les traits horizontaux dépassent donc de 4px à
   gauche et à droite du visuel, les verticaux de 4px en haut et en bas, et
   les coins ne se rejoignent pas — ils se croisent, chacun poursuivant sa
   route au-delà de l'autre. C'est ce que fait une main qui ne lève pas le
   crayon exactement au bon endroit. */
.cadre-esquisse {
	position: absolute;
	inset: -4px;
	pointer-events: none;

	--h: var(--cadre-h);
	--v: var(--cadre-v);

	background-image: var(--h), var(--h), var(--v), var(--v);
	background-repeat: repeat-x, repeat-x, repeat-y, repeat-y;
	background-position: 0 0, 0 100%, 0 0, 100% 0;
	background-size: 120px 5px, 120px 5px, 5px 120px, 5px 120px;
	transition: background-image var(--transition);
}

.carte-produit:hover .cadre-esquisse {
	--h: var(--cadre-h-fonce);
	--v: var(--cadre-v-fonce);
}

/* Trois décalages, pour que deux cartes voisines ne portent pas exactement
   le même tracé. Le décalage est déterminé par la position dans la grille,
   donc stable d'un chargement à l'autre : une page mise en cache et une
   page fraîche rendent le même dessin. */
.carte-produit:nth-child(3n + 2) .cadre-esquisse {
	background-position: -37px 0, -71px 100%, 0 -23px, 100% -58px;
}

.carte-produit:nth-child(3n) .cadre-esquisse {
	background-position: -82px 0, -19px 100%, 0 -64px, 100% -11px;
}

/* Sous l'image : niveau, titre, prix. Écarts imposés, dans cet ordre. */
/* Le corps de la carte : 16px sous l'image, puis niveau, titre et prix
   espacés de 8px. `align-content: start` empêche l'étirement de disperser
   ces trois lignes quand la carte est plus haute que son contenu. */
.carte-corps {
	margin-top: var(--e4);
	display: flex;
	flex-direction: column;
	align-content: start;
	gap: var(--e2);
}

.carte-niveau {
	font-size: var(--petit-t);
	line-height: var(--petit-i);
	font-weight: 400;
	color: var(--2b);
}

.carte-titre,
.woocommerce ul.products li.product .woocommerce-loop-product__title {
	font-size: var(--h4-t);
	line-height: var(--h4-i);
	font-weight: 500;
	color: var(--9b);
	margin: 0;
	padding: 0;
	/* Deux lignes au maximum : au-delà, la grille se déforme. */
	display: -webkit-box;
	-webkit-line-clamp: 2;
	line-clamp: 2;
	-webkit-box-orient: vertical;
	overflow: hidden;
}

.carte-prix,
.woocommerce ul.products li.product .price {
	font-size: 18px;
	line-height: 1.3;
	font-weight: 600;
	color: var(--9b);
	margin: 0;
}

/* Pas d'étiquette de promotion : une pastille colorée sur une couverture
   est le seul endroit du site où une teinte apparaîtrait. */
.woocommerce span.onsale {
	display: none;
}

/* ── Le bouton d'ajout, sur la carte ─────────────────────────────────── */

/* Il occupe toute la largeur de la carte, sous le prix, à 16px. Sa hauteur
   est celle du bouton principal du système : c'en est un, pas une variante. */
.woocommerce ul.products li.product .button,
.woocommerce ul.products li.product .added_to_cart {
	display: flex;
	width: 100%;
	margin-top: var(--e4);
	padding-inline: var(--e4);
	text-align: center;
	/* Hauteur minimale et non fixe : dans une colonne de téléphone, le
	   libellé passe sur deux lignes et un bouton de 48px verrouillés le
	   ferait déborder par le bas. */
	height: auto;
	min-height: 48px;
	padding-block: var(--e3);
	line-height: 1.25;
}

/* Le second lien, « Voir le panier », que WooCommerce ajoute après un
   ajout réussi. Il ne doit pas se présenter comme un second bouton plein :
   c'est une confirmation, pas une action de même poids. */
.woocommerce ul.products li.product .added_to_cart {
	height: auto;
	min-height: 44px;
	align-items: center;
	justify-content: center;
	margin-top: var(--e2);
	background-color: transparent;
	background-image: var(--trait-souligne);
	background-repeat: repeat-x;
	background-position: 50% calc(100% - 10px);
	background-size: 64px 6px;
	color: var(--9b);
	font-size: 15px;
	font-weight: 500;
}

.woocommerce ul.products li.product .added_to_cart:hover {
	background-color: transparent;
	background-image: var(--trait-souligne-fonce);
	color: var(--9b);
}

/* Les états de l'ajout en arrière-plan.

   WooCommerce y affiche un caractère de sa propre police d'icônes, qui
   n'existe pas sur ce site : sans neutralisation, un carré vide apparaît à
   côté du texte. Le retour visuel passe donc par l'opacité, qui ne demande
   aucune ressource extérieure. */
.woocommerce ul.products li.product .button.loading::after,
.woocommerce ul.products li.product .button.added::after,
.woocommerce ul.products li.product .button::after {
	display: none;
	content: none;
}

.woocommerce ul.products li.product .button.loading {
	opacity: 0.55;
	pointer-events: none;
}

/* ═══════════════════════════════════════════════════════════════════════
   12 · PAGE CATÉGORIE
   ═══════════════════════════════════════════════════════════════════════ */

.entete-categorie h1 {
	margin-bottom: var(--e5);
}

.introduction {
	font-size: var(--corps-t);
	line-height: var(--corps-i);
	color: var(--4b);
	max-width: var(--mesure);
}

/* Le bloc de liens, sous la description.

   Il doit se lire comme un aparté, pas comme la suite du paragraphe. Sans
   distinction, les 80 mots de la description et les trois liens formaient
   un pavé de huit lignes, et la description soignée disparaissait dedans. */
.maillage {
	margin-top: var(--e5);
	max-width: var(--mesure);
	font-size: 15px;
	line-height: 24px;
	color: var(--2b);
}

/* Les liens du maillage portent le trait ondulé : sans lui, ils se
   confondent avec le texte, en --9b sur --2b. */
.maillage a {
	color: var(--9b);
	background-image: var(--trait-souligne);
	background-repeat: repeat-x;
	background-position: 0 calc(100% + 3px);
	background-size: 64px 6px;
	padding-bottom: 4px;
	transition: background-image var(--transition);
}

.maillage a:hover {
	background-image: var(--trait-souligne-fonce);
}

.barre-filtres {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: var(--e5);
	margin-bottom: var(--e7);
}

.barre-filtres .case {
	min-height: 44px;
}

/* Le tri de WooCommerce entre dans la barre, aligné à gauche comme le reste. */
.woocommerce .woocommerce-ordering {
	float: none;
	margin: 0;
}

.woocommerce .woocommerce-ordering select {
	width: auto;
	min-width: 200px;
}

.woocommerce .woocommerce-result-count {
	float: none;
	margin: 0;
	font-size: var(--petit-t);
	line-height: var(--petit-i);
	color: var(--2b);
}

/* ── Pagination ──────────────────────────────────────────────────────── */

.woocommerce nav.woocommerce-pagination,
.pagination {
	margin-top: var(--e9);
	text-align: left;
}

.woocommerce nav.woocommerce-pagination ul,
.pagination .nav-links {
	display: flex;
	gap: var(--e5);
	border: 0;
	margin: 0;
	padding: 0;
}

.woocommerce nav.woocommerce-pagination ul li,
.pagination .nav-links > * {
	border: 0;
	margin: 0;
}

.woocommerce nav.woocommerce-pagination ul li a,
.woocommerce nav.woocommerce-pagination ul li span,
.pagination .page-numbers {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-width: 44px;
	min-height: 44px;
	padding: 0;
	background: none;
	font-size: 15px;
	font-weight: 500;
	color: var(--2b);
	transition: color var(--transition);
}

.woocommerce nav.woocommerce-pagination ul li span.current,
.pagination .page-numbers.current {
	color: var(--9b);
}

.woocommerce nav.woocommerce-pagination ul li a:hover,
.pagination a.page-numbers:hover {
	background: none;
	color: var(--9b);
}

/* ═══════════════════════════════════════════════════════════════════════
   13 · FICHE PRODUIT
   ═══════════════════════════════════════════════════════════════════════ */

.fiche-produit,
.woocommerce div.product {
	display: grid;
	grid-template-columns: 55fr 45fr;
	column-gap: var(--e8);
	align-items: start;
}

.woocommerce div.product div.images,
.fiche-image {
	position: relative;
	float: none;
	width: auto;
	margin: 0;
}

.woocommerce div.product div.images img {
	width: 100%;
}

/* Le cadre de la fiche est le même composant que celui des cartes : même
   trait, même débord, à la même taille réelle. */
.fiche-cadre {
	position: absolute;
	inset: -4px;
}

.woocommerce div.product div.summary,
.fiche-detail {
	float: none;
	width: auto;
	margin: 0;
}

.woocommerce div.product .product_title,
.fiche-detail h1 {
	font-size: var(--h1-t);
	line-height: var(--h1-i);
	letter-spacing: var(--h1-l);
	font-weight: 600;
	color: var(--9b);
	margin-bottom: var(--e3);
}

.fiche-meta {
	font-size: var(--petit-t);
	line-height: var(--petit-i);
	font-weight: 400;
	color: var(--2b);
	margin-bottom: var(--e5);
}

.woocommerce div.product p.price,
.woocommerce div.product span.price,
.fiche-prix {
	font-size: var(--h3-t);
	line-height: var(--h3-i);
	letter-spacing: var(--h3-l);
	font-weight: 600;
	color: var(--9b);
	margin-bottom: var(--e5);
}

.woocommerce div.product p.price del,
.woocommerce div.product span.price del {
	color: var(--2b);
	font-weight: 400;
}

.woocommerce div.product p.price ins {
	text-decoration: none;
}

.woocommerce-product-details__short-description,
.produit-description {
	font-size: var(--corps-t);
	line-height: var(--corps-i);
	color: var(--4b);
	margin-bottom: var(--e6);
	max-width: var(--mesure);
}

/* Le bouton d'ajout occupe toute la largeur de sa colonne. */
.woocommerce div.product form.cart {
	margin: 0 0 var(--e7);
}

.woocommerce div.product form.cart .button {
	width: 100%;
}

/* Le champ de quantité n'est pas masqué ici : le filtre
   `woocommerce_is_sold_individually` fait que WooCommerce ne le rend pas du
   tout. Masquer en CSS un champ que le serveur envoie quand même laisserait
   une valeur modifiable à qui inspecte la page. */

/* ── Accordéons ──────────────────────────────────────────────────────── */

/* Les accordéons occupent les deux colonnes, sous l'image et le résumé. */
.accordeons {
	grid-column: 1 / -1;
	margin-top: var(--entre-sections);
}

.accordeon {
	border-top: 1px solid var(--2h);
}

.accordeon:last-of-type {
	border-bottom: 1px solid var(--2h);
}

.accordeon-titre {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: var(--e4);
	width: 100%;
	min-height: 44px;
	padding-block: var(--e4);
	font-size: var(--h4-t);
	line-height: var(--h4-i);
	font-weight: 500;
	color: var(--9b);
	text-align: left;
}

.accordeon-titre svg {
	flex: 0 0 auto;
	width: 16px;
	height: 16px;
	color: var(--hb);
	transition: transform var(--transition-ouverture);
}

.accordeon[open] .accordeon-titre svg {
	transform: rotate(180deg);
}

.accordeon-corps {
	padding-bottom: var(--e5);
	font-size: var(--corps-t);
	line-height: var(--corps-i);
	color: var(--4b);
	max-width: var(--mesure);
}

/* Le marqueur natif de <details> n'a pas sa place ici. */
.accordeon summary {
	list-style: none;
	cursor: pointer;
}

.accordeon summary::-webkit-details-marker,
.accordeon summary::marker {
	display: none;
	content: "";
}

/* L'ouverture, en 200ms.

   Elle repose sur ::details-content et interpolate-size, qui permettent
   d'animer vers une hauteur automatique sans JavaScript et sans figer une
   hauteur en dur. Les navigateurs qui ne les connaissent pas ouvrent
   l'accordéon d'un coup : le contenu est identique, seule la manière dont
   il apparaît change. C'est le bon sens de la dégradation. */
@supports (interpolate-size: allow-keywords) {
	:root {
		interpolate-size: allow-keywords;
	}

	.accordeon::details-content {
		height: 0;
		overflow: hidden;
		transition: height var(--transition-ouverture),
		            content-visibility var(--transition-ouverture) allow-discrete;
	}

	.accordeon[open]::details-content {
		height: auto;
	}
}

/* Les onglets de WooCommerce sont remplacés par les accordéons. */
.woocommerce div.product .woocommerce-tabs ul.tabs {
	display: none;
}

.woocommerce div.product .woocommerce-tabs {
	grid-column: 1 / -1;
	margin-top: var(--entre-sections);
}

.woocommerce div.product .woocommerce-tabs .panel {
	margin: 0;
	padding: 0;
}

.woocommerce div.product .woocommerce-tabs .panel h2 {
	font-size: var(--h3-t);
	line-height: var(--h3-i);
	font-weight: 500;
	margin-bottom: var(--e4);
}

.woocommerce div.product section.related,
.woocommerce div.product section.up-sells {
	grid-column: 1 / -1;
	margin-top: var(--entre-sections);
}

.woocommerce div.product section.related > h2 {
	margin-bottom: var(--e6);
}

/* ═══════════════════════════════════════════════════════════════════════
   14 · PANIER, COMMANDE, COMPTE

   Le système ne décrit pas ces écrans en détail. Ils reprennent donc ses
   règles générales sans rien inventer : filets droits, aucun rayon, aucune
   ombre, et les seules couleurs des jetons.
   ═══════════════════════════════════════════════════════════════════════ */

.woocommerce table.shop_table,
.woocommerce-page table.shop_table {
	border: 0;
	border-collapse: collapse;
	margin: 0 0 var(--e7);
}

.woocommerce table.shop_table th {
	padding: var(--e3) var(--e4) var(--e3) 0;
	border-bottom: 1px solid var(--2h);
	font-size: var(--petit-t);
	line-height: var(--petit-i);
	font-weight: 500;
	color: var(--2b);
	text-align: left;
}

.woocommerce table.shop_table td {
	padding: var(--e5) var(--e4) var(--e5) 0;
	border-top: 0;
	border-bottom: 1px solid var(--2h);
	font-size: var(--corps-t);
	color: var(--4b);
	vertical-align: top;
}

.woocommerce table.shop_table td.product-name a {
	font-weight: 500;
	color: var(--9b);
}

/* Les largeurs de colonnes.

   Avec `table-layout: auto`, une `width` posée sur une cellule n'est qu'un
   souhait : le navigateur répartit l'espace restant au prorata et donnait
   318px à la colonne de la croix de suppression. Ce qui fonctionne, c'est
   de désigner la colonne qui doit absorber le reste — celle du nom — en lui
   demandant 100%. Les autres se réduisent alors à leur contenu. */
.woocommerce table.shop_table .product-name {
	width: 100%;
}

.woocommerce table.shop_table .product-remove {
	width: 32px;
}

/* La colonne d'image a besoin d'un plancher.

   Une fois la colonne du nom à 100%, les autres se réduisent à leur
   contenu minimum — et le minimum d'une image en `max-width: 100%` est
   zéro. La vignette disparaissait, réduite à un trait de dix pixels. Il
   faut donc à la fois une largeur de colonne et un plancher sur l'image. */
.woocommerce table.shop_table .product-thumbnail {
	width: 88px;
	min-width: 88px;
}

.woocommerce table.shop_table .product-thumbnail img {
	width: 72px;
	min-width: 72px;
	max-width: none;
}

.woocommerce table.shop_table .product-price,
.woocommerce table.shop_table .product-subtotal {
	width: 120px;
	text-align: right;
	white-space: nowrap;
}

.woocommerce table.shop_table th {
	white-space: nowrap;
}

/* La colonne des quantités.

   Tous les produits sont vendus à l'unité (voir le filtre
   `woocommerce_is_sold_individually`) : cette colonne afficherait « 1 » sur
   chaque ligne, sans exception possible. Une colonne dont la valeur est
   constante n'informe de rien et vole de la place au nom du produit. */
.woocommerce table.shop_table .product-quantity {
	display: none;
}

.woocommerce table.shop_table td.product-total,
.woocommerce table.shop_table .order-total td {
	font-weight: 600;
	color: var(--9b);
}

/* La rangée d'actions.

   Le `td` garde son `display` de cellule. Le passer en `flex` paraît
   naturel, mais une cellule qui quitte le modèle tableau PERD SON COLSPAN :
   elle se replie sur la largeur de la première colonne, et le champ de code
   promo se retrouve à 57px de large sous le bouton. Mesuré. La disposition
   se fait donc à l'intérieur, sur les enfants. */
.woocommerce table.cart td.actions {
	border-bottom: 0;
	padding-top: var(--e6);
}

.woocommerce table.cart td.actions .coupon {
	display: flex;
	align-items: flex-end;
	gap: var(--e4);
	max-width: 560px;
	margin-bottom: var(--e5);
}

/* Le champ de code promo porte une bordure complète dans la feuille de
   WooCommerce, avec une spécificité supérieure à celle du sélecteur
   d'attribut. Il faut donc le nommer précisément. */
.woocommerce table.cart td.actions .coupon .input-text {
	flex: 1;
	width: auto;
	min-width: 0;
	padding: 0;
	border: 0;
	border-bottom: 1px solid var(--2h);
	background: transparent;
}

.woocommerce table.cart td.actions .coupon .input-text:focus {
	border-bottom: 1.5px solid var(--9b);
}

.woocommerce table.cart td.actions .button[name="update_cart"] {
	flex: 0 0 auto;
}

.woocommerce a.remove {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 24px;
	height: 24px;
	color: var(--2b) !important;
	font-size: 18px;
	font-weight: 400;
	line-height: 1;
	background: none !important;
}

.woocommerce a.remove:hover {
	color: var(--9b) !important;
	background: none !important;
}

.woocommerce .cart-collaterals,
.woocommerce-page .cart-collaterals {
	width: 100%;
}

.woocommerce .cart_totals,
.woocommerce-page .cart_totals {
	float: none;
	width: 100%;
	max-width: 420px;
	margin-left: auto;
}

.woocommerce .cart_totals h2,
.woocommerce-checkout h3 {
	font-size: var(--h3-t);
	line-height: var(--h3-i);
	font-weight: 500;
	margin-bottom: var(--e4);
}

/* Le récapitulatif : intitulé à gauche, montant à droite, sur la même
   ligne de base. Sans alignement explicite, le montant se pose au milieu
   de sa cellule et ne s'aligne avec rien. */
.woocommerce .cart_totals table.shop_table th {
	width: 50%;
	padding-block: var(--e4);
	vertical-align: baseline;
}

.woocommerce .cart_totals table.shop_table td {
	padding-block: var(--e4);
	padding-right: 0;
	text-align: right;
	vertical-align: baseline;
}

/* Les frais de port n'ont pas lieu d'être : tout est téléchargeable. */
.woocommerce .cart_totals .shipping,
.woocommerce-checkout .shipping,
.woocommerce-checkout .woocommerce-shipping-fields {
	display: none;
}

/* ── La page de commande ─────────────────────────────────────────────── */

/* Deux colonnes, dans la proportion de la fiche produit : la saisie à
   gauche, le récapitulatif à droite. WooCommerce les empilait sur toute la
   largeur depuis le retrait de sa feuille de mise en page, ce qui étirait
   un champ « code postal » sur 1200 pixels. */
.woocommerce-checkout form.checkout {
	display: grid;
	grid-template-columns: 55fr 45fr;
	/* La première rangée épouse le titre du récapitulatif, la seconde prend
	   le reste. Sans cette contrainte, la grille répartit la hauteur du
	   formulaire de facturation entre les deux rangées, et le titre
	   « Votre commande » se retrouve à 250px au-dessus de son tableau. */
	grid-template-rows: min-content auto;
	column-gap: var(--e8);
	align-items: start;
}

.woocommerce-checkout form.checkout #customer_details {
	grid-column: 1;
	grid-row: 1 / span 2;
}

.woocommerce-checkout form.checkout #order_review_heading {
	grid-column: 2;
	grid-row: 1;
	margin-top: 0;
}

.woocommerce-checkout form.checkout #order_review {
	grid-column: 2;
	grid-row: 2;
}

/* Les avis et messages posés par WooCommerce avant le formulaire doivent
   rester pleine largeur. */
.woocommerce-checkout form.checkout > .woocommerce-NoticeGroup,
.woocommerce-checkout form.checkout > .woocommerce-notices-wrapper {
	grid-column: 1 / -1;
}

/* Prénom et nom sur une même ligne. Ces deux classes portaient leurs
   largeurs dans woocommerce-layout ; sans lui, chaque champ occupait une
   ligne entière. */
.woocommerce form .form-row {
	display: block;
	margin: 0 0 var(--e5);
	padding: 0;
}

.woocommerce form .form-row-first,
.woocommerce form .form-row-last {
	display: inline-block;
	width: calc(50% - (var(--e5) / 2));
	vertical-align: top;
}

.woocommerce form .form-row-first {
	margin-right: var(--e5);
}

.woocommerce-checkout #payment,
.woocommerce-checkout .woocommerce-checkout-review-order {
	background: none;
	border: 0;
	padding: 0;
}

.woocommerce-checkout #payment ul.payment_methods {
	border-bottom: 1px solid var(--2h);
	padding: 0 0 var(--e5);
	margin-bottom: var(--e5);
}

.woocommerce-checkout #payment div.payment_box {
	background: var(--2h);
	color: var(--4b);
	font-size: var(--petit-t);
	line-height: var(--petit-i);
	padding: var(--e4);
	margin-top: var(--e3);
}

.woocommerce-checkout #payment div.payment_box::before {
	display: none;
}

/* ── Messages ────────────────────────────────────────────────────────── */

/* Les sélecteurs sont préfixés de `.woocommerce` : la feuille de
   l'extension pose ses propres bordures avec cette spécificité, et une
   règle plus faible laisserait un encadrement complet là où le système
   n'admet qu'un filet haut. */
.woocommerce .woocommerce-message,
.woocommerce .woocommerce-info,
.woocommerce .woocommerce-error,
.woocommerce-page .woocommerce-message,
.woocommerce-page .woocommerce-info,
.woocommerce-page .woocommerce-error {
	display: flex;
	align-items: center;
	flex-wrap: wrap;
	gap: var(--e4);
	margin: 0 0 var(--e6);
	padding: var(--e4) var(--e5);
	background: var(--2h);
	border: 0;
	border-top: 2px solid var(--9b);
	color: var(--4b);
	font-size: var(--corps-t);
	line-height: var(--corps-i);
	list-style: none;
}

.woocommerce .woocommerce-message::before,
.woocommerce .woocommerce-info::before,
.woocommerce .woocommerce-error::before,
.woocommerce-page .woocommerce-message::before,
.woocommerce-page .woocommerce-info::before,
.woocommerce-page .woocommerce-error::before {
	display: none;
}

.woocommerce .woocommerce-error,
.woocommerce-page .woocommerce-error {
	border-top-color: var(--erreur);
	color: var(--erreur);
}

/* Les invitations, plus discrètes que les confirmations.

   La page de commande en empile trois d'affilée : « ajouté au panier »,
   « déjà client ? », « un code promo ? ». Traitées à l'identique, elles
   forment un mur de trois blocs pleins avant le premier champ, et la seule
   qui annonce quelque chose se perd au milieu des deux qui proposent. Une
   invitation garde donc le filet, pas le fond. */
.woocommerce .woocommerce-info,
.woocommerce-page .woocommerce-info {
	background: none;
	padding-inline: 0;
	border-bottom: 1px solid var(--2h);
	border-top-color: var(--2h);
	border-top-width: 1px;
	color: var(--2b);
}

.woocommerce .woocommerce-info a,
.woocommerce-page .woocommerce-info a {
	color: var(--9b);
	font-weight: 500;
}

/* WooCommerce donne un tabindex à ses messages et leur met le focus pour
   qu'un lecteur d'écran les annonce. Le navigateur dessine alors son
   contour par défaut, qui encadre la boîte de trois pixels et contredit le
   filet haut seul du système. Le message n'étant pas un élément
   interactif, retirer ce contour ne retire aucun repère à personne : le
   focus reste posé, et l'annonce a bien lieu. */
.woocommerce .woocommerce-message:focus,
.woocommerce .woocommerce-info:focus,
.woocommerce .woocommerce-error:focus,
.woocommerce-page .woocommerce-message:focus,
.woocommerce-page .woocommerce-info:focus,
.woocommerce-page .woocommerce-error:focus {
	outline: none;
}

.woocommerce-message .button,
.woocommerce-info .button {
	margin-left: auto;
}

/* ── Mon compte ──────────────────────────────────────────────────────── */

.woocommerce-account .woocommerce-MyAccount-navigation {
	float: none;
	width: 100%;
	margin-bottom: var(--e7);
}

.woocommerce-account .woocommerce-MyAccount-navigation ul {
	display: flex;
	flex-wrap: wrap;
	gap: var(--e5);
	margin: 0;
	padding: 0;
	list-style: none;
	border-bottom: 1px solid var(--2h);
}

.woocommerce-account .woocommerce-MyAccount-navigation li a {
	display: inline-flex;
	align-items: center;
	min-height: 44px;
	font-size: 15px;
	font-weight: 500;
	color: var(--2b);
	transition: color var(--transition);
}

.woocommerce-account .woocommerce-MyAccount-navigation li.is-active a,
.woocommerce-account .woocommerce-MyAccount-navigation li a:hover {
	color: var(--9b);
}

.woocommerce-account .woocommerce-MyAccount-content {
	float: none;
	width: 100%;
}

/* ═══════════════════════════════════════════════════════════════════════
   15 · PIED DE PAGE
   ═══════════════════════════════════════════════════════════════════════ */

/* Le pied n'a pas de marge haute : le filet dessiné EST sa limite
   supérieure. Avec un padding en haut, il se retrouvait 64px à l'intérieur
   du fond sombre, précédé d'une bande noire qui ne séparait rien. */
.site-pied {
	background: var(--9b);
	color: var(--papier);
	padding-block: 0 var(--e8);
	font-size: 15px;
	line-height: 24px;
}

/* Le filet dessiné du haut, en --hb sur le fond sombre. */
.site-pied::before {
	content: "";
	display: block;
	height: 9px;
	margin-bottom: var(--e8);
	background-image: var(--trait-filet);
	background-repeat: repeat-x;
	background-position: 0 50%;
	background-size: 240px 9px;
}

.pied-colonnes {
	display: grid;
	grid-template-columns: repeat(4, 1fr);
	gap: var(--e6);
	margin-bottom: var(--e8);
}

.site-pied .widget-titre,
.site-pied h2 {
	font-size: 16px;
	line-height: 24px;
	font-weight: 600;
	color: var(--papier);
	margin-bottom: var(--e4);
}

.site-pied a {
	color: var(--papier);
	background-image: none;
	background-repeat: repeat-x;
	background-position: 0 calc(100% + 4px);
	background-size: 64px 6px;
	padding-bottom: 5px;
	transition: background-image var(--transition);
}

/* Le soulignement n'apparaît qu'au survol, contrairement au reste du site. */
.site-pied a:hover {
	background-image: var(--trait-souligne-clair);
}

.site-pied ul {
	display: flex;
	flex-direction: column;
	gap: var(--e3);
	margin: 0;
	padding: 0;
	list-style: none;
}

.site-pied :focus-visible {
	outline-color: var(--papier);
}

/* La mention de copyright est du texte : elle garde la valeur du pied de
   page. --hb passerait le contraste sur ce fond sombre, mais la règle du
   système ne porte pas sur le contraste : --hb est la valeur des traits,
   et un trait ne se lit pas. */
.mention-legale {
	font-size: var(--petit-t);
	line-height: var(--petit-i);
	color: var(--papier);
}

.menu-pied {
	display: flex;
	flex-wrap: wrap;
	gap: var(--e5);
	margin-bottom: var(--e5);
}

/* ═══════════════════════════════════════════════════════════════════════
   16 · LISTES ET ARCHIVES
   ═══════════════════════════════════════════════════════════════════════ */

.liste-articles {
	display: grid;
	gap: var(--e7);
	max-width: var(--mesure);
}

.apercu-titre {
	font-size: var(--h3-t);
	line-height: var(--h3-i);
	letter-spacing: var(--h3-l);
	font-weight: 500;
	margin-bottom: var(--e2);
}

.apercu-extrait {
	color: var(--4b);
}

.entete-archive,
.page-entete,
.article-entete {
	margin-bottom: var(--e7);
}

.article-date {
	margin-top: var(--e3);
	font-size: var(--petit-t);
	line-height: var(--petit-i);
	color: var(--2b);
}

.article-image {
	margin-bottom: var(--e7);
}

.page-404 {
	max-width: var(--mesure);
}

.page-404 h1 {
	margin-bottom: var(--e5);
}

.page-404 .formulaire-recherche {
	margin-block: var(--e7);
}

/* ── Recherche ───────────────────────────────────────────────────────── */

.formulaire-recherche {
	display: flex;
	align-items: flex-end;
	gap: var(--e4);
	max-width: 480px;
}

.formulaire-recherche .champ-recherche {
	flex: 1;
}

/* ═══════════════════════════════════════════════════════════════════════
   17 · MOUVEMENT

   Les transitions ne répondent qu'à une action : survol, mise au point,
   ouverture. Rien ne bouge à l'apparition, rien ne se déclenche au
   défilement.
   ═══════════════════════════════════════════════════════════════════════ */

@media (prefers-reduced-motion: reduce) {
	html {
		scroll-behavior: auto;
	}

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

/* ═══════════════════════════════════════════════════════════════════════
   18 · RESPONSIVE

   Toutes les règles adaptatives vivent ici, en fin de fichier. Écrites à
   côté de leur composant, elles passeraient AVANT les règles de base et
   seraient écrasées à spécificité égale : le responsif entier deviendrait
   du code mort. Erreur vécue sur prise-de-courant.com, à ne pas refaire.
   ═══════════════════════════════════════════════════════════════════════ */

/* ── Grille produits, par palier ─────────────────────────────────────── */

@media (max-width: 1024px) {
	.grille-produits,
	.woocommerce ul.products {
		grid-template-columns: repeat(3, 1fr);
	}
}

@media (max-width: 768px) {
	.grille-produits,
	.woocommerce ul.products {
		grid-template-columns: repeat(2, 1fr);
	}
}

/* ── Fiche produit et commande : une colonne avant le palier mobile ──── */

@media (max-width: 900px) {
	.fiche-produit,
	.woocommerce div.product {
		grid-template-columns: 1fr;
		row-gap: var(--e7);
	}

	.woocommerce-checkout form.checkout {
		grid-template-columns: 1fr;
		row-gap: var(--e7);
	}

	/* Les placements explicites doivent être défaits, sans quoi le
	   récapitulatif reste coincé dans une deuxième colonne qui n'existe
	   plus et se superpose à la saisie. */
	.woocommerce-checkout form.checkout #customer_details,
	.woocommerce-checkout form.checkout #order_review_heading,
	.woocommerce-checkout form.checkout #order_review {
		grid-column: 1;
		grid-row: auto;
	}
}

/* ── Pied de page ────────────────────────────────────────────────────── */

@media (max-width: 900px) {
	.pied-colonnes {
		grid-template-columns: repeat(2, 1fr);
		gap: var(--e7) var(--e6);
	}
}

/* ── Palier mobile ───────────────────────────────────────────────────── */

@media (max-width: 767px) {
	:root {
		--marge: 20px;
		--entre-sections: 56px;

		/* Échelle mobile. Les interlignes valent 1,35 fois la taille. */
		--display-t: 33px;  --display-i: 44px;
		--h1-t:      27px;  --h1-i:      36px;
		--h2-t:      23px;  --h2-i:      31px;
		--h3-t:      20px;  --h3-i:      27px;
		--h4-t:      18px;  --h4-i:      24px;
		--corps-t:   16px;  --corps-i:   22px;
		--petit-t:   13px;  --petit-i:   18px;
		--micro-t:   11px;  --micro-i:   15px;
	}

	.site-corps {
		padding-block: var(--e6) var(--entre-sections);
	}

	.grille-produits,
	.woocommerce ul.products {
		grid-template-columns: repeat(2, 1fr);
		column-gap: var(--e5);
		row-gap: var(--e6);
	}

	/* Deux colonnes sur un téléphone laissent environ 160px par carte :
	   le bouton garde sa hauteur de cible tactile mais resserre son texte. */
	.woocommerce ul.products li.product .button,
	.woocommerce ul.products li.product .added_to_cart {
		margin-top: var(--e3);
		padding-inline: var(--e2);
		font-size: 15px;
	}

	.entete-interieur {
		gap: var(--e4);
	}

	/* La navigation passe sous le titre plutôt que de le comprimer. */
	.entete-interieur {
		height: auto;
		flex-wrap: wrap;
		padding-block: var(--e3);
	}

	.navigation-principale {
		order: 3;
		width: 100%;
		margin-inline-start: 0;
	}

	.menu-principal {
		flex-wrap: wrap;
		gap: var(--e4);
	}

	.menu-principal a {
		min-height: 40px;
		font-size: 15px;
	}

	/* Le lockup mesure 172px de large à 26px de haut : avec l'icône du
	   panier, il ne reste rien pour respirer sur un écran de 320px. */
	.site-logo {
		height: 22px;
	}

	.filet {
		margin-block: var(--e6);
	}

	.pied-colonnes {
		grid-template-columns: 1fr;
		gap: var(--e7);
	}

	.site-pied {
		padding-block: 0 var(--e7);
	}

	.site-pied::before {
		margin-bottom: var(--e7);
	}

	.woocommerce .cart_totals,
	.woocommerce-page .cart_totals {
		max-width: none;
	}

	/* Le tableau du panier ne tient pas en deux dimensions sur un
	   téléphone : chaque ligne devient un bloc, l'en-tête disparaît et
	   l'intitulé de colonne est repris par WooCommerce en data-title. */
	.woocommerce table.shop_table_responsive thead {
		display: none;
	}

	.woocommerce table.shop_table_responsive tr {
		display: block;
		padding-block: var(--e4);
		border-bottom: 1px solid var(--2h);
	}

	/* La rangée d'actions est exclue : elle porte un colspan, et une
	   cellule mise en flex le perd. Elle débordait de 66px, mesuré. */
	.woocommerce table.shop_table_responsive td:not(.actions) {
		display: flex;
		justify-content: space-between;
		gap: var(--e4);
		padding: var(--e2) 0;
		border: 0;
		text-align: right;
	}

	.woocommerce table.shop_table_responsive td:not(.actions)::before {
		content: attr(data-title) ": ";
		font-size: var(--petit-t);
		font-weight: 500;
		color: var(--2b);
		text-align: left;
	}

	.woocommerce table.shop_table_responsive td.actions {
		display: block;
		padding: var(--e5) 0 0;
		border: 0;
		text-align: left;
	}

	/* Le code promo et son bouton s'empilent : côte à côte, ils ne tiennent
	   pas dans la largeur d'un téléphone. */
	.woocommerce table.cart td.actions .coupon {
		flex-direction: column;
		align-items: stretch;
		max-width: none;
	}

	.woocommerce table.cart td.actions .button {
		width: 100%;
	}

	/* Prénom et nom repassent l'un sous l'autre : deux champs de 45px de
	   large ne se remplissent pas au pouce. */
	.woocommerce form .form-row-first,
	.woocommerce form .form-row-last {
		display: block;
		width: 100%;
		margin-right: 0;
	}
}
