/* ==========================================================================
   VeloDisco — feuille de style principale
   Sommaire :
   1. Tokens & dark mode
   2. Base / réglages globaux
   3. Header (en-tête)
   4. Menu burger mobile
   5. Popover recherche + dropdown réglage
   6. Footer (pied de page)
   7. Cartes & images (tracé catégorie)
   8. Animations (transitions, reveal au scroll)
   9. Accessibilité (reduced motion, focus)
   ========================================================================== */

/* 0. POLICE SERIF (Merriweather, titres d'articles — auto-hébergée) --------- */
@font-face {
	font-family: "Merriweather";
	font-style: normal;
	font-weight: 300 900;
	font-display: swap;
	src: url(../fonts/merriweather-latin-wght-normal.woff2) format("woff2");
	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+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
	font-family: "Merriweather";
	font-style: normal;
	font-weight: 300 900;
	font-display: swap;
	src: url(../fonts/merriweather-latin-ext-wght-normal.woff2) format("woff2");
	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;
}
@font-face {
	font-family: "Merriweather";
	font-style: italic;
	font-weight: 300 900;
	font-display: swap;
	src: url(../fonts/merriweather-latin-italic-wght-normal.woff2) format("woff2");
	unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+2000-206F, U+2074, U+20AC, U+2122, U+FEFF, U+FFFD;
}

/* 1. TOKENS & DARK MODE ---------------------------------------------------- */
/*
 * Les couleurs de marque viennent de theme.json (--wp--preset--color--*).
 * Le dark mode redéfinit quelques presets : tout ce qui utilise base / contrast /
 * separator / societe bascule automatiquement, partout sur le site.
 */
:root {
	--vd-serif: "Merriweather", Georgia, "Times New Roman", serif;
	--vd-header-h: var(--wp--custom--layout--header-height, 76px);
	--vd-pill: var(--wp--custom--radius--pill, 999px);
	--vd-ease: var(--wp--custom--motion--ease, cubic-bezier(0.22, 1, 0.36, 1));
	--vd-t-fast: var(--wp--custom--motion--fast, 150ms);
	--vd-t-base: var(--wp--custom--motion--base, 260ms);
	--vd-t-slow: var(--wp--custom--motion--slow, 480ms);
	--vd-surface: rgba(0, 0, 0, 0.035);
	/* Gris "sourds" tokenisés (texte secondaire / dates / bordures d'input) */
	--vd-text-muted: #6C727F;   /* texte secondaire clair (excerpt, sous-titres) */
	--vd-text-soft:  #6B6B6B;   /* dates / légendes clair */
	--vd-border-soft:#D9D9E0;   /* bordure d'input */
	/* Rayons tokenisés */
	--vd-radius-sm: 4px;
	--vd-radius-md: 6px;
	--vd-radius-lg: 12px;
	/* Texte des étiquettes catégorie (contraste WCAG sur fond clair) */
	--vd-cat-text-velos: #D93E0C;
	--vd-cat-text-accessoires: #1A8927;
	--vd-cat-text-composants: #9C6D00;
	--vd-cat-text-vetements: #007EA9;
	--vd-cat-text-societe: var(--wp--preset--color--societe);
	/* Filet du footer (toujours noir → ce gris ne suit PAS le thème) */
	--vd-footer-line: #6C727F;
	color-scheme: light;
}

[data-theme="dark"] {
	--wp--preset--color--base: #000000;
	--wp--preset--color--contrast: #F5F5F0;
	--wp--preset--color--separator: #6C727F;
	--wp--preset--color--societe: #785FD3; /* lisibilité sur fond noir */
	--vd-surface: rgba(255, 255, 255, 0.06);
	--vd-text-soft: #9a9a9a;
	/* Sur fond noir les couleurs vives passent → on garde les presets vifs */
	--vd-cat-text-velos: var(--wp--preset--color--velos);
	--vd-cat-text-accessoires: var(--wp--preset--color--accessoires);
	--vd-cat-text-composants: var(--wp--preset--color--composants);
	--vd-cat-text-vetements: var(--wp--preset--color--vetements);
	color-scheme: dark;
}

/* 2. BASE ------------------------------------------------------------------ */
html {
	-webkit-text-size-adjust: 100%;
}

body {
	background-color: var(--wp--preset--color--base);
	color: var(--wp--preset--color--contrast);
	-webkit-font-smoothing: antialiased;
	-moz-osx-font-smoothing: grayscale;
	transition: background-color var(--vd-t-base) var(--vd-ease),
		color var(--vd-t-base) var(--vd-ease);
}

::selection {
	background: var(--wp--preset--color--velos);
	color: #fff;
}

/* Couleurs de catégorie utilitaires (texte) */
.vd-c-velos { color: var(--wp--preset--color--velos) !important; }
.vd-c-accessoires { color: var(--wp--preset--color--accessoires) !important; }
.vd-c-composants { color: var(--wp--preset--color--composants) !important; }
.vd-c-vetements { color: var(--wp--preset--color--vetements) !important; }
.vd-c-societe { color: var(--wp--preset--color--societe) !important; }

/* Titres d'articles en serif Merriweather */
.vd-serif { font-family: var(--vd-serif); }
.vd-single .wp-block-post-title { font-family: var(--vd-serif); }

/* Texte en gradient Grands Formats (clip sur le texte) */
.vd-gradient-text {
	background: var(--wp--preset--gradient--grands-formats);
	-webkit-background-clip: text;
	background-clip: text;
	-webkit-text-fill-color: transparent;
	color: transparent;
}

/* 3. HEADER ---------------------------------------------------------------- */
.vd-header {
	position: sticky;
	/* top tient compte de la barre d'admin WP (0 pour les visiteurs, 46px connecté). */
	top: var(--wp-admin--admin-bar--height, 0px);
	z-index: 100;
	background-color: var(--wp--preset--color--base);
	border-bottom: 1px solid var(--wp--preset--color--separator);
	min-height: var(--vd-header-h);
	transition: background-color var(--vd-t-base) var(--vd-ease),
		border-color var(--vd-t-base) var(--vd-ease);
	/* Pas de transition sur transform : l'auto-hide est lissé par une boucle
	 * requestAnimationFrame côté JS (glissement continu vers la cible à demi-vitesse). */
}

/* CAUSE RACINE du sticky cassé (desktop ET mobile) : WordPress enveloppe le header
 * dans <header class="wp-block-template-part"> qui ne fait QUE la hauteur du header.
 * Or sticky ne peut « coller » que dans les limites de son parent → ce wrapper trop
 * court le libère dès qu'on défile. display:contents efface la boîte du wrapper →
 * .vd-header colle alors par rapport à .wp-site-blocks (toute la page).
 * (Diagnostiqué en direct : sans ça rect.top tombait à -554 au scroll ; avec, 0.)
 * Appliqué globalement pour que l'auto-hide fonctionne aussi sur desktop. */
header.wp-block-template-part { display: contents; }

.vd-header__inner {
	max-width: 1440px;
	margin: 0 auto;
	min-height: var(--vd-header-h);
	padding-inline: clamp(16px, 1.9vw, 27px);
	/* Grille 3 colonnes : logo TOUJOURS centré sur la page (col. auto centrale),
	 * catégories collées à gauche, groupe droit collé à droite. */
	display: grid;
	/* minmax(0,1fr) : colonnes latérales STRICTEMENT égales (le contenu ne peut pas
	 * forcer une colonne plus large que l'autre) → « VeloDisco » centré pile sur la page. */
	grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);
	align-items: center;
	gap: 1rem;
}

/* Logo = wordmark « VeloDisco » + pastilles disco, le tout dans UN seul lien cliquable
 * (retour accueil). Centré sur la page en desktop (col. auto centrale de la grille). */
.vd-header__logo {
	grid-column: 2;
	justify-self: center;
	display: inline-flex;
	align-items: center;
	gap: 8px;
	font-weight: 700;
	font-size: clamp(26px, 2.5vw, 36px);
	letter-spacing: 0;
	text-transform: none;
	color: var(--wp--preset--color--contrast);
	text-decoration: none;
	white-space: nowrap;
}

/* Wordmark « VeloDisco » : crossfade en OPACITÉ (composité GPU → parfaitement fluide, aucun
 * à-coup) entre une couche couleur « disco » et la couche finale noire. Au chargement, la
 * couche couleur se fond (opacité 1→0, 2s linéaire) pour révéler la couche noire (= contrast,
 * off-white en sombre). Uniquement au chargement, pas de réaction au clic, pas de contour. */
.vd-header__wordmark {
	display: inline-grid;
	white-space: nowrap;
	/* La couche couleur découpe chaque lettre en <span> → le crénage saute entre les
	 * lettres et la couche couleur devient plus large que la couche noire (texte d'un
	 * seul tenant), d'où le décalage. On désactive le crénage sur les DEUX couches
	 * pour des largeurs de glyphes identiques → superposition exacte. */
	font-kerning: none;
	font-feature-settings: "kern" 0, "liga" 0;
}
.vd-wm { grid-area: 1 / 1; } /* les deux couches dans la MÊME cellule → superposition parfaite */
.vd-wm--ink { color: var(--wp--preset--color--contrast); }
/* Couche couleur : visible au chargement (animation intro 1→0 sur 2s), invisible au repos,
 * RÉAPPARAÎT au survol du logo (clin d'œil disco). On retire `forwards` pour que la valeur
 * de repos (opacity:0) reprenne après l'intro et que le :hover puisse l'override en douceur. */
.vd-wm--disco {
	pointer-events: none;
	opacity: 0;
	animation: vd-logo-fade 2s linear;
	transition: opacity 0.35s ease;
}
.vd-header__logo:hover .vd-wm--disco,
.vd-header__logo:focus-visible .vd-wm--disco {
	opacity: 1;
}

/* Pastilles disco (6 ronds 8.45px, grille 3×2) — masquées en desktop, apparaissent
 * en fondu en version mobile/tablette (cf. demande Victor). Mesures exactes Figma. */
.vd-header__dots {
	display: none;
	grid-template-columns: repeat(3, 8.45px);
	gap: 1.27px;
	flex: 0 0 auto;
}
.vd-header__dots span {
	display: block;
	width: 8.45px;
	height: 8.45px;
	border-radius: 50%;
}
@keyframes vd-fade-in { from { opacity: 0; } to { opacity: 1; } }
/* Chaque lettre part de sa couleur (--c) et fond vers la couleur de repos (contrast). */
@keyframes vd-logo-fade { from { opacity: 1; } to { opacity: 0; } }

/* Liens de nav : Inter Regular 12px (comme le Figma) */
.vd-header__nav {
	display: flex;
	align-items: center;
	font-size: 12px;
	font-weight: 400;
	letter-spacing: 0;
	text-transform: uppercase;
}

.vd-header__nav--left { grid-column: 1; justify-self: start; gap: clamp(14px, 1.8vw, 25px); }
.vd-header__nav--right { grid-column: 3; justify-self: end; gap: clamp(16px, 3.2vw, 46px); }

.vd-nav__link {
	position: relative;
	color: var(--wp--preset--color--contrast);
	text-decoration: none;
	padding-block: 0.35rem;
	white-space: nowrap; /* « Grands Formats » reste sur une seule ligne */
	transition: opacity var(--vd-t-fast) var(--vd-ease);
}

/* Couleur d'identité par catégorie */
.vd-nav__link--velos { color: var(--wp--preset--color--velos); }
.vd-nav__link--accessoires { color: var(--wp--preset--color--accessoires); }
.vd-nav__link--composants { color: var(--wp--preset--color--composants); }
.vd-nav__link--vetements { color: var(--wp--preset--color--vetements); }
.vd-nav__link--societe { color: var(--wp--preset--color--societe); }

/* Soulignement animé au survol (1px, demande Victor 2026-05-27) */
.vd-nav__link::after {
	content: "";
	position: absolute;
	left: 0;
	right: 0;
	bottom: 0;
	height: 1px;
	background: currentColor;
	transform: scaleX(0);
	transform-origin: left center;
	transition: transform var(--vd-t-base) var(--vd-ease);
}
.vd-nav__link:hover::after,
.vd-nav__link:focus-visible::after { transform: scaleX(1); }

/* Grands Formats : libellé en gradient + soulignement gradient */
.vd-nav__link--gf {
	background: var(--wp--preset--gradient--grands-formats-nav);
	-webkit-background-clip: text;
	background-clip: text;
	-webkit-text-fill-color: transparent;
	color: transparent;
}
.vd-nav__link--gf::after { background: var(--wp--preset--gradient--grands-formats-nav); }

/* Boutons icônes (loupe, réglage, burger) */
.vd-iconbtn {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 40px;
	height: 40px;
	padding: 0;
	border: 0;
	background: transparent;
	color: var(--wp--preset--color--contrast);
	cursor: pointer;
	border-radius: var(--vd-pill);
	transition: background-color var(--vd-t-fast) var(--vd-ease),
		transform var(--vd-t-fast) var(--vd-ease);
}
.vd-iconbtn:hover { background: var(--vd-surface); }
.vd-iconbtn:active { transform: scale(0.92); }
.vd-iconbtn svg { width: 22px; height: 22px; display: block; }

.vd-burger { display: none; }

/* 4. MENU BURGER MOBILE ---------------------------------------------------- */
.vd-mobile-nav {
	position: fixed;
	/* Ancré en HAUT + hauteur plein écran stable. On évite « inset:0 » (qui ancre le
	 * bas au viewport visible, lequel bouge quand la barre d'outils mobile se rétracte
	 * → saut « presque en bas » puis « plein écran »). 100lvh = hauteur « large » (chrome
	 * rétracté) → couvre tout dès l'ouverture, sans redimensionnement. */
	top: 0; left: 0; right: 0;
	height: 100vh;                   /* repli navigateurs anciens (≈ hauteur max sur iOS) */
	/* lvh = hauteur « large » = barre d'outils RÉTRACTÉE = hauteur MAX, indépendante de
	 * l'état courant. Donc même si on ouvre le menu en haut de page (barre déployée),
	 * l'overlay fait déjà la hauteur max → il couvre jusqu'au vrai bas, et quand la barre
	 * se rétracte rien ne bouge (plus de saut). +100px = marge tampon anti-décalage. */
	height: calc(100lvh + 100px);
	z-index: 200;
	background: var(--wp--preset--color--base);
	color: var(--wp--preset--color--contrast);
	display: flex;
	flex-direction: column;
	padding: 1.25rem clamp(1.25rem, 6vw, 2.5rem) 2.5rem;
	/* Quand on est connecté, la barre d'admin WP (46px, par-dessus tout) couvrait la
	 * rangée recherche/réglages/fermer du menu → on décale le contenu sous elle.
	 * Visiteurs (pas de barre) : la variable vaut 0, donc aucun effet. */
	padding-top: calc(1.25rem + var(--wp-admin--admin-bar--height, 0px));
	transform: translateY(-100%);
	visibility: hidden;
	transition: transform var(--vd-t-slow) var(--vd-ease), visibility 0s linear var(--vd-t-slow);
	overflow-y: auto;
}
.vd-mobile-nav.is-open {
	transform: translateY(0);
	visibility: visible;
	transition: transform var(--vd-t-slow) var(--vd-ease);
}
.vd-mobile-nav__top {
	display: flex;
	align-items: center;
	justify-content: flex-end;
	gap: 0.5rem;
	min-height: var(--vd-header-h);
}
.vd-mobile-nav__list {
	list-style: none;
	margin: 1.5rem 0 0;
	padding: 0;
	display: flex;
	flex-direction: column;
	gap: 0.35rem;
}
.vd-mobile-nav__list a {
	display: block;
	font-size: 1.625rem;
	font-weight: 200;
	letter-spacing: 0.01em;
	text-transform: uppercase;
	text-decoration: none;
	color: inherit;
	padding-block: 0.35rem;
	padding-inline: clamp(1.25rem, 6vw, 2.5rem);
	margin-inline: calc(-1 * clamp(1.25rem, 6vw, 2.5rem)); /* zone cliquable jusqu'aux bords de l'écran */
	opacity: 0;
	transform: translateY(12px);
}
.vd-mobile-nav.is-open .vd-mobile-nav__list a {
	animation: vd-stagger-in var(--vd-t-slow) var(--vd-ease) forwards;
}
.vd-mobile-nav__list li:nth-child(1) a { animation-delay: 60ms; }
.vd-mobile-nav__list li:nth-child(2) a { animation-delay: 110ms; }
.vd-mobile-nav__list li:nth-child(3) a { animation-delay: 160ms; }
.vd-mobile-nav__list li:nth-child(4) a { animation-delay: 210ms; }
.vd-mobile-nav__list li:nth-child(5) a { animation-delay: 260ms; }
.vd-mobile-nav__list li:nth-child(6) a { animation-delay: 310ms; }
.vd-mobile-nav__list li:nth-child(7) a { animation-delay: 360ms; }
.vd-mobile-nav__list li:nth-child(8) a { animation-delay: 410ms; }

@keyframes vd-stagger-in {
	to { opacity: 1; transform: translateY(0); }
}

/* « LE LABO » (menu burger) : pas de dégradé → texte plus GRAS + halo lumineux discret qui PULSE
   très lentement en passant d'une couleur de marque à l'autre. Le halo/cycle est porté par un
   <span class="vd-labo-glow"> intérieur pour ne PAS entrer en conflit avec l'animation d'entrée
   (vd-stagger-in, qui anime opacity/transform du <a>). Le <a> donne la graisse (héritée par le span). */
.vd-mobile-nav__list a.vd-labo-link { font-weight: 800; }
/* Couleur de REPOS (entre chaque couleur) : noir en thème clair, blanc cassé en thème sombre. */
.vd-labo-glow { --vd-labo-rest: #111111; color: var(--vd-labo-rest); }
html[data-theme="dark"] .vd-labo-glow { --vd-labo-rest: #F5F5F0; }
.vd-mobile-nav.is-open .vd-labo-glow {
	animation: vd-labo-glow 8s ease-in-out infinite; /* 2× plus rapide qu'avant (était 16s) */
	will-change: color, text-shadow;
}
/* 5 couleurs de marque, chacune sortant avec un halo, SÉPARÉES par un retour au repos (noir/blanc)
   où le halo s'éteint (text-shadow transparent → plus aucun rayonnement). */
@keyframes vd-labo-glow {
	0%, 100% { color: var(--vd-labo-rest); text-shadow: 0 0 0 rgba(0, 0, 0, 0); }
	10% { color: var(--c-red); text-shadow: 0 0 12px rgba(238, 42, 0, 0.60); }
	20% { color: var(--vd-labo-rest); text-shadow: 0 0 0 rgba(0, 0, 0, 0); }
	30% { color: var(--c-amber); text-shadow: 0 0 12px rgba(226, 146, 0, 0.60); }
	40% { color: var(--vd-labo-rest); text-shadow: 0 0 0 rgba(0, 0, 0, 0); }
	50% { color: var(--c-green); text-shadow: 0 0 12px rgba(0, 146, 12, 0.60); }
	60% { color: var(--vd-labo-rest); text-shadow: 0 0 0 rgba(0, 0, 0, 0); }
	70% { color: var(--c-blue); text-shadow: 0 0 12px rgba(0, 148, 200, 0.60); }
	80% { color: var(--vd-labo-rest); text-shadow: 0 0 0 rgba(0, 0, 0, 0); }
	90% { color: var(--c-purple); text-shadow: 0 0 12px rgba(125, 94, 218, 0.60); }
}
/* Accessibilité : pas d'animation si l'utilisateur préfère réduire les mouvements. */
@media (prefers-reduced-motion: reduce) {
	.vd-mobile-nav.is-open .vd-labo-glow { animation: none; }
}

/* 5. POPOVER RECHERCHE + DROPDOWN RÉGLAGE ---------------------------------- */
.vd-pop {
	position: absolute;
	z-index: 250; /* au-dessus de l'overlay burger (200) pour rester utilisable dans le menu mobile */
	background: var(--wp--preset--color--base);
	border: 1px solid var(--wp--preset--color--separator);
	box-shadow: 0 12px 32px rgba(0, 0, 0, 0.16);
	opacity: 0;
	transform: translateY(-8px) scale(0.98);
	pointer-events: none;
	transition: opacity var(--vd-t-base) var(--vd-ease),
		transform var(--vd-t-base) var(--vd-ease);
}
.vd-pop.is-open {
	opacity: 1;
	transform: translateY(0) scale(1);
	pointer-events: auto;
}

/* Popover recherche (pill 260×50) */
.vd-search-pop {
	right: clamp(1rem, 5vw, 2rem);
	top: calc(var(--vd-header-h) - 6px);
	width: 260px;
	border-radius: var(--vd-pill);
	padding: 0 0.5rem 0 1rem;
	display: flex;
	align-items: center;
	height: 50px;
}
.vd-search-pop input {
	flex: 1;
	border: 0;
	background: transparent;
	color: inherit;
	font: inherit;
	font-size: 1rem; /* 16px min : iOS Safari zoome sur les inputs < 16px au focus */
	outline: none; /* pas d'anneau de focus sur la recherche (choix Victor 07/06) */
}
.vd-search-pop button { flex: 0 0 auto; }

/* Dropdown réglage thème — fidèle au Figma : 72px, coins nets, bordure contrastée */
.vd-theme-menu {
	right: clamp(1rem, 5vw, 2rem);
	top: calc(var(--vd-header-h) - 6px);
	width: 72px;
	border-radius: var(--vd-radius-sm);
	border: 1px solid var(--wp--preset--color--contrast);
	box-shadow: none;
	padding: 16px 8px;
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: 16px;
}
.vd-theme-menu button {
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: 6px;
	width: 100%;
	border: 0;
	background: transparent;
	color: inherit;
	cursor: pointer;
	padding: 6px 0;
	border-radius: var(--vd-radius-md);
	font-size: 10px;
	font-weight: 600;
	letter-spacing: 0.04em;
	text-transform: uppercase;
	transition: background-color var(--vd-t-fast) var(--vd-ease);
}
.vd-theme-menu button svg { width: 24px; height: 24px; }
.vd-theme-menu button:hover { background: var(--vd-surface); }
.vd-theme-menu button[aria-checked="true"] { background: var(--vd-surface); }

/* 6. FOOTER ---------------------------------------------------------------- */
/* Reproduction au pixel près du Figma (frame 1440×215). Toujours noir pur. */
.vd-footer {
	background: var(--wp--preset--color--ink);
	color: var(--wp--preset--color--off-white);
}
.vd-footer__mobile { display: none; }

/* Bande de liens en haut : hauteur 68px, liens répartis (gaps ~93px à 1440) */
.vd-footer__nav {
	display: flex;
	flex-wrap: nowrap;
	align-items: center;
	justify-content: space-between;
	gap: 0 12px;
	min-height: 68px;
	padding: 0 20px;
	border-top: 1px solid var(--vd-footer-line);
	border-bottom: 1px solid var(--vd-footer-line);
	font-size: 12px;
	text-transform: uppercase;
	letter-spacing: 0;
	white-space: nowrap;
}
.vd-footer__nav a {
	color: var(--wp--preset--color--off-white);
	text-decoration: none;
	opacity: 0.9;
	transition: opacity var(--vd-t-fast) var(--vd-ease), color 2s ease;
}
.vd-footer__nav a:hover { opacity: 1; }
/* Hover sur une section d'article : la couleur fond doucement vers la couleur identitaire
 * de la catégorie (2s). Sélecteurs sur href pour éviter de toucher au HTML. */
.vd-footer__nav a[href*="/category/velos/"]:hover       { color: var(--wp--preset--color--velos); }
.vd-footer__nav a[href*="/category/accessoires/"]:hover { color: var(--wp--preset--color--accessoires); }
.vd-footer__nav a[href*="/category/composants/"]:hover  { color: var(--wp--preset--color--composants); }
.vd-footer__nav a[href*="/category/vetements/"]:hover   { color: var(--wp--preset--color--vetements); }
.vd-footer__nav a[href*="/category/societe/"]:hover     { color: #785FD3; /* societe sombre voulu, ≠ preset */ }

/* « LE LABO » du footer (desktop) : même clignotement que le menu burger (cycle des 5 couleurs de
 * marque avec halo), mais VOLONTAIREMENT plus discret (halo réduit 7px / alpha 0.30 au lieu de 12px / 0.60)
 * et plus lent (20s au lieu de 8s). Desktop-only par construction (la nav n'existe que dans
 * .vd-footer__desktop, masquée < breakpoint). Ciblé par href pour ne pas toucher au HTML.
 * Fond footer toujours sombre → couleur de repos = off-white (comme les autres liens). */
.vd-footer__nav a[href="/le-labo/"] {
	--vd-flabo-rest: var(--wp--preset--color--off-white);
	animation: vd-footer-labo-glow 20s ease-in-out infinite;
	will-change: color, text-shadow;
}
@keyframes vd-footer-labo-glow {
	0%, 100% { color: var(--vd-flabo-rest); text-shadow: 0 0 0 rgba(0, 0, 0, 0); }
	10% { color: var(--c-red);    text-shadow: 0 0 7px rgba(238, 42, 0, 0.30); }
	20% { color: var(--vd-flabo-rest); text-shadow: 0 0 0 rgba(0, 0, 0, 0); }
	30% { color: var(--c-amber);  text-shadow: 0 0 7px rgba(226, 146, 0, 0.30); }
	40% { color: var(--vd-flabo-rest); text-shadow: 0 0 0 rgba(0, 0, 0, 0); }
	50% { color: var(--c-green);  text-shadow: 0 0 7px rgba(0, 146, 12, 0.30); }
	60% { color: var(--vd-flabo-rest); text-shadow: 0 0 0 rgba(0, 0, 0, 0); }
	70% { color: var(--c-blue);   text-shadow: 0 0 7px rgba(0, 148, 200, 0.30); }
	80% { color: var(--vd-flabo-rest); text-shadow: 0 0 0 rgba(0, 0, 0, 0); }
	90% { color: var(--c-purple); text-shadow: 0 0 7px rgba(125, 94, 218, 0.30); }
}
@media (prefers-reduced-motion: reduce) {
	.vd-footer__nav a[href="/le-labo/"] { animation: none; }
}

/* Bloc principal : identité (gauche, 341/1440 = 23.7%) + bande dégradée (droite) */
.vd-footer__main {
	display: grid;
	grid-template-columns: minmax(340px, 23.7%) minmax(0, 1fr);
	align-items: stretch;
	min-height: 147px;
}

/* Bloc noir gauche : wordmark à 24px du haut, padding gauche 17px / droite 28px */
.vd-footer__left {
	display: flex;
	flex-direction: column;
	justify-content: flex-start;
	gap: 12px;
	padding: 24px 28px 24px 17px;
	background: var(--wp--preset--color--ink);
}
.vd-footer__brandrow {
	display: flex;
	align-items: flex-start;
	justify-content: space-between; /* © au bord droit → aligné sous le logo TikTok */
	/* PAS de gap forcé : avec space-between, un gap min faisait déborder le © au-delà
	 * du bord droit (wordmark large + bloc étroit). L'espace wordmark↔© vient du space-between. */
	gap: 8px;
}
.vd-footer__brand {
	color: #FFFFFF;
	font-weight: 700;
	font-size: 30px;
	letter-spacing: 0;
	line-height: 1;
	text-decoration: none;
	white-space: nowrap;
	display: inline-block;
}
.vd-footer__brand-text {
	display: inline-block;
}
/* Mark © à droite du wordmark : image exacte exportée du Figma (nœud « Copyright ») */
.vd-footer__mark {
	flex: 0 0 auto;
	width: 23px;
	height: 23px;
	margin-top: 6px; /* offset Figma : © à 6px sous le haut du wordmark */
	/* Le © (23px) est plus large que TikTok (18px) : aligner les bords droits laisse
	 * les CENTRES décalés de 2,5px. On nudge le © à droite pour centrer pile sous TikTok. */
	transform: translateX(2.5px);
	background-image: url(../images/footer-copyright.png);
	background-size: contain;
	background-repeat: no-repeat;
	background-position: center;
}
.vd-footer__sub {
	margin: 0;
	font-size: 12px;
	text-transform: uppercase;
	letter-spacing: 0;
	opacity: 0.95;
}
/* "World Wide Ride" à gauche, réseaux collés à droite du bloc noir */
.vd-footer__taglinerow {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 12px;
	font-size: 12px;
}
.vd-footer__tagline { opacity: 0.95; }
.vd-footer__socials {
	display: flex;
	align-items: center;
	gap: 12px;
}
.vd-footer__socials a { color: var(--wp--preset--color--off-white); display: inline-flex; }
.vd-footer__socials svg { width: 18px; height: 18px; }

/* Bande dégradée (droite) + pastilles 16px en bas à droite (14px/12px des bords) */
.vd-footer__gradient {
	position: relative;
	min-height: 147px;
	background: var(--wp--preset--gradient--grands-formats);
}
/* ============================================================
   FOOTER « 6 POINTS » — bouton + moteur d'animation (refonte 06/06, Claude design)
   Au clic, les 6 points du logo s'assemblent en un objet (vélo, roue, casque,
   pompe…), l'objet fait son geste, puis redevient le logo. Le SVG multi-parties
   est injecté dans .vd-footer__fx-img par velodisco-ui.js (données window.FX_*) ;
   la durée vient de --fx-dur (= durée du son associé). Les 10 vélos partagent les
   sons 1..10. Source : dossier « Animations logo 6 points/ ».
   ============================================================ */

/* — Bouton (position héritée : bas-droite de la bande dégradée) — */
.vd-footer__dots {
	position: absolute;
	right: 14px;
	bottom: 12px;
	line-height: 0;
}
button.vd-footer__dots {
	border: 0;
	background: transparent;
	padding: 0;
	font: inherit;
	color: inherit;
	cursor: pointer;
}
.vd-footer__dots:focus-visible { outline: 2px solid #fff; outline-offset: 4px; border-radius: var(--vd-radius-sm); }
.vd-footer__dots--sm { right: 12px; bottom: 13px; }

/* — Couleurs de marque + durée (surchargée par le JS au clic) — */
:root {
	--c-red:    #ee2a00;
	--c-blue:   #0094c8;
	--c-green:  #00920c;
	--c-amber:  #e29200;
	--c-purple: #7d5eda;
	--c-anthra: #3a3a39;
	--fx-dur:   1500ms;
}

/* — Zone d'animation (= taille du logo) — */
.vd-footer__fx-img {
	display: block;
	width: 52px;                 /* desktop */
	height: 34px;
	overflow: visible;           /* les points peuvent dépasser pendant l'assemblage */
}
.vd-footer__dots--sm .vd-footer__fx-img { width: 28px; height: 18px; }  /* footer mobile (≤900px) */

.fx-svg { width: 100%; height: 100%; display: block; overflow: visible; }

/* Les 6 points : couleurs de marque */
.fx-svg .d  { transform-box: fill-box; transform-origin: center; }
.fx-svg .d1 { fill: var(--c-red); }
.fx-svg .d2 { fill: var(--c-blue); }
.fx-svg .d3 { fill: var(--c-green); }
.fx-svg .d4 { fill: var(--c-amber); }
.fx-svg .d5 { fill: var(--c-purple); }
.fx-svg .d6 { fill: var(--c-anthra); }

/* Ossature (traits dessinés) */
.fx-svg .ln {
	fill: none;
	stroke: var(--c-anthra);
	stroke-width: 2.4;
	stroke-linecap: round;
	stroke-linejoin: round;
	opacity: 0;
}
.fx-svg .ln.draw {
	stroke-dasharray: var(--len, 120);
	stroke-dashoffset: var(--len, 120);
}
.fx-svg .fill-part { opacity: 0; transform-box: fill-box; transform-origin: center; }

/* groupes pivotants : origine = centre de la boîte */
.fx-svg .pivot { transform-box: view-box; transform-origin: 39px 25.5px; }

/* Accessibilité : on n'anime pas l'assemblage, apparition douce du logo. */
@media (prefers-reduced-motion: reduce) {
	.vd-footer__dots[class*="is-fx-"] .fx-svg * { animation: none !important; }
	.vd-footer__dots[class*="is-fx-"] .fx-svg { animation: fx-soft 360ms ease both !important; }
	.vd-footer__dots[class*="is-fx-"] .fx-svg .ln,
	.vd-footer__dots[class*="is-fx-"] .fx-svg .fill-part { opacity: 0 !important; }
}
@keyframes fx-soft { from { opacity: 0; } to { opacity: 1; } }


/* ===== Moteur (keyframes) — ex fx-keyframes.css ===== */
/* ============================================================
   FOOTER « 6 POINTS » — keyframes & règles (mode CYCLE)
   Chaque animation = ALLER-RETOUR dans var(--fx-dur) :
     0–24%  assemblage   logo  -> objet
     24–78% geste        l'objet vit (tourne, pompe, sonne…)
     78–100% retour       objet -> logo
   Tous les groupes reviennent à l'identité, les points
   regagnent la grille : on retombe exactement sur le logo.
   ============================================================ */

/* ---------- briques partagées ----------------------------- */
@keyframes fx-assemble{
  0%   { transform:none; }
  16%  { transform: translate(calc(var(--tx,0)*1.06),calc(var(--ty,0)*1.06)) scale(calc(var(--sc,1)*1.04)) rotate(var(--rot,0deg)); }
  24%  { transform: translate(var(--tx,0),var(--ty,0)) scale(var(--sc,1)) rotate(var(--rot,0deg)); }
  78%  { transform: translate(var(--tx,0),var(--ty,0)) scale(var(--sc,1)) rotate(var(--rot,0deg)); }
  100% { transform:none; }
}
@keyframes fx-draw{
  0%  { opacity:0; stroke-dashoffset:var(--len,120); }
  7%  { opacity:1; }
  24% { stroke-dashoffset:0; opacity:1; }
  80% { stroke-dashoffset:0; opacity:1; }
  100%{ stroke-dashoffset:var(--len,120); opacity:0; }
}
@keyframes fx-draw-b{
  0%  { opacity:0; stroke-dashoffset:var(--len,120); }
  14% { opacity:0; }
  20% { opacity:1; }
  38% { stroke-dashoffset:0; opacity:1; }
  78% { stroke-dashoffset:0; opacity:1; }
  100%{ stroke-dashoffset:var(--len,120); opacity:0; }
}
@keyframes fx-pop{
  0%,16%{ opacity:0; transform:scale(0); }
  26%   { opacity:1; transform:scale(1.16); }
  34%   { transform:scale(1); }
  80%   { opacity:1; transform:scale(1); }
  100%  { opacity:0; transform:scale(0); }
}

/* timing par défaut des pièces */
.vd-footer__dots[class*="is-fx-"] .fx-svg .d{
  animation: fx-assemble var(--fx-dur) cubic-bezier(.34,1.32,.5,1) both;
}
.vd-footer__dots[class*="is-fx-"] .fx-svg .ln{
  animation: fx-draw var(--fx-dur) ease both;
}
.vd-footer__dots[class*="is-fx-"] .fx-svg .ln.late{
  animation: fx-draw-b var(--fx-dur) ease both;
}
.vd-footer__dots[class*="is-fx-"] .fx-svg .fill-part{
  animation: fx-pop var(--fx-dur) cubic-bezier(.34,1.5,.5,1) both;
}

/* ============================================================
   1. ROUE ARRIÈRE (1,27 s) — tourne puis se range en logo.
   ============================================================ */
.is-fx-rouearriere .d{ --sc:0.315; }
.is-fx-rouearriere .d1{ --tx:12.3px;  --ty:5px;  }
.is-fx-rouearriere .d2{ --tx:0px;    --ty:-3.5px;}
.is-fx-rouearriere .d3{ --tx:-12.3px; --ty:5px;  }
.is-fx-rouearriere .d4{ --tx:12.3px;  --ty:-5px; }
.is-fx-rouearriere .d5{ --tx:0px;    --ty:3.5px;}
.is-fx-rouearriere .d6{ --tx:-12.3px; --ty:-5px; }
.is-fx-rouearriere .wheel{ animation: fx-spin var(--fx-dur) cubic-bezier(.2,.65,.25,1) both; }
@keyframes fx-spin{ 0%,22%{ transform:rotate(0); } 100%{ transform:rotate(720deg); } }

/* ============================================================
   2. POMPE (1,46 s) — le piston pompe puis se range.
   ============================================================ */
.is-fx-pompe .d1{ --tx:19px;  --ty:1px; --sc:0.54; }
.is-fx-pompe .d2{ --tx:0px;   --ty:-1px; --sc:0.54; }
.is-fx-pompe .d3{ --tx:-19px; --ty:1px; --sc:0.54; }
.is-fx-pompe .d4{ --tx:21px;  --ty:2px;  --sc:0.3375; }
.is-fx-pompe .d5{ --tx:9px;   --ty:-9px; --sc:0.375;  }
.is-fx-pompe .d6{ --tx:-7px;  --ty:-4px; --sc:0.315; }
.is-fx-pompe .plunger{ animation: fx-pump var(--fx-dur) cubic-bezier(.45,0,.55,1) both; }
@keyframes fx-pump{
  0%,26%{ transform:translateY(0); }
  38%{ transform:translateY(7px); } 50%{ transform:translateY(0); }
  62%{ transform:translateY(7px); } 74%{ transform:translateY(0); }
  100%{ transform:translateY(0); }
}

/* ============================================================
   3. SONNETTE (1,58 s) — oscillation amortie.
   ============================================================ */
.is-fx-sonnnette .d{ --sc:0.375; }
.is-fx-sonnnette .d1{ --tx:18px;  --ty:11px;  }
.is-fx-sonnnette .d2{ --tx:0px;   --ty:8px;  }
.is-fx-sonnnette .d3{ --tx:-18px; --ty:11px;  }
.is-fx-sonnnette .d4{ --tx:22px;  --ty:-11px; }
.is-fx-sonnnette .d5{ --tx:5px;   --ty:-11px; }
.is-fx-sonnnette .d6{ --tx:-27px; --ty:-4px; --sc:0.3; }
.is-fx-sonnnette .bell{
  transform-box:view-box; transform-origin:39px 14px;
  animation: fx-rock var(--fx-dur) ease-out both;
}
@keyframes fx-rock{
  0%,26%{ transform:rotate(0); }
  36%{ transform:rotate(13deg); } 48%{ transform:rotate(-10deg); }
  60%{ transform:rotate(7deg); }  70%{ transform:rotate(-4deg); }
  80%{ transform:rotate(2deg); }  90%,100%{ transform:rotate(0); }
}
.is-fx-sonnnette .ring{
  fill:none; stroke:var(--c-anthra); stroke-width:2; stroke-linecap:round;
  transform-box:fill-box; transform-origin:center;
  animation: fx-ringwave var(--fx-dur) ease both;
}
@keyframes fx-ringwave{
  0%,32%{ opacity:0; transform:scale(.6); }
  40%{ opacity:.85; transform:scale(1); }
  56%{ opacity:0; transform:scale(1.25); }
  100%{ opacity:0; }
}

/* ============================================================
   4. PHARE (1,06 s) — le faisceau s'allume puis s'éteint.
   ============================================================ */
.is-fx-phare .d1{ --tx:21px; --ty:9px;  --sc:0.525; }
.is-fx-phare .d4{ --tx:21px; --ty:-9px; --sc:0.525; }
.is-fx-phare .d2{ --tx:0px;  --ty:9px;  --sc:0.6; }
.is-fx-phare .d5{ --tx:0px;  --ty:-9px; --sc:0.6; }
.is-fx-phare .d3{ --tx:-21px;--ty:9px;  --sc:0.4125; }
.is-fx-phare .d6{ --tx:-21px;--ty:-9px; --sc:0.4125; }
.is-fx-phare .lamp{ animation: fx-lampglow var(--fx-dur) ease both; }
@keyframes fx-lampglow{
  0%,28%{ filter:none; }
  48%{ filter:drop-shadow(0 0 5px rgba(226,146,0,.9)); }
  80%{ filter:drop-shadow(0 0 3px rgba(226,146,0,.6)); }
  100%{ filter:none; }
}
.is-fx-phare .beam{ transform-box:view-box; transform-origin:40px 25.5px; }
.is-fx-phare .beamfill{
  fill:var(--c-amber); transform-box:view-box; transform-origin:40px 25.5px;
  animation: fx-beam var(--fx-dur) ease both;
}
@keyframes fx-beam{
  0%,28%{ opacity:0; transform:scaleX(0); }
  46%{ opacity:.55; transform:scaleX(1.05); }
  60%{ opacity:.38; transform:scaleX(1); }
  80%{ opacity:.38; transform:scaleX(1); }
  100%{ opacity:0; transform:scaleX(0); }
}

/* ============================================================
   5. GARMIN (1,22 s) — l'écran s'allume puis s'éteint.
   ============================================================ */
.is-fx-garmin .d{ --sc:0.345; }
.is-fx-garmin .d1{ --tx:21px; --ty:3px;  }
.is-fx-garmin .d2{ --tx:0px;  --ty:3px;  }
.is-fx-garmin .d3{ --tx:-21px;--ty:3px;  }
.is-fx-garmin .d4{ --tx:21px; --ty:-9px; }
.is-fx-garmin .d5{ --tx:0px;  --ty:-9px; --sc:0.495; }
.is-fx-garmin .d6{ --tx:-21px;--ty:-9px; }
.is-fx-garmin .screen{ animation: fx-draw var(--fx-dur) ease both, fx-screenglow var(--fx-dur) ease both; }
@keyframes fx-screenglow{
  0%,28%{ filter:none; }
  46%{ filter:drop-shadow(0 0 4px rgba(0,148,200,.85)); }
  80%{ filter:drop-shadow(0 0 2px rgba(0,148,200,.5)); }
  100%{ filter:none; }
}

/* ============================================================
   6. VOLANT / KLAXON (2,23 s) — braque, klaxonne, se range.
   ============================================================ */
.is-fx-klaxon .d{ --sc:0.3; }
.is-fx-klaxon .d1{ --tx:12.3px;  --ty:5px;  }
.is-fx-klaxon .d2{ --tx:0px;    --ty:-3.5px;}
.is-fx-klaxon .d3{ --tx:-12.3px; --ty:5px;  }
.is-fx-klaxon .d4{ --tx:12.3px;  --ty:-5px; }
.is-fx-klaxon .d5{ --tx:0px;    --ty:3.5px;}
.is-fx-klaxon .d6{ --tx:-12.3px; --ty:-5px; }
.is-fx-klaxon .wheelg{ animation: fx-steer var(--fx-dur) ease-in-out both; }
@keyframes fx-steer{
  0%,24%{ transform:rotate(0); }
  40%{ transform:rotate(-26deg); } 58%{ transform:rotate(22deg); }
  72%{ transform:rotate(0); } 100%{ transform:rotate(0); }
}
.is-fx-klaxon .horn{
  fill:var(--c-anthra); transform-box:fill-box; transform-origin:center;
  animation: fx-honk var(--fx-dur) ease both;
}
@keyframes fx-honk{
  0%,60%{ opacity:0; transform:scale(0); }
  66%{ opacity:1; transform:scale(1.3); }
  72%{ transform:scale(1); }
  78%{ transform:scale(1.25); }
  84%{ transform:scale(1); }
  100%{ opacity:0; transform:scale(0); }
}

/* ============================================================
   7. CASQUE (1,62 s) — se pose, rebondit, se redéploie en logo.
   ============================================================ */
.is-fx-casque .d{ --sc:0.315; }
.is-fx-casque .d1{ --tx:14px; --ty:12px;  }
.is-fx-casque .d2{ --tx:0px;  --ty:10px;  }
.is-fx-casque .d3{ --tx:-14px;--ty:12px;  }
.is-fx-casque .d4{ --tx:21px; --ty:-12px; }
.is-fx-casque .d5{ --tx:0px;  --ty:-15px;}
.is-fx-casque .d6{ --tx:-21px;--ty:-12px; }
.is-fx-casque .helmet{ transform-box:view-box; transform-origin:39px 33px; animation: fx-drop var(--fx-dur) cubic-bezier(.3,1.25,.5,1) both; }
@keyframes fx-drop{
  0%{ transform:translateY(-14px); }
  24%{ transform:translateY(0); }
  36%{ transform:translateY(-3px); } 46%{ transform:translateY(0); }
  100%{ transform:translateY(0); }
}

/* ============================================================
   8. BOULE DISCO (4,27 s) — tourne et scintille longtemps.
   ============================================================ */
.is-fx-disco .d{ --sc:0.225; }
.is-fx-disco .d1{ --tx:18.3px; --ty:11px;  }
.is-fx-disco .d2{ --tx:0px;    --ty:6px;  }
.is-fx-disco .d3{ --tx:-18.3px;--ty:11px;  }
.is-fx-disco .d4{ --tx:18.3px; --ty:-6px; }
.is-fx-disco .d5{ --tx:0px;    --ty:-1px;  }
.is-fx-disco .d6{ --tx:-18.3px;--ty:-6px; }
.is-fx-disco .ball{ animation: fx-discospin var(--fx-dur) cubic-bezier(.3,0,.4,1) both; }
@keyframes fx-discospin{ 0%,14%{ transform:rotate(0); } 86%{ transform:rotate(690deg);} 100%{ transform:rotate(720deg); } }
.is-fx-disco .facet{ fill:#fff; opacity:0; transform-box:fill-box; transform-origin:center;
  animation: fx-twinkle calc(var(--fx-dur)/5) ease-in-out 3; }
.is-fx-disco .facet.f2{ animation-delay: calc(var(--fx-dur)/14); }
.is-fx-disco .facet.f3{ animation-delay: calc(var(--fx-dur)/7); }
@keyframes fx-twinkle{ 0%,100%{ opacity:0; transform:scale(.4);} 50%{ opacity:.95; transform:scale(1);} }
.is-fx-disco .sparks{ transform-box:view-box; transform-origin:39px 28px; }
.is-fx-disco .spark{ stroke:var(--c-amber); stroke-width:1.6; stroke-linecap:round; opacity:0;
  transform-box:fill-box; transform-origin:center;
  animation: fx-sparkle calc(var(--fx-dur)/3.5) ease-in-out 3; }
.is-fx-disco .spark.k2{ stroke:var(--c-blue);  animation-delay: calc(var(--fx-dur)/10); }
.is-fx-disco .spark.k3{ stroke:var(--c-purple);animation-delay: calc(var(--fx-dur)/5); }
@keyframes fx-sparkle{ 0%,100%{ opacity:0; transform:scale(.5);} 40%{ opacity:1; transform:scale(1.1);} 60%{ opacity:.4; } }

/* ===== Keyframes complémentaires — ex fx-keyframes2.css ===== */
/* ============================================================
   FOOTER « 6 POINTS » — keyframes complémentaires (mode CYCLE)
   Objets restants + système vélo. Chaque geste revient à
   l'identité à 100% pour retomber sur le logo.
   ============================================================ */

/* assemblage de référence, repris quand on combine 2 animations */
/* (identique au .d générique : translate/scale/rotate + retour) */

/* ---- CASSETTE : rotation crantée (ratchet), finit à 360° ---- */
.is-fx-cassette .cassg{ animation: fx-ratchet var(--fx-dur) linear both; }
@keyframes fx-ratchet{
  0%,24%{ transform:rotate(0); }
  34%{ transform:rotate(60deg); }  40%{ transform:rotate(60deg); }
  48%{ transform:rotate(135deg); } 54%{ transform:rotate(135deg); }
  62%{ transform:rotate(215deg); } 68%{ transform:rotate(215deg); }
  76%{ transform:rotate(300deg); } 82%{ transform:rotate(300deg); }
  100%{ transform:rotate(360deg); }
}

/* ---- PANNEAU : surgit du sol + léger balancement ---- */
.is-fx-panneau .signpost{ animation: fx-signrise var(--fx-dur) cubic-bezier(.3,1.2,.5,1) both; }
@keyframes fx-signrise{
  0%{ transform:translateY(11px) rotate(0); }
  24%{ transform:translateY(0) rotate(0); }
  38%{ transform:translateY(0) rotate(5deg); }
  52%{ transform:rotate(-3deg); }
  64%{ transform:rotate(1.5deg); }
  74%,100%{ transform:rotate(0) translateY(0); }
}

/* ---- CHAÎNE : pendule amorti ---- */
.is-fx-chain .chaing{ animation: fx-swing var(--fx-dur) ease-out both; }
@keyframes fx-swing{
  0%,24%{ transform:rotate(0); }
  36%{ transform:rotate(11deg); } 50%{ transform:rotate(-8deg); }
  62%{ transform:rotate(5deg); }  74%{ transform:rotate(-2deg); }
  84%,100%{ transform:rotate(0); }
}

/* ---- VESTE : flottement dans le vent ---- */
.is-fx-veste .jacket{ animation: fx-flutter var(--fx-dur) ease-in-out both; }
@keyframes fx-flutter{
  0%,24%{ transform:skewX(0) scaleX(1); }
  38%{ transform:skewX(6deg) scaleX(.98); }
  52%{ transform:skewX(-5deg); }
  66%{ transform:skewX(3deg); }
  78%,100%{ transform:skewX(0) scaleX(1); }
}

/* ---- ARCEAU : se plante dans le sol avec rebond ---- */
.is-fx-arceau .arc{ animation: fx-plant var(--fx-dur) cubic-bezier(.3,1.3,.5,1) both; }
@keyframes fx-plant{
  0%{ transform:translateY(-15px); }
  24%{ transform:translateY(0); }
  34%{ transform:translateY(-4px); } 44%{ transform:translateY(0); }
  52%{ transform:translateY(-1.5px); } 60%,100%{ transform:translateY(0); }
}

/* ---- MONTAGNE : le soleil (d4) rayonne ---- */
.is-fx-jumpp .sun{
  animation: fx-assemble var(--fx-dur) cubic-bezier(.34,1.32,.5,1) both,
             fx-sunpulse var(--fx-dur) ease both;
}
@keyframes fx-sunpulse{
  0%,30%{ filter:none; }
  50%{ filter:drop-shadow(0 0 5px rgba(226,146,0,.9)); }
  80%{ filter:drop-shadow(0 0 2px rgba(226,146,0,.5)); }
  100%{ filter:none; }
}

/* ---- GUIDON DE COURSE : prise en main (rotation douce) ---- */
.is-fx-course .hbar{ animation: fx-grip var(--fx-dur) ease-in-out both; }
@keyframes fx-grip{
  0%,26%{ transform:rotate(0); }
  42%{ transform:rotate(-4deg); } 58%{ transform:rotate(3deg); }
  72%{ transform:rotate(-1.5deg); } 82%,100%{ transform:rotate(0); }
}

/* ---- BATTERIE : les segments se chargent de bas en haut ---- */
.is-fx-batterie .s1{ animation: fx-assemble var(--fx-dur) cubic-bezier(.34,1.32,.5,1) both, fx-fill1 var(--fx-dur) ease both; }
.is-fx-batterie .s2{ animation: fx-assemble var(--fx-dur) cubic-bezier(.34,1.32,.5,1) both, fx-fill2 var(--fx-dur) ease both; }
.is-fx-batterie .s3{ animation: fx-assemble var(--fx-dur) cubic-bezier(.34,1.32,.5,1) both, fx-fill3 var(--fx-dur) ease both; }
.is-fx-batterie .s4{ animation: fx-assemble var(--fx-dur) cubic-bezier(.34,1.32,.5,1) both, fx-fill4 var(--fx-dur) ease both; }
@keyframes fx-fill1{ 0%,30%{opacity:.22} 40%{opacity:1} 100%{opacity:1} }
@keyframes fx-fill2{ 0%,42%{opacity:.22} 52%{opacity:1} 100%{opacity:1} }
@keyframes fx-fill3{ 0%,52%{opacity:.22} 62%{opacity:1} 100%{opacity:1} }
@keyframes fx-fill4{ 0%,62%{opacity:.22} 72%{opacity:1} 100%{opacity:1} }

/* ---- CHAMBRE À AIR : le boudin se dégonfle puis se regonfle ---- */
.is-fx-crevaison .tube{ animation: fx-deflate var(--fx-dur) ease-in-out both; }
.is-fx-crevaison .tubering{ stroke-width:3.6; }
@keyframes fx-deflate{
  0%,40%{ transform:scale(1); }
  50%{ transform:scale(.92,1.05); }
  60%{ transform:scale(1.05,.86); }
  70%{ transform:scale(.85,.96); }
  80%{ transform:scale(.95); }
  100%{ transform:scale(1); }
}
.is-fx-crevaison .puff{
  fill:none; stroke:var(--c-amber); stroke-width:1.6; stroke-linecap:round; opacity:0;
  transform-box:fill-box; transform-origin:center;
  animation: fx-puffline var(--fx-dur) ease both;
}
.is-fx-crevaison .p2{ animation-delay: calc(var(--fx-dur)*.04); }
.is-fx-crevaison .p3{ animation-delay: calc(var(--fx-dur)*.07); }
@keyframes fx-puffline{
  0%,50%{ opacity:0; transform:scale(.5); }
  60%{ opacity:1; transform:scale(1.2); }
  74%{ opacity:0; transform:scale(1.7); }
  100%{ opacity:0; }
}

/* ============================================================
   VÉLOS — gestes partagés (roues + caisse)
   ============================================================ */
.vd-footer__dots[class*="is-fx-velib"] .bw,
.vd-footer__dots[class*="is-fx-velo_"] .bw{
  animation: bike-spin var(--fx-dur) cubic-bezier(.22,.6,.3,1) both;
}
@keyframes bike-spin{ 0%,22%{ transform:rotate(0); } 100%{ transform:rotate(720deg); } }

.vd-footer__dots[class*="is-fx-velib"] .bike,
.vd-footer__dots[class*="is-fx-velo_"] .bike{
  animation: bike-bob var(--fx-dur) ease-in-out both;
}
@keyframes bike-bob{
  0%,24%{ transform:translate(0,0); }
  40%{ transform:translate(-2px,-1.5px); }
  56%{ transform:translate(0,0); }
  72%{ transform:translate(1px,-1px); }
  100%{ transform:translate(0,0); }
}
.vd-footer__dots[class*="is-fx-"] .fx-svg .bikehop{
  animation: bike-hop var(--fx-dur) cubic-bezier(.3,1.2,.5,1) both;
}
@keyframes bike-hop{
  0%,28%{ transform:translateY(0) rotate(0); }
  42%{ transform:translateY(-9px) rotate(-7deg); }
  54%{ transform:translateY(0) rotate(0); }
  64%{ transform:translateY(-4px); } 72%{ transform:translateY(0); }
  100%{ transform:translateY(0); }
}


@media (max-width: 900px) {
	/* Footer : on bascule en version MOBILE dès que la nav desktop ne tient plus
	 * sur une seule ligne (≤900px), au lieu de la laisser passer sur deux lignes. */
	.vd-footer__desktop { display: none; }
	.vd-footer__mobile { display: block; }
	.vd-footer__mobile .vd-footer__brand { font-size: clamp(24px, 7.2vw, 30px); }
}

/* ---- Footer mobile (≤720px) : layout dédié, calé sur le Figma 375×176 ---- */
.vd-footer__m-top { padding: 17px 18px 16px 20px; }
.vd-footer__m-row {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 12px;
}
.vd-footer__brandwrap { display: inline-flex; align-items: flex-start; min-width: 0; }
.vd-footer__mark--sup {
	width: 14px;
	height: 14px;
	margin-top: 1px;
	margin-left: 3px;
}
.vd-footer__soc { color: #F5F5F0; display: inline-flex; flex: 0 0 auto; }
.vd-footer__soc svg { width: 18px; height: 18px; }
.vd-footer__m-top .vd-footer__sub { margin: 13px 0; }
.vd-footer__m-gradient {
	position: relative;
	height: 44px;
	background: var(--wp--preset--gradient--grands-formats);
}
/* (sizing --sm déplacé dans la section FOOTER « 6 POINTS » ci-dessus) */


/* 7. CARTES & IMAGES (tracé catégorie) ------------------------------------- */
/*
 * Tracé 0.5px INSIDE en couleur de catégorie sur les images d'article.
 * On utilise box-shadow inset (n'ajoute pas à la taille = équivalent INSIDE).
 */
/* Tracé dessiné PAR-DESSUS l'image via ::after (un box-shadow inset sur le lien
 * lui-même est masqué par l'image qui occupe 100% de la vignette). */
.vd-img-stroke { position: relative; }
.vd-img-stroke::after {
	content: "";
	position: absolute;
	inset: 0;
	box-shadow: inset 0 0 0 0.5px var(--vd-stroke-color, var(--wp--preset--color--separator));
	pointer-events: none;
	z-index: 1;
}
.vd-img-stroke--velos { --vd-stroke-color: var(--wp--preset--color--velos); }
.vd-img-stroke--accessoires { --vd-stroke-color: var(--wp--preset--color--accessoires); }
.vd-img-stroke--composants { --vd-stroke-color: var(--wp--preset--color--composants); }
.vd-img-stroke--vetements { --vd-stroke-color: var(--wp--preset--color--vetements); }
.vd-img-stroke--societe { --vd-stroke-color: var(--wp--preset--color--societe); }
/* Grands Formats : tracé en DÉGRADÉ arc-en-ciel (un box-shadow ne peut pas être un dégradé →
 * technique du masque : le ::after a un padding = épaisseur, fond dégradé, on évide l'intérieur). */
.vd-img-stroke--grands-formats::after {
	box-shadow: none;
	padding: 0.5px;
	background: var(--wp--preset--gradient--grands-formats);
	-webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
	-webkit-mask-composite: xor;
	        mask-composite: exclude;
}

/* Étiquette de catégorie (core/post-terms, style "vd-tag") */
.is-style-vd-tag,
.is-style-vd-tag a,
.vd-term {
	text-transform: uppercase;
	font-weight: 600;
	letter-spacing: 0.04em;
	text-decoration: none;
}
/* Couleur de catégorie : .vd-nav__link--X (nav) / .vd-term--X (étiquettes) /
 * .vd-c-X (nav mobile) / .vd-img-stroke--X (trait image) — composants distincts,
 * tous basés sur les presets theme.json. Les .vd-term--X (texte d'étiquette) utilisent
 * une nuance assombrie (--vd-cat-text-X) pour le contraste WCAG sur fond clair. */
.vd-term--velos { color: var(--vd-cat-text-velos); }
.vd-term--accessoires { color: var(--vd-cat-text-accessoires); }
.vd-term--composants { color: var(--vd-cat-text-composants); }
.vd-term--vetements { color: var(--vd-cat-text-vetements); }
.vd-term--societe { color: var(--vd-cat-text-societe); }
.vd-term--grands-formats {
	background: var(--wp--preset--gradient--grands-formats);
	-webkit-background-clip: text;
	background-clip: text;
	-webkit-text-fill-color: transparent;
	color: transparent;
}

/* Image avec tracé catégorie (style de bloc "vd-stroke") */
.is-style-vd-stroke img {
	box-shadow: inset 0 0 0 0.5px var(--wp--preset--color--separator);
}

/* Bouton outline → pill, suit la couleur du texte */
.wp-block-button.is-style-outline .wp-block-button__link {
	border-radius: var(--vd-pill);
	border-width: 1px;
	background: transparent;
	color: var(--wp--preset--color--contrast);
	border-color: currentColor;
	transition: background-color var(--vd-t-base) var(--vd-ease),
		color var(--vd-t-base) var(--vd-ease);
}
.wp-block-button.is-style-outline .wp-block-button__link:hover {
	background: var(--wp--preset--color--contrast);
	color: var(--wp--preset--color--base);
}

/* Largeur de lecture confortable pour le corps d'article */
.vd-single :where(p, ul, ol, h2, h3, blockquote, figure) {
	margin-inline: auto;
}
.vd-single h2 { margin-top: var(--wp--preset--spacing--50); }

/* 8. ANIMATIONS ------------------------------------------------------------ */
/* Reveal au défilement : appliquer .vd-reveal sur un bloc, le JS ajoute .is-in. */
.vd-reveal {
	opacity: 0;
	transform: translateY(20px);
	transition: opacity var(--vd-t-slow) var(--vd-ease),
		transform var(--vd-t-slow) var(--vd-ease);
}
.vd-reveal.is-in {
	opacity: 1;
	transform: none;
}

/* Survol générique des cartes / images */
.vd-hover-rise {
	transition: transform var(--vd-t-base) var(--vd-ease);
}
.vd-hover-rise:hover { transform: translateY(-4px); }

.vd-hover-zoom { overflow: hidden; }
.vd-hover-zoom img {
	transition: transform var(--vd-t-slow) var(--vd-ease);
}
.vd-hover-zoom:hover img { transform: scale(1.04); }

/* 9b. HOME (page d'accueil — relevé Figma 1440) ---------------------------- */
/* ---- Spacing des wrappers <main> par type de page ----
 * Avant v1.10.0 (audit), ces valeurs étaient en INLINE style sur le main
 * dans chaque template (`style="padding-top:...;padding-bottom:..."`), ce qui
 * empêchait tout override CSS. Migré ici pour pouvoir ajuster sans toucher
 * aux templates. */
/* Utilitaire d'accessibilité : visuellement masqué mais lu par les lecteurs
 * d'écran et indexable. Utilisé pour les <h1> de Home/Actu/Recherche/Section/
 * 404 — pages dont le titre visible est porté par la zone de contenu mais
 * dont la sémantique (SEO + a11y) requiert un H1 unique par page. */
.vd-sr-only {
	position: absolute !important;
	width: 1px; height: 1px;
	padding: 0; margin: -1px;
	overflow: hidden; clip: rect(0,0,0,0);
	white-space: nowrap; border: 0;
}

.vd-main--home { max-width: none; padding-inline: 0; margin-top: 0; padding-top: 0; padding-bottom: 0; }
.vd-main--actu,
.vd-main--section,
.vd-main--search,
.vd-contact,
.vd-legal { padding-top: 0; padding-bottom: var(--wp--preset--spacing--60); }
.vd-main--page { padding-top: var(--wp--preset--spacing--50); padding-bottom: var(--wp--preset--spacing--60); }
.vd-single { padding-top: var(--wp--preset--spacing--40); padding-bottom: var(--wp--preset--spacing--60); }

/* Mobile-first : display:block par défaut → si iOS Safari ne réévalue pas les media
 * queries immédiatement après une rotation portrait↔paysage, l'état de fallback est
 * toujours correct (block), jamais le grid 3 colonnes qui déborde sur un viewport étroit. */
.vd-home {
	display: block;
	max-width: 640px;      /* centre le contenu sur tablette (560-880px) */
	margin: 0 auto;
	margin-bottom: 0;      /* annule le margin-bottom WP (is-layout-flow) avant .vd-gf */
	margin-block-end: 0;
	padding-inline: 0;
	padding-top: 0;
}

/* Desktop (≥881px) : grid 3 colonnes. Avec un min-width, même si iOS rate la
 * réévaluation à la rotation, il reste en display:block (la valeur par défaut ci-dessus). */
@media (min-width: 881px) {
	.vd-home {
		max-width: 1410px;
		padding-inline: clamp(16px, 2vw, 24px);
		display: grid;
		/* Colonnes latérales FLUIDES : elles rétrécissent avec la fenêtre (donc les images
		 * de TENDANCES aussi), tout en restant plafonnées aux tailles Figma (286 / 374) sur
		 * grand écran et avec un plancher avant la bascule en pile (≤880px). */
		grid-template-columns: clamp(180px, 20vw, 286px) minmax(0, 1fr) clamp(280px, 26vw, 374px);
		column-gap: clamp(24px, 3vw, 44px);
		align-items: start;   /* chaque colonne garde sa hauteur naturelle ; le JS aligne ensuite */
		padding-top: 0;
	}
}

/* Titres de section : Inter 600 15px majuscules */
.vd-sectitle {
	font-family: var(--wp--preset--font-family--inter, "Inter", sans-serif);
	font-weight: 600;
	font-size: 15px;
	line-height: 18px;
	letter-spacing: 0;
	text-transform: uppercase;
	color: var(--wp--preset--color--contrast);
	margin: 0 0 1rem;
}

/* Étiquette catégorie : Inter 400 15px, couleur de catégorie (classes vd-term--*) */
.vd-tag {
	display: inline-block;
	font-family: var(--wp--preset--font-family--inter, "Inter", sans-serif);
	font-weight: 400;
	font-size: 15px;
	line-height: 18px;
	letter-spacing: 0;
	text-transform: uppercase;
	text-decoration: none;
	margin: 0 0 0.4rem;
}

/* Excerpt gris + date */
.vd-card__excerpt {
	font-family: var(--wp--preset--font-family--inter, "Inter", sans-serif);
	font-weight: 400;
	font-size: 14px;
	line-height: 18px;
	color: var(--vd-text-muted);
	margin: 0.5rem 0 0;
}
.vd-card__date {
	display: block;
	text-align: right;
	font-size: 12px;
	line-height: 15px;
	color: var(--wp--preset--color--contrast);
	margin-top: 0.6rem;
	opacity: 0.85;
}

/* Vignettes (image liée + tracé catégorie) */
.vd-thumb__img { width: 100%; height: 100%; object-fit: cover; display: block; }
.vd-thumb__ph { display: block; width: 100%; height: 100%; background: var(--vd-surface); }
.vd-aune__img, .vd-card__img, .vd-tcard__img, .vd-gfcard__img {
	display: block; overflow: hidden; position: relative;
}
.vd-aune__img { aspect-ratio: 660 / 352; }
.vd-card__img, .vd-tcard__img { aspect-ratio: 320 / 192; }
.vd-gfcard__img { aspect-ratio: 271 / 176; }

/* Titres d'articles (serif Merriweather) */
.vd-aune__title, .vd-card__title, .vd-tcard__title, .vd-gfcard__title, .vd-frais__title {
	display: block;
	color: var(--wp--preset--color--contrast);
	text-decoration: none;
	font-weight: 700;
}
.vd-aune__title  { font-size: clamp(26px, 2.5vw, 36px); line-height: 1.25; margin: 0.5rem 0; }
.vd-card__title  { font-size: clamp(20px, 1.7vw, 24px); line-height: 1.25; margin: 0.5rem 0 0; }
.vd-tcard__title { font-size: clamp(20px, 1.5vw, 24px); line-height: 1.25; margin: 0.5rem 0 0; }
.vd-gfcard__title{ font-size: 16px; line-height: 20px; margin: 0.4rem 0 0; }

/* ---- À LA UNE ---- */
.vd-aune { margin-bottom: clamp(2rem, 4vw, 3rem); }
.vd-aune .vd-tag { margin-top: 0.5rem; }

/* ---- DERNIERS ARTICLES (grille 2×2) ---- */
.vd-derniers__grid {
	display: grid;
	grid-template-columns: repeat(2, minmax(0, 1fr));
	column-gap: 21px;
	row-gap: clamp(1.5rem, 3vw, 2.25rem);
}
/* Desktop : grille 2×2 → on n'affiche que 4 cartes (le 5e article est réservé au mobile). */
.vd-derniers__grid > .vd-card:nth-child(n+5) { display: none; }
.vd-card__title { font-family: var(--vd-serif); }

/* Lien « Mentions légales » : présent dans le DOM mais visible uniquement en mobile. */
.vd-home-mentions { display: none; }

/* Bouton "Tous les articles" en bas de Derniers articles (home) */
.vd-derniers__all {
	display: block;
	text-align: center;
	margin-top: 24px;
	padding: 10px 24px;
	font-family: var(--wp--preset--font-family--inter, "Inter", sans-serif);
	font-weight: 600;
	font-size: 12px;
	line-height: 15px;
	letter-spacing: 0.04em;
	text-transform: uppercase;
	text-decoration: none;
	color: var(--wp--preset--color--contrast);
	border: 1.5px solid currentColor;
	transition: background 0.15s, color 0.15s;
}
.vd-derniers__all:hover,
.vd-derniers__all:focus-visible {
	background: var(--wp--preset--color--contrast);
	color: var(--wp--preset--color--base);
}

/* ---- Colonnes : espaces haut ET bas INTERNES → les bordures verticales touchent
 * la ligne du header (haut) et la ligne des Grands Formats (bas), sans gap. ---- */
/* padding-top = MÊME token que l'inset latéral du header (.vd-header__inner
 * padding-inline: clamp(16px,1.9vw,27px)) → la marge au-dessus des titres
 * TOUT FRAIS / À LA UNE / TENDANCES est cohérente avec les marges du header.
 * (était clamp(1.5rem,3vw,2.5rem) ≈ 40px ; réduit à ≈27px le 07/06.) */
.vd-col { padding-top: clamp(16px, 1.9vw, 27px); padding-bottom: 0; }

/* ---- Colonnes latérales : séparateurs verticaux ---- */
.vd-col--frais { border-right: 1px solid var(--wp--preset--color--separator); padding-right: clamp(16px, 2vw, 40px); overflow: hidden; }
.vd-col--tend  { border-left: 1px solid var(--wp--preset--color--separator); padding-left: clamp(16px, 2vw, 40px); overflow: hidden; }

/* ---- Widget « Le Labo » (bas de la colonne Tendances) ---- */
/* Marge d'air sous le widget. PADDING (pas margin) : toujours compté dans
   tend.scrollHeight (= hauteur naturelle mesurée par vdSyncFrais), donc jamais
   clippé par l'overflow:hidden de la colonne. Sur une page section au centre
   court, le widget tombe au bas de la colonne → cette marge l'écarte de la
   séparatrice. Sur la home (colonne étirée) c'est invisible. */
.vd-labo { padding-bottom: 24px; }
.vd-labo__frame { width: 100%; height: 452px; border: 0; overflow: hidden; display: block; background: transparent; border-radius: var(--vd-radius-lg); }

/* ---- TOUT FRAIS (liste compacte) ---- */
.vd-frais__list { list-style: none; margin: 0; padding: 0; }
.vd-frais__item { padding: 0.55rem 0; }
.vd-frais__time {
	display: block;
	font-size: 12px; line-height: 15px;
	color: var(--wp--preset--color--contrast);
	opacity: 0.6;
	margin-bottom: 0.15rem;
}
.vd-frais__title { font-size: 12px; line-height: 15px; }

/* Survol (et focus clavier) des titres TOUT FRAIS : la couleur fond vers un dégradé
 * multicolore TRÈS FONCÉ (clin d'œil subtil aux couleurs de marque). Le dégradé est
 * clippé sur le texte en permanence (invisible car couvert par la couleur pleine) ;
 * au survol on rend la couleur transparente → le dégradé se révèle EN DOUCEUR grâce
 * à la transition (plus élégant qu'un changement de couleur sec). */
.vd-frais__title {
	background-image: linear-gradient(90deg, #b8401a, #1a8030, #0f7ba0, #b07e0a);
	-webkit-background-clip: text;
	background-clip: text;
	transition: color var(--vd-t-base) var(--vd-ease), -webkit-text-fill-color var(--vd-t-base) var(--vd-ease);
}
.vd-frais__title:hover,
.vd-frais__title:focus-visible {
	color: transparent;
	-webkit-text-fill-color: transparent;
}
/* Mode sombre : un dégradé atténué mais CLAIR (un « très foncé » serait invisible sur
 * fond noir) → effet subtil et lisible sur fond sombre. */
[data-theme="dark"] .vd-frais__title {
	background-image: linear-gradient(90deg, #d99a86, #9fc9ab, #9cc3d4, #d8c692);
}

/* Indice de clic TRÈS subtil sur les grands titres d'articles : un léger zoom au
 * survol et au focus clavier (×1.01, à peine perceptible), ancré à gauche.
 * (TOUT FRAIS a déjà son dégradé comme signal, on ne l'alourdit pas.) */
.vd-aune__title, .vd-card__title, .vd-tcard__title, .vd-gfcard__title {
	transform-origin: left center;
	transition: transform var(--vd-t-base) var(--vd-ease);
}
.vd-aune__title:hover,  .vd-aune__title:focus-visible,
.vd-card__title:hover,  .vd-card__title:focus-visible,
.vd-tcard__title:hover, .vd-tcard__title:focus-visible,
.vd-gfcard__title:hover, .vd-gfcard__title:focus-visible {
	transform: scale(1.01);
}

/* ---- TENDANCES ---- */
.vd-tcard { margin-bottom: clamp(1.75rem, 3vw, 2.5rem); }

/* ---- GRANDS FORMATS (pleine largeur, 4 colonnes) ----
 * Espacements verticaux symétriques au pixel près :
 *   A = ligne → titre  = padding-top  = 16px
 *   B = titre → carte  = .vd-gf__head margin-bottom = 16px
 *   C = carte → footer = .vd-main--home padding-bottom = 0  + le margin-top
 *       naturel du footer = 16px (compensé plus bas)
 */
.vd-gf {
	max-width: 1410px;
	margin: 0 auto;
	margin-block-start: 0; /* annule le block-gap WP (is-layout-flow) au-dessus de la séparatrice */
	padding-inline: clamp(16px, 2vw, 24px);
	border-top: 1px solid var(--wp--preset--color--separator);
	padding-top: 12px;
}
.vd-gf__head {
	display: grid;
	grid-template-columns: auto 1fr auto;
	align-items: baseline;
	gap: 1rem;
	margin-bottom: 0;
}
/* Le H2 .vd-sectitle a un margin-top par défaut (~48px) qui casse la symétrie.
 * Reset à 0 ici : seul le padding-top de .vd-gf compte. */
.vd-gf__head .vd-sectitle { margin-top: 0; }
/* Note : le padding-bottom: 0 de .vd-main--home est désormais dans le bloc
 * groupé `.vd-main--*` au-dessus (l. ~975) avec les autres types de pages. */
.vd-gf__sub { font-size: 16px; line-height: 19px; color: var(--vd-text-muted); margin: 0; }
.vd-gf__all { justify-self: end; font-weight: 600; font-size: 15px; text-decoration: none; white-space: nowrap; }
.vd-gf__grid {
	display: grid;
	grid-template-columns: repeat(4, minmax(0, 1fr));
	gap: clamp(1rem, 2vw, 28px);
}
.vd-gfcard .vd-tag {
	font-size: 12px; line-height: 15px;
	background: var(--wp--preset--gradient--grands-formats);
	-webkit-background-clip: text; background-clip: text;
	-webkit-text-fill-color: transparent; color: transparent;
}

/* Single article GF — la pastille `.vd-gf01__badge` (état v1.11.4).
 * display: block + width: fit-content : sort la pastille du flux inline et
 * supprime les 5px de décalage baseline laissés par l'inline-block AUTONOME.
 * padding-top/bottom: 0 + line-height 30px : pas de creux interne, hauteur
 * de capsule conservée. vertical-align: top : ceinture-bretelles. */
body[class*="vd-cat--grands-formats"] .vd-gf01__badge {
	display: block;
	width: fit-content;
	padding-top: 0;
	padding-bottom: 0;
	line-height: 30px;
	vertical-align: top;
}
/* Home GF card — espacements verticaux INTERNES uniformes (13px partout, valeur
 * de référence visée par Victor : gap tag↔titre v1.11.1). Les autres cartes
 * du site gardent leurs marges propres. */
.vd-gfcard .vd-tag         { margin: 13px 0 0; }
.vd-gfcard__title          { margin: 13px 0 0; }
.vd-gfcard .vd-card__excerpt { margin: 13px 0 0; }
.vd-gfcard .vd-card__date    { margin: 13px 0 0; }

.vd-empty { color: var(--vd-text-muted); font-size: 14px; }

/* ---- Responsive Home : design MOBILE (Figma « Home — Mobile », base 375) ----
 * Bascule abaissée de 1080 à 880px : on garde le 3 colonnes plus longtemps (les colonnes
 * latérales fluides ci-dessus rétrécissent jusque-là). Le header, lui, passe en burger à
 * 1080px (média query séparée plus bas) — donc entre 880 et 1080 : header burger + Home 3 col. */
@media (max-width: 880px) {
	/* Pile verticale pleine largeur (images edge-to-edge), centrée sur tablette. */
	/* Sections absentes du Home mobile */
	.vd-col--frais,
	.vd-col--tend,
	.vd-gf { display: none; }

	.vd-col { padding: 0; }
	.vd-col--center { display: block; }
	/* Page de section : grille du centre en 1 colonne (préfixe .vd-section = priorité). */
	.vd-section .vd-section__grid { grid-template-columns: 1fr; row-gap: 0; }
	.vd-section .vd-card + .vd-card { margin-top: 16px; padding-top: 16px; }
	/* En 1 colonne, le bandeau (nom de section + « Derniers articles ») devient le 1er
	   élément sous le header → on ajoute de l'air au-dessus pour qu'il ne soit pas collé
	   (à ≤560px la règle mobile remet padding:20px sur tous les côtés). */
	.vd-section .vd-section__head { padding: 24px 20px 0; }

	/* Filet de catégorie : en haut et en bas de l'image */
	.vd-home .vd-img-stroke::after { display: none; }
	.vd-aune__img.vd-img-stroke,
	.vd-card__img.vd-img-stroke { border-top: 1px solid var(--vd-stroke-color); border-bottom: 1px solid var(--vd-stroke-color); }
	/* Grands Formats : filets dégradés en haut et en bas */
	.vd-home .vd-img-stroke--grands-formats { border-top: 0; border-bottom: 0; }
	.vd-home .vd-img-stroke--grands-formats::after {
		display: block; inset: 0 0 auto 0; height: 1px; padding: 0;
		-webkit-mask: none; mask: none;
		background: var(--wp--preset--gradient--grands-formats);
	}
	.vd-home .vd-img-stroke--grands-formats::before {
		content: ''; display: block; position: absolute; inset: auto 0 0 0; height: 1px;
		background: var(--wp--preset--gradient--grands-formats);
	}

	/* Labels de section */
	.vd-home .vd-sectitle { padding: 20px 20px 0; margin: 0 0 8px; }
	.vd-aune > .vd-sectitle { font-size: 16px; font-weight: 700; }

	/* ===== Carte À LA UNE (lead) ===== */
	.vd-aune {
		margin-bottom: 0;
		padding-bottom: 20px;
		border-bottom: 1px solid var(--wp--preset--color--separator);
	}
	.vd-aune > .vd-tag {
		padding-inline: 20px;
		margin: 0 0 8px;
		font-size: 11px; line-height: 13px; font-weight: 600;
	}
	.vd-aune__title {
		padding-inline: 20px;
		margin: 0 0 20px; /* + d'air avant l'image de la une (Figma : 12px, jugé trop serré) */
		font-size: 17px; line-height: 21px;
	}
	.vd-aune__img { aspect-ratio: 375 / 210; }
	.vd-aune__foot { padding: 12px 20px 0; }
	.vd-aune__foot .vd-card__excerpt { margin: 0 0 8px; }
	.vd-aune__foot .vd-card__date { margin: 0; font-size: 11px; }

	/* ===== DERNIERS ARTICLES (pile de cartes) ===== */
	/* Dégradé de fond catégorie : couleur en haut → transparent en bas */
	.vd-card:has(.vd-term--velos)       { --vd-card-bg: linear-gradient(180deg, rgba(219,63,12,0.07) 0%, transparent 100%); }
	.vd-card:has(.vd-term--accessoires) { --vd-card-bg: linear-gradient(180deg, rgba(27,143,41,0.07) 0%, transparent 100%); }
	.vd-card:has(.vd-term--composants)  { --vd-card-bg: linear-gradient(180deg, rgba(214,150,0,0.07) 0%, transparent 100%); }
	.vd-card:has(.vd-term--vetements)   { --vd-card-bg: linear-gradient(180deg, rgba(0,145,194,0.07) 0%, transparent 100%); }
	.vd-card:has(.vd-term--societe)     { --vd-card-bg: linear-gradient(180deg, rgba(47,0,216,0.04) 0%, transparent 100%); }
	.vd-card { background-image: var(--vd-card-bg, none); }
	.vd-derniers > .vd-sectitle { margin-bottom: 20px; }
	.vd-derniers__grid { grid-template-columns: 1fr; gap: 0; padding-top: 0; }
	.vd-derniers .vd-card:first-child { padding-top: 16px; }
	.vd-derniers .vd-card + .vd-card { margin-top: 16px; padding-top: 16px; }
	.vd-derniers__grid > .vd-card:nth-child(n+5) { display: flex; } /* on montre le 5e en mobile */
	.vd-derniers .vd-card { display: flex; flex-direction: column; }
	.vd-derniers .vd-card > .vd-tag { order: 1; padding-inline: 20px; margin: 0 0 8px;  font-size: 11px; line-height: 13px; font-weight: 600; }
	.vd-derniers .vd-card__title    { order: 2; padding-inline: 20px; margin: 0 0 12px; font-size: 17px; line-height: 21px; }
	.vd-derniers .vd-card__img      { order: 3; aspect-ratio: 375 / 200; }
	.vd-derniers .vd-card__excerpt  { order: 4; padding-inline: 20px; margin: 12px 0 8px; }
	.vd-derniers .vd-card__date     { order: 5; padding-inline: 20px; margin: 0; font-size: 11px; }

	/* ===== Lien Mentions légales (mobile uniquement) ===== */
	.vd-home-mentions {
		display: block;
		text-align: center;
		padding: 22px 20px;
		font-family: var(--wp--preset--font-family--inter, "Inter", sans-serif);
		font-weight: 600;
		font-size: 10px;
		line-height: 12px;
		text-transform: uppercase;
		text-decoration: underline;
		color: var(--wp--preset--color--contrast);
	}
	.vd-derniers__all {
		display: block;
		text-align: center;
		margin: 20px 20px 0;
		padding: 11px 20px;
		font-size: 11px;
		line-height: 13px;
	}
}
@media (max-width: 560px) {
	.vd-derniers__grid { grid-template-columns: 1fr; }
	.vd-gf__grid { grid-template-columns: 1fr; }
	.vd-gf__head { grid-template-columns: 1fr; }
	.vd-gf__all { justify-self: start; }
}

/* 9d. ACTU (Page Actu — flux des derniers articles, grille 3 colonnes) ----- */
/* Relevé Figma « Page Actu - Ordi » (1440) : 3 colonnes de 320px, gap 127px,
 * marges latérales 113px ; cartes identiques à la Home. */
.vd-actu {
	max-width: 1262px;              /* 1214 (3×320 + 2×127) + 2×24 de padding */
	margin-inline: auto;
	padding-inline: clamp(20px, 5vw, 24px);
}

/* En-tête de flux : « Actu  Tout frais » à gauche, « Derniers articles » à droite */
.vd-actu__head {
	display: flex;
	align-items: baseline;
	gap: 18px;
	margin: clamp(28px, 4vw, 38px) 0 clamp(36px, 5vw, 56px);
	font-family: var(--wp--preset--font-family--inter, "Inter", sans-serif);
	font-size: 15px;
	line-height: 18px;
	color: var(--wp--preset--color--contrast);
}
.vd-actu__crumb { font-weight: 400; }
.vd-actu__tab   { font-weight: 600; }
.vd-actu__tab--right { margin-left: auto; font-weight: 600; }
.vd-actu__m-right { display: none; } /* libellé « Tout est là » : mobile uniquement */

/* Grille 3 colonnes (320px à 1440, gap 127px), fluide en dessous */
.vd-actu__grid {
	display: grid;
	grid-template-columns: repeat(3, minmax(0, 1fr));
	column-gap: clamp(28px, 8.8vw, 127px);
	row-gap: clamp(2rem, 3vw, 36px);
}

/* Réglages propres au flux Actu (Figma) — sans toucher aux cartes de la Home :
 * extrait 16/19, date 12/15 noire pleine opacité, écart image→étiquette 23px. */
.vd-actu .vd-card__excerpt { font-size: 16px; line-height: 19px; }
.vd-actu .vd-card__date { font-size: 12px; line-height: 15px; opacity: 1; }
.vd-actu .vd-card .vd-tag { display: inline-block; margin-top: clamp(14px, 1.6vw, 23px); }

/* Même écart image→étiquette de catégorie sur les cartes des pages de SECTION
 * (sinon « VÉLOS » colle à l'image, surtout en 1 colonne à largeur réduite).
 * Placé AVANT le bloc @media ≤560 (mise en page mobile catégorie-au-dessus,
 * margin:0) → la règle mobile reste prioritaire et n'est pas affectée. */
.vd-section .vd-card .vd-tag { display: inline-block; margin-top: clamp(14px, 1.6vw, 23px); }

/* Pagination : [1] 2 3 →  (1 actif = rond plein ; chiffres Inter Thin), à droite */
.vd-actu__pagination {
	display: flex;
	justify-content: flex-end;
	align-items: center;
	gap: 14px;
	margin-top: clamp(2rem, 4vw, 45px);
	font-family: var(--wp--preset--font-family--inter, "Inter", sans-serif);
}
.vd-page {
	font-weight: 100;
	font-size: 25px;
	line-height: 30px;
	color: var(--wp--preset--color--contrast);
	text-decoration: none;
	min-width: 1ch;
	text-align: center;
	transition: opacity var(--vd-t-fast) var(--vd-ease);
}
.vd-page:hover { opacity: 0.6; }
.vd-page.is-active {
	font-weight: 600;
	width: 28px;
	height: 28px;
	border-radius: 50%;
	background: var(--wp--preset--color--contrast);
	color: var(--wp--preset--color--base);
	display: inline-flex;
	align-items: center;
	justify-content: center;
}
.vd-page.is-active:hover { opacity: 1; }
.vd-page--next {
	font-weight: 400;
	font-size: 22px;
	width: 21px;
	height: 21px;
	display: inline-flex;
	align-items: center;
	justify-content: center;
}

/* Intermédiaire (tablette) : 2 colonnes, cartes style desktop. */
@media (max-width: 780px) {
	.vd-actu__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); column-gap: clamp(20px, 4vw, 44px); }
}

/* MOBILE (relevé Figma « Page Actu — Mobile », 375) : pile verticale de cartes,
 * catégorie + titre AU-DESSUS, image pleine largeur (filet couleur en haut), extrait + date. */
@media (max-width: 560px) {
	.vd-actu { max-width: none; padding-inline: 0; margin-block-start: 0; } /* annule le block-gap WP (le <main is-layout-flow> ajoute un margin-block-start à .vd-actu, 2e enfant après le <h1 sr-only> absolu) */
	.vd-main--actu { padding-top: 0; margin-top: 0; margin-block-start: 0; } /* main collé au header, comme .vd-main--home. Avec ce qui précède : seul reste le padding 20px haut+bas du head → « Actu » centré */

	/* En-tête : « ACTU » (gras 16) à gauche, « Tout est là » à droite ; divider en bas. */
	.vd-actu__head {
		margin: 0;
		padding: 20px;
		gap: 8px;
		border-bottom: 1px solid var(--wp--preset--color--separator);
	}
	.vd-actu__crumb { font-weight: 700; font-size: 16px; line-height: 19px; }
	.vd-actu__tab, .vd-actu__tab--right { display: none; }
	.vd-actu__m-right { display: inline; margin-left: auto; font-weight: 400; font-size: 13px; line-height: 16px; }

	/* Pile de cartes (gap 24px), avec un peu d'air sous le divider de l'en-tête */
	.vd-actu__grid { display: flex; flex-direction: column; gap: 0; padding-top: 0; }

	/* Carte = catégorie + titre, puis image pleine largeur, puis extrait + date (ordre flex).
	   Style MUTUALISÉ entre la Page Actu et les pages de section (même maquette mobile). */
	:is(.vd-actu, .vd-section) .vd-card { display: flex; flex-direction: column; }
	:is(.vd-actu, .vd-section) .vd-card:first-child { padding-top: 16px; }
	:is(.vd-actu, .vd-section) .vd-card .vd-tag   { order: 1; padding-inline: 20px; margin: 0; font-size: 11px; line-height: 13px; }
	:is(.vd-actu, .vd-section) .vd-card + .vd-card { margin-top: 16px; padding-top: 16px; }
	:is(.vd-actu, .vd-section) .vd-card__title    { order: 2; padding-inline: 20px; margin: 8px 0 0; font-size: 17px; line-height: 21px; }
	:is(.vd-actu, .vd-section) .vd-card__img      { order: 3; margin: 12px 0 0; aspect-ratio: 375 / 200; }
	:is(.vd-actu, .vd-section) .vd-card__img::after { display: none; }   /* on enlève le contour inset desktop */
	:is(.vd-actu, .vd-section) .vd-card__img { border-top: 1px solid var(--vd-stroke-color, var(--wp--preset--color--separator)); border-bottom: 1px solid var(--vd-stroke-color, var(--wp--preset--color--separator)); } /* filets couleur en haut et en bas */
	/* Grands Formats : filets dégradés en haut et en bas */
	:is(.vd-actu, .vd-section) .vd-card__img.vd-img-stroke--grands-formats { border-top: 0; border-bottom: 0; }
	:is(.vd-actu, .vd-section) .vd-card__img.vd-img-stroke--grands-formats::after {
		display: block; inset: 0 0 auto 0; height: 1px; padding: 0;
		-webkit-mask: none; mask: none;
		background: var(--wp--preset--gradient--grands-formats);
	}
	:is(.vd-actu, .vd-section) .vd-card__img.vd-img-stroke--grands-formats::before {
		content: ''; display: block; position: absolute; inset: auto 0 0 0; height: 1px;
		background: var(--wp--preset--gradient--grands-formats);
	}
	:is(.vd-actu, .vd-section) .vd-card__excerpt  { order: 4; padding-inline: 20px; margin: 12px 0 0; font-size: 13px; line-height: 16px; }
	:is(.vd-actu, .vd-section) .vd-card__date     { order: 5; padding-inline: 20px; margin: 8px 0 0; font-size: 11px; line-height: 13px; text-align: left; color: var(--vd-text-soft); }

	/* Pagination centrée (Actu + Section) */
	.vd-actu__pagination, .vd-section__pagination { justify-content: center; }

	/* Pages de section — en-tête mobile : nom de section (gras 16, couleur catégorie) +
	   « Derniers articles » (13) ; pile de cartes avec air sous le divider.
	   Préfixe .vd-section pour battre les règles desktop écrites plus bas dans le fichier. */
	.vd-section .vd-section__head {
		margin: 0;
		padding: 20px;
		border-bottom: 1px solid var(--wp--preset--color--separator);
	}
	.vd-section .vd-section__head .vd-section__name { font-weight: 700; font-size: 16px; line-height: 19px; margin: 0; } /* h2 (4.13) : 0-3-0 > desktop 0-2-0 */
	.vd-section .vd-section__label { font-weight: 400; font-size: 13px; line-height: 16px; }
	.vd-section .vd-section__grid  { display: flex; flex-direction: column; gap: 0; padding-top: 0; }
	/* Mode sombre : dégradé plus intense (fond foncé = opacité plus haute) */
	[data-theme="dark"] .vd-card:has(.vd-term--velos)       { --vd-card-bg: linear-gradient(180deg, rgba(219,63,12,0.22) 0%, transparent 100%); }
	[data-theme="dark"] .vd-card:has(.vd-term--accessoires) { --vd-card-bg: linear-gradient(180deg, rgba(27,143,41,0.22) 0%, transparent 100%); }
	[data-theme="dark"] .vd-card:has(.vd-term--composants)  { --vd-card-bg: linear-gradient(180deg, rgba(214,150,0,0.22) 0%, transparent 100%); }
	[data-theme="dark"] .vd-card:has(.vd-term--vetements)   { --vd-card-bg: linear-gradient(180deg, rgba(0,145,194,0.22) 0%, transparent 100%); }
	[data-theme="dark"] .vd-card:has(.vd-term--societe)     { --vd-card-bg: linear-gradient(180deg, rgba(47,0,216,0.22) 0%, transparent 100%); }
}

/* 9e. SECTION (archive de catégorie — grille de la Home filtrée) ----------- */
/* En-tête du centre : nom de section (couleur de catégorie) à gauche, « Derniers articles » à droite. */
.vd-section__head {
	display: flex;
	align-items: baseline;
	justify-content: space-between;
	gap: 1rem;
	margin: 0 0 clamp(1.25rem, 2.5vw, 1.75rem);
	font-family: var(--wp--preset--font-family--inter, "Inter", sans-serif);
	font-size: 15px;
	line-height: 18px;
}
/* .vd-section__name est un <h2> (titre de catégorie, a11y/SEO — 4.13). On neutralise
 * explicitement la taille/marge h2 de theme.json (0-1-0) avec une spécificité 0-2-0
 * pour garder l'apparence d'origine (15px, sans marge). Couleur via vd-term--{slug}. */
.vd-section__head .vd-section__name { font-weight: 400; letter-spacing: 0; font-size: 15px; line-height: 18px; margin: 0; }
.vd-section__label { font-weight: 600; color: var(--wp--preset--color--contrast); white-space: nowrap; }

/* Grille du centre : 2 colonnes, TOUTES les cartes (pas de plafond comme la Home). */
.vd-section__grid {
	display: grid;
	grid-template-columns: repeat(2, minmax(0, 1fr));
	column-gap: 21px;
	row-gap: clamp(1.5rem, 3vw, 2.25rem);
}

/* Pagination du centre (réutilise .vd-actu__pagination + .vd-page, alignée à droite). */
.vd-section__pagination { margin-top: clamp(2rem, 4vw, 3rem); }

/* 9f. RECHERCHE (résultats + état « Aucun résultat ») --------------------- */
/* Le conteneur porte aussi la classe .vd-actu → réutilise la grille 3 colonnes,
 * les cartes (desktop + mobile) et la pagination de la Page Actu. */
.vd-search__form {
	position: relative;
	max-width: 960px;
	margin: clamp(24px, 4vw, 38px) auto clamp(20px, 3vw, 28px);
}
.vd-search__icon {
	position: absolute; left: 18px; top: 50%; transform: translateY(-50%);
	width: 20px; height: 20px; pointer-events: none;
	color: var(--wp--preset--color--contrast); opacity: 0.6;
}
.vd-search__form input {
	width: 100%; height: 56px; box-sizing: border-box;
	padding: 0 20px 0 50px;
	border: 1px solid var(--vd-border-soft); border-radius: var(--vd-radius-md);
	background: var(--wp--preset--color--base);
	color: var(--wp--preset--color--contrast);
	font-family: var(--wp--preset--font-family--inter, "Inter", sans-serif);
	font-size: 18px; line-height: 22px;
}
[data-theme="dark"] .vd-search__form input { border-color: var(--wp--preset--color--separator); }

.vd-search__head {
	text-align: center;
	font-family: var(--wp--preset--font-family--inter, "Inter", sans-serif);
	font-weight: 600; font-size: 15px; line-height: 18px;
	text-transform: uppercase; letter-spacing: 0;
	margin: 0 0 clamp(1.5rem, 3vw, 2.25rem);
	color: var(--wp--preset--color--contrast);
}

/* État « Aucun résultat » (Figma « Page Aucun Résultat ») : grand « Rien trouvé »,
 * dessin du vélo crevé (placeholder), sous-titre, bouton retour accueil. */
.vd-search__empty { text-align: center; padding: clamp(2rem, 6vw, 4rem) 20px clamp(3rem, 8vw, 5rem); }
.vd-search__empty-big {
	font-family: var(--vd-serif); font-weight: 700;
	font-size: clamp(56px, 12vw, 100px); line-height: 1.1;
	margin: 0 0 clamp(1.5rem, 4vw, 2.5rem);
	color: var(--wp--preset--color--contrast);
}
/* Page 404 (Figma « Page 404 ») : même gabarit que l'état vide mais le grand nombre
 * est en Merriweather 200px (vs 100px pour « Rien trouvé »). */
.vd-404 .vd-search__empty-big { font-size: clamp(90px, 22vw, 200px); }
/* Dessin du vélo : SVG externe (assets/images/velo-creve.svg, tracés noirs sur fond
 * transparent) utilisé comme MASQUE → peint avec la couleur « contrast » pour s'adapter
 * au dark/light, exactement comme l'ancien placeholder en currentColor. Ratio Figma 320×160. */
.vd-search__empty-img {
	display: block;
	width: clamp(200px, 30vw, 320px);
	aspect-ratio: 320 / 160;
	margin: 0 auto clamp(1.5rem, 4vw, 2.5rem);
	background-color: var(--wp--preset--color--contrast);
	-webkit-mask: url(../images/velo-creve.svg) center / contain no-repeat;
	mask: url(../images/velo-creve.svg) center / contain no-repeat;
}
.vd-search__empty-sub {
	font-family: var(--vd-serif); font-weight: 700;
	font-size: clamp(22px, 3vw, 36px); line-height: 1.25;
	margin: 0 0 clamp(1.5rem, 3vw, 2rem);
	color: var(--wp--preset--color--contrast);
}
.vd-search__empty-btn {
	display: inline-block;
	padding: 18px 28px;
	border: 1px solid var(--wp--preset--color--contrast);
	border-radius: 6px;
	font-family: var(--wp--preset--font-family--inter, "Inter", sans-serif);
	font-weight: 700; font-size: 13px; line-height: 16px;
	text-transform: uppercase; letter-spacing: 0.02em; text-decoration: none;
	color: var(--wp--preset--color--contrast);
	transition: background-color var(--vd-t-base) var(--vd-ease), color var(--vd-t-base) var(--vd-ease);
}
.vd-search__empty-btn:hover { background: var(--wp--preset--color--contrast); color: var(--wp--preset--color--base); }

/* Mobile : marge latérale pour le champ + l'en-tête (les cartes restent edge-to-edge).
 * Le champ utilise une MARGE (pas un padding) pour que l'icône loupe, positionnée dans
 * le form, reste alignée à l'intérieur du champ. */
@media (max-width: 560px) {
	.vd-search__form { margin-inline: 20px; }
	.vd-search__head { padding-inline: 20px; box-sizing: border-box; }
}

/* 9g. PAGE TEXTE / LÉGALE (Mentions légales, et autres pages de prose) -------
 * Gabarit page-mentions-legales.html : titre Merriweather centré + colonne de
 * texte éditable (post-content) à 960px. Couleurs via « contrast » → dark/light. */
.vd-legal {
	max-width: 960px;
	margin-inline: auto;
	padding-inline: clamp(20px, 5vw, 24px);
	box-sizing: border-box;
}
.vd-legal > .wp-block-post-title {
	font-family: var(--vd-serif); font-weight: 700;
	font-size: clamp(34px, 6vw, 64px); line-height: 1.25;
	text-align: center;
	color: var(--wp--preset--color--contrast);
	margin: clamp(2.5rem, 7vw, 4.5rem) 0 clamp(2rem, 5vw, 3.5rem);
}
/* Sous-titres de section (Figma : Inter 700 14px majuscules) — quel que soit le niveau. */
.vd-legal .wp-block-post-content :is(h2, h3, h4) {
	font-family: var(--wp--preset--font-family--inter, "Inter", sans-serif);
	font-weight: 700; font-size: 14px; line-height: 17px;
	text-transform: uppercase; letter-spacing: 0.02em;
	color: var(--wp--preset--color--contrast);
	margin: clamp(1.75rem, 4vw, 2.5rem) 0 0.5rem;
}
.vd-legal .wp-block-post-content :is(h2, h3, h4):first-child { margin-top: 0; }
.vd-legal .wp-block-post-content :is(p, li) {
	font-family: var(--wp--preset--font-family--inter, "Inter", sans-serif);
	font-weight: 400; font-size: 14px; line-height: 1.6;
	color: var(--wp--preset--color--contrast);
	margin: 0 0 0.75rem;
}
.vd-legal .wp-block-post-content ul,
.vd-legal .wp-block-post-content ol { margin: 0 0 0.75rem 1.25rem; padding: 0; }
.vd-legal .wp-block-post-content a { color: inherit; text-decoration: underline; text-underline-offset: 2px; }

/* 9h. PAGE CONTACT (Figma « Page Contact - Ordi ») -------------------------
 * Grand titre « CONTACT » Inter 700 + formulaire 459px centré, labels colorés
 * par catégorie. Handler côté serveur = bloc velodisco/contact (inc/contact.php). */
.vd-contact { text-align: center; }
.vd-contact > .wp-block-post-title {
	font-family: var(--wp--preset--font-family--inter, "Inter", sans-serif);
	font-weight: 700; text-transform: uppercase; letter-spacing: -0.01em;
	font-size: clamp(56px, 18vw, 200px); line-height: 1.1;
	color: var(--wp--preset--color--contrast);
	margin: clamp(2rem, 6vw, 4.5rem) 0 clamp(2rem, 5vw, 3.5rem);
}
.vd-contact__wrap { max-width: 459px; margin-inline: auto; padding-inline: 20px; box-sizing: border-box; text-align: left; }

.vd-field { margin: 0 0 1.5rem; }
.vd-field__label {
	display: block; margin: 0 0 8px;
	font-family: var(--wp--preset--font-family--inter, "Inter", sans-serif);
	font-weight: 600; font-size: 11px; line-height: 13px;
	text-transform: uppercase; letter-spacing: 0.02em;
}
.vd-field__input {
	width: 100%; box-sizing: border-box;
	height: 48px; padding: 0 14px;
	border: 1px solid var(--vd-border-soft); border-radius: 4px;
	background: var(--wp--preset--color--base);
	color: var(--wp--preset--color--contrast);
	font-family: var(--wp--preset--font-family--inter, "Inter", sans-serif);
	font-size: 15px; line-height: 1.4;
	transition: border-color var(--vd-t-fast) var(--vd-ease);
}
.vd-field__textarea { height: 140px; padding: 12px 14px; resize: vertical; }
.vd-field__input:focus { outline: none; border-color: var(--wp--preset--color--contrast); }
[data-theme="dark"] .vd-field__input { border-color: var(--wp--preset--color--separator); }

.vd-contact__btn {
	display: inline-block;
	min-width: 140px; height: 44px; padding: 0 24px;
	border: 1px solid var(--wp--preset--color--contrast); border-radius: 6px;
	background: transparent; cursor: pointer;
	font-family: var(--wp--preset--font-family--inter, "Inter", sans-serif);
	font-weight: 700; font-size: 13px; line-height: 16px;
	text-transform: uppercase; letter-spacing: 0.02em;
	color: var(--wp--preset--color--contrast);
	transition: background-color var(--vd-t-base) var(--vd-ease), color var(--vd-t-base) var(--vd-ease);
}
.vd-contact__btn:hover { background: var(--wp--preset--color--contrast); color: var(--wp--preset--color--base); }

/* Messages de retour */
.vd-contact__notice { margin: 0 0 1.5rem; padding: 12px 16px; border-radius: var(--vd-radius-md); font-size: 14px; line-height: 1.5; }
.vd-contact__notice p { margin: 0 0 0.25rem; }
.vd-contact__notice p:last-child { margin: 0; }
.vd-contact__notice--err { border: 1px solid var(--wp--preset--color--velos); color: var(--wp--preset--color--contrast); }

/* Honeypot : invisible aux humains, hors flux, non focusable visuellement */
.vd-hp { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }

/* 9i. BANDEAU DE CONSENTEMENT COOKIES (Figma « Cookie Banner ») -------------
 * Barre fixe en bas. Adaptatif dark/light via les tokens base/contrast (le Figma
 * correspond au mode clair). GA4 n'est chargé par le JS qu'après « Tout accepter ». */
.vd-consent {
	position: fixed; left: 0; right: 0; bottom: 0; z-index: 300;
	background: var(--wp--preset--color--base);
	border-top: 1px solid var(--wp--preset--color--separator);
	box-shadow: 0 -4px 20px rgba(0, 0, 0, 0.15);
	padding: clamp(16px, 2vw, 24px) clamp(20px, 4vw, 48px);
}
.vd-consent[hidden] { display: none; }
.vd-consent__inner {
	max-width: 1440px; margin: 0 auto;
	display: flex; align-items: center; gap: clamp(16px, 3vw, 40px); flex-wrap: wrap;
}
.vd-consent__text { flex: 1 1 380px; }
.vd-consent__title {
	font-family: var(--wp--preset--font-family--inter, "Inter", sans-serif);
	font-weight: 600; font-size: 18px; line-height: 22px;
	margin: 0 0 6px; color: var(--wp--preset--color--contrast);
}
.vd-consent__desc {
	font-family: var(--wp--preset--font-family--inter, "Inter", sans-serif);
	font-weight: 400; font-size: 14px; line-height: 1.4;
	margin: 0; color: var(--wp--preset--color--contrast); opacity: 0.65;
}
.vd-consent__actions { display: flex; gap: 12px; flex: 0 0 auto; flex-wrap: wrap; }
.vd-consent__btn {
	min-width: 140px; height: 44px; padding: 0 18px; box-sizing: border-box;
	border-radius: 22px; cursor: pointer;
	border: 1px solid var(--wp--preset--color--contrast);
	font-family: var(--wp--preset--font-family--inter, "Inter", sans-serif);
	font-weight: 600; font-size: 13px; line-height: 16px;
	transition: opacity var(--vd-t-fast) var(--vd-ease),
		background-color var(--vd-t-base) var(--vd-ease), color var(--vd-t-base) var(--vd-ease);
}
.vd-consent__btn--ghost { background: transparent; color: var(--wp--preset--color--contrast); }
.vd-consent__btn--ghost:hover { background: var(--vd-surface); }
.vd-consent__btn--solid { background: var(--wp--preset--color--contrast); color: var(--wp--preset--color--base); }
.vd-consent__btn--solid:hover { opacity: 0.85; }

.vd-consent__prefs {
	max-width: 1440px; margin: 16px auto 0;
	border-top: 1px solid var(--wp--preset--color--separator); padding-top: 8px;
}
.vd-consent__prefs[hidden] { display: none; }
.vd-consent__pref {
	display: flex; align-items: flex-start; justify-content: space-between;
	gap: 16px; padding: 12px 0;
}
.vd-consent__pref-txt {
	font-family: var(--wp--preset--font-family--inter, "Inter", sans-serif);
	font-size: 14px; color: var(--wp--preset--color--contrast);
}
.vd-consent__pref-txt strong { display: block; font-weight: 600; margin-bottom: 2px; }
.vd-consent__pref-txt span { font-size: 13px; opacity: 0.65; }
.vd-consent__pref input { width: 20px; height: 20px; flex: 0 0 auto; accent-color: var(--wp--preset--color--contrast); }
.vd-consent__prefs-actions { margin-top: 8px; }

/* Lien « Gérer les cookies » (footer) : masqué tant que le JS n'a pas confirmé
 * qu'un bandeau existe (= GA4 configuré). */
[data-consent-reopen][hidden] { display: none; }

/* Lien « Gérer les cookies » en bas de la page Mentions légales (rouvre le bandeau).
 * Bouton stylé comme un lien discret de la prose légale. */
.vd-legal__cookies-row { margin-top: clamp(1.5rem, 3vw, 2.25rem); }
.vd-legal__cookies {
	font-family: var(--wp--preset--font-family--inter, "Inter", sans-serif);
	font-size: 14px; line-height: 1.6;
	color: var(--wp--preset--color--contrast);
	background: none; border: 0; padding: 0; cursor: pointer;
	text-decoration: underline; text-underline-offset: 2px;
}
.vd-legal__cookies:hover { opacity: 0.7; }

@media (max-width: 560px) {
	.vd-consent__inner { flex-direction: column; align-items: stretch; gap: 16px; }
	/* En colonne, flex-basis 380px deviendrait une HAUTEUR imposée au texte (grand
	 * vide avant les boutons) → on laisse le bloc texte se dimensionner à son contenu. */
	.vd-consent__text { flex: 0 0 auto; }
	.vd-consent__actions { flex-direction: column; }
	.vd-consent__btn { width: 100%; min-width: 0; height: 42px; border-radius: 21px; }
	/* Ordre mobile (cf. Figma) : Tout accepter, puis Tout refuser, puis Personnaliser. */
	.vd-consent [data-consent="accept"] { order: 1; }
	.vd-consent [data-consent="deny"]   { order: 2; }
	.vd-consent [data-consent="custom"] { order: 3; }
}

/* État de confirmation (après envoi) : coche tracée à la main + message + bouton.
 * Remplace le formulaire ; le grand titre « CONTACT » est masqué dans cet état. */
.vd-contact:has(.vd-contact__confirm) > .wp-block-post-title { display: none; }
.vd-contact__confirm {
	text-align: center;
	padding: clamp(2.5rem, 8vw, 6rem) 20px clamp(2rem, 5vw, 3rem);
	display: flex; flex-direction: column; align-items: center;
}
.vd-contact__confirm .vd-search__empty-sub { margin-top: clamp(1.5rem, 4vw, 2.5rem); }
.vd-contact__confirm .vd-search__empty-btn { margin-top: clamp(1.25rem, 3vw, 2rem); }

/* La coche : cercle 120px puis coche, dessinés au trait via stroke-dashoffset.
 * pathLength="1" normalise la longueur → dasharray/offset = 1, animés vers 0. */
.vd-check { width: 120px; height: 120px; display: block; color: var(--wp--preset--color--contrast); }
.vd-check__circle, .vd-check__tick {
	fill: none;
	/* pathLength=1 → tiret de 1 (= tracé entier) + trou de 2 (plus grand que le
	 * tracé) et départ décalé à 1.02 : aucune extrémité de tiret ne tombe sur le
	 * tracé → pas de point parasite avant l'animation. */
	stroke-dasharray: 1 2; stroke-dashoffset: 1.02;
}
.vd-check__circle { animation: vd-trace 0.9s var(--vd-ease) 0.15s forwards; }
.vd-check__tick   { animation: vd-trace 0.45s var(--vd-ease) 0.95s forwards; }
@keyframes vd-trace { to { stroke-dashoffset: 0; } }

/* Accessibilité : pas d'animation si l'utilisateur la refuse → coche affichée d'emblée. */
@media (prefers-reduced-motion: reduce) {
	.vd-check__circle, .vd-check__tick { animation: none; stroke-dashoffset: 0; }
}

/* 9c. ARTICLE (single / Blog Page) ---------------------------------------- */
.vd-single { padding-inline: clamp(20px, 5vw, 24px); }

/* Étiquette catégorie : centrée sous le header (GF = gradient, autres = couleur) */
.vd-single__cat { text-align: center; margin: 0 0 0.75rem; }
.vd-single__cat a { font-weight: 600; text-decoration: none; letter-spacing: 0; }
.vd-single__cat .vd-term--velos { color: var(--wp--preset--color--velos); }
.vd-single__cat .vd-term--accessoires { color: var(--wp--preset--color--accessoires); }
.vd-single__cat .vd-term--composants { color: var(--wp--preset--color--composants); }
.vd-single__cat .vd-term--vetements { color: var(--wp--preset--color--vetements); }
.vd-single__cat .vd-term--societe { color: var(--wp--preset--color--societe); }
.vd-single__cat .vd-term--grands-formats {
	background: var(--wp--preset--gradient--grands-formats);
	-webkit-background-clip: text; background-clip: text;
	-webkit-text-fill-color: transparent; color: transparent;
}

/* Titre : Merriweather gras, aligné à gauche */
.vd-single__title { font-family: var(--vd-serif); font-weight: 700; text-align: left; }

/* Date : alignée à gauche, NOIR (#000) en clair, off-white en sombre */
.vd-single__date { text-align: left; color: #000000; }
[data-theme="dark"] .vd-single__date { color: var(--wp--preset--color--off-white, #F5F5F0); }

/* Couleur de catégorie partagée (pour tracés d'images), posée sur le body */
body[class*="vd-cat--velos"]       { --vd-cat-color: var(--wp--preset--color--velos); }
body[class*="vd-cat--accessoires"] { --vd-cat-color: var(--wp--preset--color--accessoires); }
body[class*="vd-cat--composants"]  { --vd-cat-color: var(--wp--preset--color--composants); }
body[class*="vd-cat--vetements"]   { --vd-cat-color: var(--wp--preset--color--vetements); }
body[class*="vd-cat--societe"]     { --vd-cat-color: var(--wp--preset--color--societe); }

/* Images de l'article (toutes les images du corps) : coins CARRÉS + tracé 1px
 * de la couleur de catégorie (dégradé pour Grands Formats). */
.vd-single__body .wp-block-image img { border-radius: 0; display: block; vertical-align: bottom; width: 100%; height: auto; }

/* IMAGES DU CORPS : une <figure> WordPress place la <figcaption> À L'INTÉRIEUR. Pour que le
 * tracé épouse SEULEMENT la photo (et pas la légende), on passe la figure en GRILLE : image
 * en cellule (1,1), légende en cellule (2,1), et le ::after (le tracé) placé dans la MÊME
 * cellule que l'image → il couvre exactement la box de l'image, avec OU sans légende.
 * Plus robuste/cohérent navigateur que border-image (qui laissait un liseré pâle à gauche).
 * Diagnostiqué en direct : un ::after en inset:0 sur la figure englobait la légende
 * (~10px de trop, ligne du bas en travers du texte « Photo : … »). */
.vd-single__body .wp-block-image {
	display: grid; grid-template-columns: 100%; width: 100%; line-height: 0;
}
.vd-single__body .wp-block-image img { grid-area: 1 / 1; }
.vd-single__body .wp-block-image > figcaption { grid-area: 2 / 1; }
.vd-single__body .wp-block-image::after {
	content: ""; grid-area: 1 / 1; pointer-events: none;
	box-shadow: inset 0 0 0 1px var(--vd-cat-color, transparent);
}
body[class*="vd-cat--grands-formats"] .vd-single__body .wp-block-image::after {
	box-shadow: none;
	padding: 1px;
	background: var(--wp--preset--gradient--grands-formats);
	-webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
	-webkit-mask-composite: xor; mask-composite: exclude;
}

/* Légende d'image : line-height remise (sinon héritée à 0 → texte écrasé), placée juste
 * sous la photo (hors cadre). Couleur discrète, adaptée au thème clair / sombre. */
.vd-single__body figcaption {
	line-height: 1.45; font-size: 13px; margin-top: 8px;
	color: var(--vd-text-soft); text-align: center;
}

/* Corps de l'article (contenu Gutenberg) */
.vd-single__body p { font-size: 16px; line-height: 1.65; color: var(--wp--preset--color--contrast); margin: 0 0 1.1rem; }
.vd-single__body h2 { font-family: var(--vd-serif); font-weight: 700; font-size: 24px; line-height: 1.3; margin: 2rem 0 0.75rem; }
.vd-single__body h3 { font-family: var(--wp--preset--font-family--inter, "Inter", sans-serif); font-weight: 600; font-size: 18px; line-height: 1.35; margin: 1.5rem 0 0.5rem; }
.vd-single__body ul, .vd-single__body ol { margin: 0 0 1.1rem 1.25rem; padding: 0; }
.vd-single__body li { font-size: 16px; line-height: 1.65; color: var(--wp--preset--color--contrast); margin: 0.3rem 0; }
.vd-single__body a { color: var(--vd-cat-color, var(--wp--preset--color--vetements)); text-decoration: underline; }

/* Tableau minimaliste : aucune bordure de colonne ; uniquement des lignes
 * horizontales sous chaque rangée, dont les extrémités s'estompent en fondu. */
.vd-single__body .wp-block-table table { border-collapse: collapse; width: 100%; }
.vd-single__body .wp-block-table td,
.vd-single__body .wp-block-table th {
	border: 0;
	padding: 0.85rem 0.5rem;
	font-size: 16px;
	line-height: 1.5;
}
.vd-single__body .wp-block-table tr {
	background-repeat: no-repeat;
	background-position: left bottom;
	background-size: 100% 1px;
	background-image: linear-gradient(90deg, transparent 0%, rgba(20,18,30,0.16) 12%, rgba(20,18,30,0.16) 88%, transparent 100%);
}
[data-theme="dark"] .vd-single__body .wp-block-table tr {
	background-image: linear-gradient(90deg, transparent 0%, rgba(245,245,240,0.22) 12%, rgba(245,245,240,0.22) 88%, transparent 100%);
}
/* Pas de trait sous la dernière rangée : le tableau se termine "ouvert". */
.vd-single__body .wp-block-table tbody tr:last-child,
.vd-single__body .wp-block-table tr:last-child {
	background-image: none;
}

/* Barre dégradée : un bloc « Séparateur » stylé en barre pleine largeur du contenu.
 * Couleur de section (dégradé pour Grands Formats). À placer dans l'article (ex : sous « En bref »).
 * Au clic dans les 40px à droite, le JS fait traverser un vélo (1 parmi 10) → cf. .vd-line-bike. */
.vd-single__body .wp-block-separator {
	border: 0;
	height: 6px;
	width: 100%;
	max-width: none;
	margin: 1.5rem 0;
	opacity: 1;
	background: var(--vd-cat-color, var(--wp--preset--color--separator));
	position: relative;
}
body[class*="vd-cat--grands-formats"] .vd-single__body .wp-block-separator {
	background: var(--wp--preset--gradient--grands-formats);
}

/* « Petite route » qui suit le vélo : asphalte gris foncé + pointillés blancs au centre.
 * Le JS ajoute .is-bike-passing (+ .is-bike-rtl) sur le séparateur en même temps qu'il
 * spawn le vélo. Le rendu de la route est masqué via un GRADIENT MASK en forme de
 * « fenêtre » centrée sur la position du vélo. La fenêtre a un fade in côté avant et
 * un fade out côté arrière → la route apparaît en fondu devant le vélo et disparaît
 * en fondu derrière, en sync avec son déplacement (4 s linear). */
.vd-single__body .wp-block-separator::after {
	content: "";
	position: absolute;
	inset: 0;
	pointer-events: none;
	opacity: 0;
	background-color: #333;
	background-image: repeating-linear-gradient(
		to right,
		rgba(255, 255, 255, 0.95) 0,
		rgba(255, 255, 255, 0.95) 14px,
		transparent 14px,
		transparent 28px
	);
	background-size: 100% 1.5px;
	background-position: center;
	background-repeat: no-repeat;
	/* Fenêtre mask : noir au centre (50%) avec fades de 6% de chaque côté. Mask 2x plus
	 * large que l'élément → la fenêtre se promène en animant mask-position. */
	-webkit-mask-image: linear-gradient(to right,
		transparent 0%, transparent 44%,
		black 48%, black 52%,
		transparent 56%, transparent 100%);
	        mask-image: linear-gradient(to right,
		transparent 0%, transparent 44%,
		black 48%, black 52%,
		transparent 56%, transparent 100%);
	-webkit-mask-size: 200% 100%;
	        mask-size: 200% 100%;
	-webkit-mask-repeat: no-repeat;
	        mask-repeat: no-repeat;
}
.vd-single__body .wp-block-separator.is-bike-passing::after {
	animation: vd-road-window-ltr 4s linear forwards;
}
.vd-single__body .wp-block-separator.is-bike-passing.is-bike-rtl::after {
	animation: vd-road-window-rtl 4s linear forwards;
}
/* mask-position 100% = fenêtre à gauche de l'élément ; 0% = fenêtre à droite.
 * Pour LTR (vélo L→R), animer 100% → 0%. Pour RTL, l'inverse. */
@keyframes vd-road-window-ltr {
	0%   { -webkit-mask-position: 100% 0; mask-position: 100% 0; opacity: 0; }
	8%   { opacity: 1; }
	92%  { opacity: 1; }
	100% { -webkit-mask-position: 0% 0;   mask-position: 0% 0;   opacity: 0; }
}
@keyframes vd-road-window-rtl {
	0%   { -webkit-mask-position: 0% 0;   mask-position: 0% 0;   opacity: 0; }
	8%   { opacity: 1; }
	92%  { opacity: 1; }
	100% { -webkit-mask-position: 100% 0; mask-position: 100% 0; opacity: 0; }
}
@media (prefers-reduced-motion: reduce) {
	.vd-single__body .wp-block-separator::after { display: none; }
}
/* Mobile (≤600 px) : route 2x plus rapide. L'override sur le vélo est plus bas,
 * APRÈS la déclaration de .vd-line-bike--ltr/rtl (sinon la shorthand `animation: ... 4s`
 * de la base écrase l'animation-duration: 2s).
 * On cible AUSSI le sélecteur RTL (.is-bike-rtl::after) qui a une spécificité
 * supérieure → sans ça la route RTL restait à 4s pendant que le vélo RTL passait
 * à 2s (désynchro spécifique au sens droite→gauche). */
@media (max-width: 600px) {
	.vd-single__body .wp-block-separator.is-bike-passing::after,
	.vd-single__body .wp-block-separator.is-bike-passing.is-bike-rtl::after {
		animation-duration: 2s;
	}
}

/* Vélo qui traverse la barre séparateur. Le contexte de positionnement est le body de
 * l'article (rendu position: relative). Le JS spawn un .vd-line-bike absolu, position
 * top = haut de la barre, transform translateY(-100%) → le bas du wrapper (= les roues
 * du vélo) est posé pile sur la ligne. L'animation (translateX + opacity fade in/out)
 * est gérée par CSS keyframes, avec --travel défini en inline par le JS.
 * Le vélo apparaît au bord d'entrée de la barre, traverse, disparaît au bord opposé,
 * sans jamais sortir des limites de la ligne. */
.vd-single__body { position: relative; }
.vd-line-bike {
	position: absolute;
	width: 35px;
	height: 25px;
	pointer-events: none;
	z-index: 5;
	opacity: 0; /* point de départ : invisible, l'animation fade in */
	/* --bike-lift : décalage vertical au-dessus de la ligne (≈ 1/4 cm = 10 px). */
	--bike-lift: 10px;
	transform: translateY(calc(-100% - var(--bike-lift)));
	will-change: transform, opacity;
}
.vd-line-bike--ltr { animation: vd-line-bike-ltr 4s linear forwards; }
.vd-line-bike--rtl { animation: vd-line-bike-rtl 4s linear forwards; }
@keyframes vd-line-bike-ltr {
	0%   { opacity: 0; transform: translateY(calc(-100% - var(--bike-lift))) translateX(0); }
	8%   { opacity: 1; }
	92%  { opacity: 1; }
	100% { opacity: 0; transform: translateY(calc(-100% - var(--bike-lift))) translateX(var(--travel, 0px)); }
}
@keyframes vd-line-bike-rtl {
	0%   { opacity: 0; transform: translateY(calc(-100% - var(--bike-lift))) translateX(0); }
	8%   { opacity: 1; }
	92%  { opacity: 1; }
	100% { opacity: 0; transform: translateY(calc(-100% - var(--bike-lift))) translateX(calc(-1 * var(--travel, 0px))); }
}
/* Mobile : durée 2s pour le vélo, SYNC avec la route (qui a son propre override
 * dans le bloc @media plus haut). Cette règle doit venir APRÈS les bases
 * `.vd-line-bike--ltr { animation: ... 4s }` sinon la shorthand de la base
 * réécrase l'animation-duration à 4s sur mobile (bug v1.7.x → v1.11.7). */
@media (max-width: 600px) {
	.vd-line-bike--ltr,
	.vd-line-bike--rtl { animation-duration: 2s; }
}
.vd-line-bike__img {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: contain;
	object-position: center bottom; /* roues calees au bord bas du wrapper */
}
.vd-line-bike--rtl .vd-line-bike__img { transform: scaleX(-1); }

/* Accessibilité : pas d'animation pour les utilisateurs qui le demandent. */
@media (prefers-reduced-motion: reduce) {
	.vd-line-bike { display: none !important; }
}

/* Bloc « En bref » : aligné à gauche, pleine largeur du contenu (on neutralise la
 * largeur restreinte des anciens brouillons), titre EN MAJUSCULES. */
.vd-single__body .en-bref { max-width: none; margin: 1.25rem 0; }
.vd-single__body .en-bref > * { max-width: none; margin-left: 0; margin-right: 0; }
.vd-single__body .en-bref h4 {
	text-transform: uppercase; /* INTER + taille par défaut (comme avant), juste en majuscules */
	margin: 0 0 0.5rem;
}
.vd-single__body .en-bref p { margin: 0; }

/* Bouton RETOUR : pill à bord dégradé + texte dégradé, fond transparent (à droite).
 * Au survol : un vélo (aléatoire parmi 10) traverse le bouton de gauche à droite et le
 * « peint » au passage (noir en thème clair, blanc en thème sombre). L'élément <img>
 * est injecté par JS (assets/js/velodisco-ui.js) ; le mot « Retour » est ré-encapsulé
 * dans un <span class="vd-bike-label"> par le même JS pour passer au-dessus du vélo. */
.vd-single__retour {
	position: relative;
	display: inline-flex;
	align-items: center;
	padding: 7px 22px;
	border-radius: 999px;
	font-family: var(--wp--preset--font-family--inter, "Inter", sans-serif);
	font-weight: 600; font-size: 12px; line-height: 15px;
	text-transform: uppercase; text-decoration: none;
	color: transparent;
	overflow: hidden;
	isolation: isolate;
	--vd-fill: #000;            /* couleur du remplissage en thème clair */
	--vd-on-fill: #fff;         /* couleur du texte par-dessus le remplissage */
}
[data-theme="dark"] .vd-single__retour {
	--vd-fill: #fff;
	--vd-on-fill: #000;
}
.vd-single__retour::before {
	content: ""; position: absolute; inset: 0;
	border-radius: 999px; padding: 1px;
	background: var(--wp--preset--gradient--grands-formats);
	-webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
	-webkit-mask-composite: xor; mask-composite: exclude;
	pointer-events: none;
}
/* Couche de remplissage : glisse de gauche à droite (derrière le texte et le vélo). */
.vd-single__retour::after {
	content: "";
	position: absolute;
	inset: 0;
	border-radius: inherit;
	background: var(--vd-fill);
	transform: translateX(-101%);
	transition: transform 1.5s cubic-bezier(.4, 0, .2, 1);
	z-index: -1;
}
.vd-single__retour:hover::after,
.vd-single__retour:focus-visible::after {
	transform: translateX(0);
}
/* Vélo qui traverse (injecté par JS, src aléatoire parmi 10). Hauteur 100% : la silhouette
 * du vélo tient entièrement dans la hauteur du bouton (au lieu de déborder en haut/bas, ce
 * qui faisait voir une bande horizontale plutôt que la forme complète du vélo). */
.vd-single__retour .vd-bike {
	position: absolute;
	top: 50%;
	left: 0;
	height: 100%;
	width: auto;
	transform: translate(-130%, -50%);
	transition: transform 1.5s cubic-bezier(.4, 0, .2, 1), opacity 0.3s ease;
	pointer-events: none;
	opacity: 0;
	z-index: 0;
}
.vd-single__retour:hover .vd-bike,
.vd-single__retour:focus-visible .vd-bike {
	transform: translate(180%, -50%);
	opacity: 1;
}
/* Le mot « Retour » passe au-dessus du vélo. Le dégradé en mode texte (background-clip)
 * doit être appliqué DIRECTEMENT sur le span (pas hérité du parent) sinon le texte
 * passe en color:transparent sans dégradé visible. Au survol on remplace le dégradé
 * par une couleur unie lisible sur le fond (blanc en clair, noir en sombre). */
.vd-single__retour .vd-bike-label {
	position: relative;
	z-index: 1;
	background: var(--wp--preset--gradient--grands-formats);
	-webkit-background-clip: text; background-clip: text;
	-webkit-text-fill-color: transparent; color: transparent;
	transition:
		-webkit-text-fill-color 0.45s ease 0.75s,
		color 0.45s ease 0.75s;
}
.vd-single__retour:hover .vd-bike-label,
.vd-single__retour:focus-visible .vd-bike-label {
	background: none;
	-webkit-text-fill-color: var(--vd-on-fill);
	color: var(--vd-on-fill);
}
/* Accessibilité : pas d'animation pour les utilisateurs qui le demandent. */
@media (prefers-reduced-motion: reduce) {
	.vd-single__retour .vd-bike { display: none; }
	.vd-single__retour::after,
	.vd-single__retour .vd-bike-label { transition: none; }
}

/* ---- Fonds dégradés subtils par catégorie (relevé Figma, Victor gère/ajuste) ---- */
body[class*="vd-cat--"] { background-repeat: no-repeat; }
body[class*="vd-cat--velos"]        { background-image: linear-gradient(180deg, rgba(219,63,12,0.04) 0%, transparent 41%); }
body[class*="vd-cat--accessoires"]  { background-image: linear-gradient(180deg, rgba(27,143,41,0.04) 0%, transparent 29%); }
body[class*="vd-cat--composants"]   { background-image: linear-gradient(180deg, rgba(214,150,0,0.04) 0%, transparent 46%); }
body[class*="vd-cat--vetements"]    { background-image: linear-gradient(180deg, rgba(0,145,194,0.04) 0%, transparent 39%); }
body[class*="vd-cat--societe"]      { background-image: linear-gradient(180deg, rgba(47,0,216,0.02) 0%, transparent 34%); }
body[class*="vd-cat--grands-formats"] { background-image: linear-gradient(180deg, rgba(242,78,30,0.10) 0%, rgba(11,195,124,0.10) 29.3%, rgba(26,188,254,0.10) 73.6%, rgba(255,178,0,0.10) 100%); }
[data-theme="dark"] body[class*="vd-cat--velos"]        { background-image: linear-gradient(180deg, rgba(219,63,12,0.25) 0%, transparent 54%); }
[data-theme="dark"] body[class*="vd-cat--accessoires"]  { background-image: linear-gradient(180deg, rgba(27,143,41,0.25) 0%, transparent 100%); }
[data-theme="dark"] body[class*="vd-cat--composants"]   { background-image: linear-gradient(180deg, rgba(214,150,0,0.25) 0%, transparent 54%); }
[data-theme="dark"] body[class*="vd-cat--vetements"]    { background-image: linear-gradient(180deg, rgba(0,145,194,0.25) 0%, transparent 100%); }
[data-theme="dark"] body[class*="vd-cat--societe"]      { background-image: linear-gradient(180deg, rgba(47,0,216,0.25) 0%, transparent 100%); }
[data-theme="dark"] body[class*="vd-cat--grands-formats"] { background-image: linear-gradient(180deg, rgba(242,78,30,0.20) 0%, rgba(11,195,124,0.20) 31.3%, rgba(26,188,254,0.20) 67.8%, rgba(255,178,0,0.20) 100%); }

/* ---- Passe MOBILE de l'article (relevé Figma « Blog Page Grands Formats — Mobile », 375px) ---- */
@media (max-width: 600px) {
	/* Maquette mobile : pas d'étiquette catégorie au-dessus du titre. */
	.vd-single__cat { display: none; }

	/* Titre : Merriweather 700, 26px / 33px (au lieu de la taille desktop).
	   !important nécessaire : WP met !important sur .has-xx-large-font-size, et la
	   line-height desktop est en style inline. */
	.vd-single__title { font-size: 26px !important; line-height: 33px !important; }

	/* Date : Inter 500, 11px, gris doux (--vd-text-soft, en clair ; off-white conservé en sombre).
	   !important sur font-size pour battre .has-small-font-size de WP. */
	.vd-single__date { font-size: 11px !important; line-height: 13px; color: var(--vd-text-soft); }

	/* Photos (toutes les images du corps) : PLEINE LARGEUR écran.
	   WP impose margin-left/right:auto !important aux enfants du layout « constrained » →
	   on doit forcer la marge négative en !important pour déborder le padding latéral (20px). */
	.vd-single__body .wp-block-image {
		margin-left: calc(clamp(20px, 5vw, 24px) * -1) !important;
		margin-right: calc(clamp(20px, 5vw, 24px) * -1) !important;
		max-width: none !important;
		width: auto !important;
	}

	/* Tracé : UNIQUEMENT en haut de la photo (0.3px, valeur du Figma), couleur de catégorie
	   (dégradé pour Grands Formats) — au lieu du cadre 1px tout autour du desktop. */
	.vd-single__body .wp-block-image::after {
		box-shadow: none !important;
		-webkit-mask: none !important; mask: none !important;
		padding: 0 !important;
		inset: 0 0 auto 0;          /* hero (absolu) : ligne collée en haut, pleine largeur */
		align-self: start;          /* corps (grille) : ligne en haut de la cellule image */
		height: 1px;
		background: var(--vd-cat-color, transparent);
	}
	body[class*="vd-cat--grands-formats"] .vd-single__body .wp-block-image::after {
		background: var(--wp--preset--gradient--grands-formats);
	}

	/* Corps : paragraphes/listes 14px, line-height 160%. */
	.vd-single__body p,
	.vd-single__body li { font-size: 14px; line-height: 1.6; }
	/* Sous-titres : H2 Merriweather 700 18px / 23px ; H3 légèrement réduit. */
	.vd-single__body h2 { font-size: 18px; line-height: 23px; margin: 1.5rem 0 0.6rem; }
	.vd-single__body h3 { font-size: 16px; }
	/* Tableau : cellules un peu plus compactes. */
	.vd-single__body .wp-block-table td,
	.vd-single__body .wp-block-table th { font-size: 14px; padding: 0.7rem 0.4rem; }

	/* Bouton RETOUR : centré (au lieu d'aligné à droite en desktop). */
	.vd-single .vd-single__retourwrap { justify-content: center; }
}

/* 9. ACCESSIBILITÉ --------------------------------------------------------- */
:where(a, button, input, [tabindex]):focus-visible {
	outline: 2px solid var(--wp--preset--color--vetements);
	outline-offset: 2px;
	border-radius: 4px;
}

@media (prefers-reduced-motion: reduce) {
	*,
	*::before,
	*::after {
		animation-duration: 0.001ms !important;
		animation-iteration-count: 1 !important;
		transition-duration: 0.001ms !important;
		scroll-behavior: auto !important;
	}
	.vd-reveal { opacity: 1; transform: none; }
}

/* RESPONSIVE : bascule mobile -------------------------------------------- */
/* Header en burger dès ≤1080px (même seuil que la Home) : au-delà, la grille
 * 3 colonnes a la place de garder une distance confortable entre les catégories
 * et le logo centré ; en dessous, les catégories frôleraient « VeloDisco ». */
@media (max-width: 1080px) {
	/* Version « mobile » : logo à gauche, et à droite ACTU + Grands Formats + loupe + burger
	 * (cf. capture Victor). Les catégories passent dans le burger. */
	.vd-header__inner { grid-template-columns: auto 1fr auto; }
	.vd-header__nav--left { display: none; }
	.vd-header__logo { grid-column: 1; justify-self: start; }
	.vd-header__nav--right { grid-column: 3; }
	.vd-burger { display: inline-flex; }
	/* On masque uniquement le réglage du thème (il reste dans le burger déplié) ;
	   ACTU, Grands Formats et la loupe restent visibles dans le header. */
	.vd-header__nav--right .vd-iconbtn[data-popover-target="vd-theme-menu"] { display: none; }
	/* Pastilles disco : apparaissent en fondu à côté de « VeloDisco ». */
	.vd-header__dots { display: grid; animation: vd-fade-in 2s var(--vd-ease, ease) both; }

	/* Header plus court sur mobile : on réduit UNIQUEMENT la hauteur (l'espace
	 * haut), pas la taille du logo ni du burger. La var pilote aussi le calage
	 * des popovers, donc tout reste aligné. */
	:root { --vd-header-h: 56px; }

	/* NB : le fix sticky (header.wp-block-template-part { display:contents }) et le
	 * calage sous la barre d'admin (.vd-header { top: ... }) sont désormais GLOBAUX
	 * (voir section 3) pour que l'auto-hide fonctionne aussi sur desktop.
	 * Auto-hide lié au défilement : le transform translateY est posé en inline par
	 * le JS (suivi direct de la vitesse de scroll, zone morte d'~1 cm à la remontée). */
}

@media (min-width: 1081px) {
	.vd-mobile-nav { display: none; }
}

/* Téléphone / petite tablette : ACTU, Grands Formats et la loupe ne tiennent plus à côté
 * du burger sans pousser ce dernier hors écran → on les replie dans le burger (header =
 * VeloDisco + pastilles + burger). Au-dessus (769-1080px), tout s'affiche avec le burger. */
@media (max-width: 768px) {
	.vd-header__nav--right .vd-nav__link,
	.vd-header__nav--right .vd-iconbtn[data-popover-target="vd-search-pop"] { display: none; }
}


/* ================================================================
 * GRANDS FORMATS — Historique
 * Le bloc initial (v1.6.4, ~230 lignes : .vd-gf-title, .vd-en-bref,
 * .vd-gf-citation, .vd-gf-aside, .vd-gf-illustration, .vd-pionniere-card,
 * .vd-gf-sources, .vd-gf-separator) a été SUPPRIMÉ le 2026-05-29 (v1.10.0
 * — audit) : ces classes ne sont plus utilisées par l'article GF actuel
 * qui repose sur `.vd-gf01__*` + blocs Gutenberg natifs.
 *
 * En plus de simplifier, ça corrige un piège latent : `.vd-gf h2` (spec
 * 0,0,2) écrasait `.vd-sectitle` (0,0,1) → le titre "Grands Formats" sur
 * la home risquait une mauvaise taille de police.
 *
 * Palette officielle (cf. theme.json) :
 *   Vélos #DB3F0C · Accessoires #1B8F29 · Composants #D69600
 *   Vêtements #0091C2 · Société #785FD3 · GF = gradient des 5
 * ================================================================ */



/* ================================================================
 * GRANDS FORMATS — Photos des cartes pionnières uniformisées
 * Ajouté le 2026-05-29 (thème v1.6.7)
 * Cible les images dans les wp:columns à côté d'une carte
 * .vd-gf01__cardmeta : force le carré + cadre minimaliste pour
 * que toutes les cartes aient la même hauteur, peu importe la
 * proportion d'origine de la photo uploadée.
 * ================================================================ */
/* La colonne image est flex stretch — figure + image prennent toute la hauteur
 * disponible, ce qui les aligne exactement sur le cardmeta voisin. Le radius
 * (12px) matche celui de .vd-gf01__cardmeta. */
.wp-block-columns:has(.vd-gf01__cardmeta) > .wp-block-column:has(.wp-block-image) {
	display: flex;
}
.wp-block-columns:has(.vd-gf01__cardmeta) .wp-block-image,
.wp-block-columns:has(.vd-gf01__cardmeta) .wp-block-image figure {
	margin: 0;
	height: 100%;
	width: 100%;
}
.wp-block-columns:has(.vd-gf01__cardmeta) .wp-block-image img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	border-radius: 12px;
	border: 1px solid rgba(255, 255, 255, 0.10);
	background: rgba(255, 255, 255, 0.03);
	box-sizing: border-box;
	display: block;
}
/* Retire le tracé arc-en-ciel SPÉCIFIQUEMENT sur ces 4 photos (les autres
 * images du GF gardent leur tracé). Spécificité haute pour battre la règle
 * body[class*="vd-cat--grands-formats"] .vd-single__body .wp-block-image::after. */
body[class*="vd-cat--grands-formats"] .vd-single__body .wp-block-columns:has(.vd-gf01__cardmeta) .wp-block-image::after {
	display: none;
}
/* Le site contrôle son thème via [data-theme] (toggle JS, anti-flash). On suit
 * ce contrat plutôt que prefers-color-scheme (qui suit l'OS, pas le toggle). */
:root:not([data-theme="dark"]) .wp-block-columns:has(.vd-gf01__cardmeta) .wp-block-image img {
	border-color: rgba(0, 0, 0, 0.12);
	background: rgba(0, 0, 0, 0.03);
}
/* Mobile : approche radicale après plusieurs essais ratés à matcher photo↔cardmeta.
 * Les 4 photos se comportent EXACTEMENT comme des images classiques du GF
 * (pleine largeur, ratio naturel, tracé dégradé arc-en-ciel). Le cardmeta vient
 * juste en dessous comme un encart séparé. Plus simple, plus prévisible,
 * marche sans JS. */
@media (max-width: 720px) {
	/* Stack les colonnes (Gutenberg n'a pas la classe are-stacked-on-mobile) */
	.wp-block-columns:has(.vd-gf01__cardmeta) {
		flex-wrap: wrap;
	}
	.wp-block-columns:has(.vd-gf01__cardmeta) > .wp-block-column {
		flex-basis: 100% !important;
		max-width: 100%;
		width: 100%;
	}
	.wp-block-columns:has(.vd-gf01__cardmeta) > .wp-block-column:has(.wp-block-image) {
		display: block;
	}
	/* Reset des overrides desktop : la figure et l'image redeviennent classiques */
	.wp-block-columns:has(.vd-gf01__cardmeta) .wp-block-image,
	.wp-block-columns:has(.vd-gf01__cardmeta) .wp-block-image figure {
		height: auto;
		width: 100%;
	}
	.wp-block-columns:has(.vd-gf01__cardmeta) .wp-block-image img {
		aspect-ratio: auto;
		height: auto;
		border-radius: 0;
		border: none;
		background: transparent;
	}
	/* Re-active le tracé dégradé arc-en-ciel (annule notre display:none desktop) */
	body[class*="vd-cat--grands-formats"] .vd-single__body .wp-block-columns:has(.vd-gf01__cardmeta) .wp-block-image::after {
		display: block;
	}

	/* Séparateur entre chaque groupe photo/encart (s'affiche sur 2e, 3e, 4e
	 * cardmeta — pas sur la première). */
	.vd-single__body .wp-block-columns:has(.vd-gf01__cardmeta) ~ .wp-block-columns:has(.vd-gf01__cardmeta) {
		border-top: 1px solid rgba(0, 0, 0, 0.12);
		padding-top: 2rem;
		margin-top: 2rem;
	}
}
@media (max-width: 720px) {
	[data-theme="dark"] .vd-single__body .wp-block-columns:has(.vd-gf01__cardmeta) ~ .wp-block-columns:has(.vd-gf01__cardmeta) {
		border-top-color: rgba(255, 255, 255, 0.14);
	}
}


/* ================================================================
 * GRANDS FORMATS — Blocs "Image à insérer" (workflow d'édition)
 * Ajouté le 2026-05-29 (thème v1.6.8)
 * Encadré jaune pointillé visible dans l'éditeur Gutenberg ET dans
 * le rendu public. Indique à Victor le sujet/source/licence/légende
 * de chaque emplacement image. À supprimer en 1 clic après upload.
 * En CSS pur, sans script — fonctionne aussi sur le rendu publié
 * au cas où un bloc serait oublié (visible = pas oublié).
 * ================================================================ */
.vd-image-todo {
	background: rgba(245, 194, 66, 0.08);
	border: 1.5px dashed rgba(245, 194, 66, 0.55);
	border-radius: 6px;
	padding: 1rem 1.25rem;
	margin: 1.5rem 0;
	font-size: 0.88rem;
	line-height: 1.55;
	color: inherit;
}
.vd-image-todo__label {
	display: inline-block;
	font-size: 0.72rem;
	font-weight: 700;
	letter-spacing: 0.15em;
	text-transform: uppercase;
	color: #C7861A;
	background: rgba(245, 194, 66, 0.18);
	padding: 0.2rem 0.55rem;
	border-radius: 999px;
	margin-bottom: 0.7rem;
}
.vd-image-todo dl { margin: 0; }
.vd-image-todo dt { font-weight: 600; margin-top: 0.4rem; opacity: 0.85; }
.vd-image-todo dd { margin: 0 0 0.2rem 0; }
.vd-image-todo a { color: inherit; text-decoration: underline; }
.vd-image-todo code { font-size: 0.85em; padding: 0.1em 0.35em; background: rgba(0,0,0,0.1); border-radius: 3px; }
:root:not([data-theme="dark"]) .vd-image-todo code { background: rgba(0,0,0,0.06); }
.vd-image-todo__action {
	margin-top: 0.7rem;
	padding-top: 0.6rem;
	border-top: 1px dashed rgba(245, 194, 66, 0.35);
	font-style: italic;
	opacity: 0.85;
}


/* ================================================================
 * GRANDS FORMATS — Adapter .vd-image-todo pour wp:group/wp:paragraph
 * Ajouté le 2026-05-29 (thème v1.6.9)
 * Les blocs sont passés de wp:html à wp:group + wp:paragraph natifs
 * pour que les liens soient cliquables dans l'éditeur Gutenberg.
 * ================================================================ */
.vd-image-todo p {
	margin: 0.4rem 0;
	font-size: 0.88rem;
	line-height: 1.55;
}
.vd-image-todo p:first-child { margin-top: 0; }
.vd-image-todo p:last-child { margin-bottom: 0; }
.vd-image-todo p.vd-image-todo__label {
	margin-bottom: 0.7rem;
}
.vd-image-todo strong {
	font-weight: 600;
	opacity: 0.85;
}
.vd-image-todo p.vd-image-todo__action {
	margin-top: 0.7rem;
	padding-top: 0.6rem;
	border-top: 1px dashed rgba(245, 194, 66, 0.35);
	font-style: italic;
	opacity: 0.85;
}


/* ================================================================
 * GRANDS FORMATS — Styles pour blocs Gutenberg natifs
 * Ajouté le 2026-05-29 (thème v1.7.0)
 * Cible les wp:paragraph, wp:heading, wp:separator natifs
 * dans les articles de la catégorie Grands Formats, pour qu'ils
 * conservent l'apparence GF tout en restant editables nativement
 * dans Gutenberg (un clic = je modifie le texte).
 *
 * Selector : body[class*="vd-cat--grands-formats"] .vd-single__body
 * (vd-single__body est la classe sur wp:post-content dans single.html)
 * ================================================================ */
body[class*="vd-cat--grands-formats"] .vd-single__body {
	max-width: 760px;
	margin: 0 auto;
	font-family: 'Inter', system-ui, -apple-system, sans-serif;
	line-height: 1.7;
}
body[class*="vd-cat--grands-formats"] .vd-single__body > p {
	font-size: 1rem;
	margin-bottom: 1.1rem;
}
body[class*="vd-cat--grands-formats"] .vd-single__body > h2 {
	font-size: clamp(1.55rem, 3vw, 1.9rem);
	font-weight: 700;
	line-height: 1.25;
	letter-spacing: -0.01em;
	margin: 3rem 0 1.2rem;
}
body[class*="vd-cat--grands-formats"] .vd-single__body > h3 {
	font-size: 1.15rem;
	font-weight: 600;
	margin: 2rem 0 0.6rem;
}
body[class*="vd-cat--grands-formats"] .vd-single__body > p strong { font-weight: 600; }
body[class*="vd-cat--grands-formats"] .vd-single__body > p em { font-style: italic; opacity: 0.95; }

/* Séparateur dégradé : si on utilise wp:separator avec className vd-sep-gradient */
.wp-block-separator.vd-sep-gradient {
	height: 3px;
	border: none;
	background: linear-gradient(90deg, #DB3F0C 0%, #1B8F29 25%, #D69600 50%, #0091C2 75%, #785FD3 100%);
	margin: 3.5rem auto;
	width: 100%;
	max-width: 480px;
	opacity: 1;
}


/* ================================================================
 * GRANDS FORMATS — Couleurs par nth-child (corrige le bug "bloc
 * invalide" causé par les attributs style JSON dans wp:group)
 * Ajouté le 2026-05-29 (thème v1.7.1)
 *
 * Au lieu de poser les couleurs en style inline + JSON attribute,
 * on les pose en CSS pur via nth-child : les wp:group restent
 * compatibles Gutenberg (aucun attribut style requis).
 * ================================================================ */

/* Timeline : 9 jalons, couleurs par position
 * (#785FD3 = société sombre voulu, ≠ preset --societe #2F00D8 → laissé en hex) */
.vd-gf01__timeline > .vd-gf01__tl-item:nth-of-type(1) { --c: var(--wp--preset--color--velos); }
.vd-gf01__timeline > .vd-gf01__tl-item:nth-of-type(2) { --c: var(--wp--preset--color--accessoires); }
.vd-gf01__timeline > .vd-gf01__tl-item:nth-of-type(3) { --c: var(--wp--preset--color--accessoires); }
.vd-gf01__timeline > .vd-gf01__tl-item:nth-of-type(4) { --c: var(--wp--preset--color--vetements); }
.vd-gf01__timeline > .vd-gf01__tl-item:nth-of-type(5) { --c: #785FD3; }
.vd-gf01__timeline > .vd-gf01__tl-item:nth-of-type(6) { --c: var(--wp--preset--color--velos); }
.vd-gf01__timeline > .vd-gf01__tl-item:nth-of-type(7) { --c: #785FD3; }
.vd-gf01__timeline > .vd-gf01__tl-item:nth-of-type(8) { --c: var(--wp--preset--color--vetements); }
.vd-gf01__timeline > .vd-gf01__tl-item:nth-of-type(9) { --c: #785FD3; }

/* Cardmetas : couleurs par modificateurs de classe
 * (#785FD3 = société sombre voulu, ≠ preset --societe #2F00D8 → laissé en hex) */
.vd-gf01__cardmeta--purple { border-top-color: #785FD3; }
.vd-gf01__cardmeta--purple .vd-gf01__card-icon { background: #785FD3; }
.vd-gf01__cardmeta--orange { border-top-color: var(--wp--preset--color--velos); }
.vd-gf01__cardmeta--orange .vd-gf01__card-icon { background: var(--wp--preset--color--velos); }
.vd-gf01__cardmeta--green { border-top-color: var(--wp--preset--color--accessoires); }
.vd-gf01__cardmeta--green .vd-gf01__card-icon { background: var(--wp--preset--color--accessoires); }
.vd-gf01__cardmeta--blue { border-top-color: var(--wp--preset--color--vetements); }
.vd-gf01__cardmeta--blue .vd-gf01__card-icon { background: var(--wp--preset--color--vetements); }


/* ================================================================
 * GRANDS FORMATS — Timeline HORIZONTALE scroll-progressive (v1.7.5)
 * Refonte propre : année EN HAUT, point sur la ligne, titre + texte
 * dessous. Aucune superposition. Lisible.
 *
 * Architecture :
 * .vd-gf01__hframe         → wrapper de 220vh (durée du scroll)
 * .vd-gf01__hframe-sticky  → sticky en haut du viewport
 * .vd-gf01__htimeline      → flex horizontal des 9 jalons
 * .vd-gf01__htl-item       → 1 jalon (année / point / titre+texte)
 * ================================================================ */

.vd-gf01__hframe {
	position: relative;
	height: 220vh;
	margin: 4rem 0;
}
.vd-gf01__hframe-sticky {
	position: sticky;
	top: 10vh;
	height: 80vh;
	display: flex;
	align-items: center;
	justify-content: center;
}
.vd-gf01__htimeline {
	width: 100%;
	display: flex;
	align-items: flex-start;
	gap: 0.5rem;
	position: relative;
}
/* La ligne horizontale dégradée — alignée verticalement avec le
 * centre des points. Calcul : année (2.5rem) + margin-top du dot
 * (0.7rem) + demi-dot (7px) − demi-trait (1.5px) = top de la ligne. */
.vd-gf01__htimeline::before {
	content: "";
	position: absolute;
	top: calc(2.5rem + 0.7rem + 5.5px);
	left: 2%;
	right: 2%;
	height: 3px;
	background: linear-gradient(90deg, #DB3F0C 0%, #1B8F29 25%, #D69600 50%, #0091C2 75%, #785FD3 100%);
	border-radius: 1px;
	z-index: 1;
}
/* Chaque jalon : colonne verticale centrée
 * Ordre visuel : 1) année 2) point (sur la ligne) 3) titre 4) texte */
.vd-gf01__htl-item {
	flex: 1 1 0;
	min-width: 0;
	position: relative;
	padding: 0 0.4rem;
	text-align: center;
	display: flex;
	flex-direction: column;
	align-items: center;
	opacity: 0;
	transform: translateY(8px);
	transition: opacity 0.45s ease, transform 0.45s ease;
}
/* Important : transform:none (et non translateY(0)) à l'état final, sinon le
 * point reste prisonnier de son propre stacking context et la ligne (z-index:2
 * au niveau parent) n'arrive pas à passer devant lui. */
.vd-gf01__htl-item.is-visible {
	opacity: 1;
	transform: none;
}
/* Année (TOUT EN HAUT, taille marquée, couleur du jalon)
 * order: -1 → s'affiche AVANT le pseudo-élément ::before (qui est le point) */
.vd-gf01__htl-year {
	order: -1;
	font-size: 1.15rem;
	font-weight: 700;
	color: var(--c, inherit);
	line-height: 1;
	letter-spacing: -0.01em;
	margin: 0;
	height: 2.5rem;
	display: flex;
	align-items: center;
	justify-content: center;
}
/* Point — placé entre l'année et le titre, AU-DESSUS de la ligne dégradée
 * (z-index: 2 > 1 du ::before de .vd-gf01__htimeline). */
.vd-gf01__htl-item::before {
	content: "";
	display: block;
	width: 14px;
	height: 14px;
	border-radius: 50%;
	background: var(--c, #888);
	margin: 0.7rem 0 1rem;
	position: relative;
	z-index: 2;
	flex-shrink: 0;
}
.vd-gf01__htl-item--major::before {
	width: 20px;
	height: 20px;
	margin-top: calc(0.7rem - 3px);
	margin-bottom: calc(1rem - 3px);
}
/* Couleurs par position
 * (#785FD3 = société sombre voulu, ≠ preset --societe #2F00D8 → laissé en hex) */
.vd-gf01__htl-item--c1 { --c: var(--wp--preset--color--velos); }
.vd-gf01__htl-item--c2 { --c: var(--wp--preset--color--accessoires); }
.vd-gf01__htl-item--c3 { --c: var(--wp--preset--color--accessoires); }
.vd-gf01__htl-item--c4 { --c: var(--wp--preset--color--vetements); }
.vd-gf01__htl-item--c5 { --c: #785FD3; }
.vd-gf01__htl-item--c6 { --c: var(--wp--preset--color--velos); }
.vd-gf01__htl-item--c7 { --c: #785FD3; }
.vd-gf01__htl-item--c8 { --c: var(--wp--preset--color--vetements); }
.vd-gf01__htl-item--c9 { --c: #785FD3; }

.vd-gf01__htl-title {
	font-weight: 600;
	font-size: 0.88rem;
	line-height: 1.3;
	margin: 0 0 0.4rem 0;
}
.vd-gf01__htl-text {
	font-size: 0.8rem;
	line-height: 1.45;
	opacity: 0.78;
	margin: 0;
}

/* Si JS n'a pas tourné : tous les jalons visibles d'office */
.vd-gf01__hframe:not(.is-anim-ready) .vd-gf01__htl-item {
	opacity: 1;
	transform: none;
}

@media (prefers-reduced-motion: reduce) {
	.vd-gf01__htl-item { opacity: 1 !important; transform: none !important; transition: none !important; }
}

/* Mobile : timeline verticale */
@media (max-width: 720px) {
	.vd-gf01__hframe { height: auto; margin: 3rem 0; }
	.vd-gf01__hframe-sticky { position: static; height: auto; display: block; }
	.vd-gf01__htimeline {
		flex-direction: column;
		align-items: stretch;
		padding: 1rem 0 1rem 2rem;
		gap: 1.5rem;
	}
	.vd-gf01__htimeline::before {
		top: 0;
		bottom: 0;
		left: 0;
		right: auto;
		height: auto;
		width: 3px;
		background: linear-gradient(180deg, #DB3F0C 0%, #1B8F29 25%, #D69600 50%, #0091C2 75%, #785FD3 100%);
	}
	.vd-gf01__htl-item {
		text-align: left;
		padding: 0;
		flex-direction: column;
		align-items: flex-start;
	}
	.vd-gf01__htl-year {
		height: auto;
		font-size: 1.3rem;
		margin: 0 0 0.3rem 0;
	}
	/* Point centré pile sur la ligne verticale (largeur 3px, left:0 du container).
	 * Calcul : on veut centre point = centre ligne = 1.5px du container.
	 * Item commence à 2rem (padding-left), point absolu relatif à l'item, dot 14px.
	 * → left point = 1.5px (centre ligne) − 7px (demi-dot) − 2rem (offset item) = calc(-2rem - 5.5px). */
	.vd-gf01__htl-item::before {
		position: absolute;
		top: 0.45rem;
		left: calc(-2rem - 5.5px);
		margin: 0;
	}
	/* Gros point (jalon majeur, 20px) : décalage différent pour rester centré.
	 * left = 1.5 − 10 (demi-dot) − 2rem = calc(-2rem - 8.5px). */
	.vd-gf01__htl-item--major::before {
		left: calc(-2rem - 8.5px);
	}
	.vd-gf01__htl-title { font-size: 1rem; margin-bottom: 0.3rem; }
	.vd-gf01__htl-text { font-size: 0.9rem; }
}


/* ================================================================
 * GRANDS FORMATS — Fix final timeline + card-icon sur <p> (v1.7.3)
 * ================================================================ */

/* Card-icon en <p> wp:paragraph natif : forcer ligne et marges */
p.vd-gf01__card-icon {
	display: inline-flex;
	width: 36px;
	height: 36px;
	line-height: 1;
	margin: 0 0 0.7rem 0;
	padding: 0;
	color: #fff !important;
}

/* Timeline horizontale : breakout pour déborder du conteneur 760px */
.vd-gf01__hframe {
	width: min(100vw - 2rem, 1100px);
	max-width: none;
	margin-left: 50%;
	transform: translateX(-50%);
}
@media (max-width: 720px) {
	.vd-gf01__hframe {
		width: 100%;
		margin-left: 0;
		transform: none;
	}
}

/* ===== Section titles → logo swap (desktop home, au survol) =====
 * Même réglage de transition que le footer VELODISCO : opacity 2s ease.
 * Desktop uniquement (≥ 881px), mobile inchangé.
 * Revert : supprimer ce bloc + restaurer home.php.bak-20260602-sectionlogos */
/* Masquer les logos par défaut (toutes tailles) — sinon ils s'affichent en géant sur mobile */
.vd-sectitle__logo { display: none; }

@media (min-width: 881px) {
	.vd-sectitle--frais,
	.vd-sectitle--aune,
	.vd-sectitle--tend {
		position: relative;
	}
	.vd-sectitle--frais .vd-sectitle__text,
	.vd-sectitle--aune .vd-sectitle__text,
	.vd-sectitle--tend .vd-sectitle__text {
		display: inline-block;
		transition: opacity 2s ease;
	}
	/* Pas de cursor pointer — c'est un easter egg caché */
	.vd-sectitle--frais,
	.vd-sectitle--aune,
	.vd-sectitle--tend { cursor: default; }
	.vd-sectitle--frais .vd-sectitle__logo,
	.vd-sectitle--aune .vd-sectitle__logo,
	.vd-sectitle--tend .vd-sectitle__logo {
		display: block;
		position: absolute;
		left: 0;
		top: 50%;
		transform: translateY(-50%);
		height: 40px;
		width: auto;
		max-width: 200px;
		opacity: 0;
		transition: opacity 2s ease;
		pointer-events: none;
	}
	/* Velojournal légèrement plus grand que les autres */
	.vd-sectitle--aune .vd-sectitle__logo { height: 50px; }
	/* Velocomet : pochoir noir en mode clair, blanc en mode sombre */
	.vd-sectitle--tend .vd-sectitle__logo {
		filter: brightness(0);
		transition: opacity 2s ease, filter 0.3s ease;
	}
	[data-theme="dark"] .vd-sectitle--tend .vd-sectitle__logo {
		filter: brightness(0) invert(1);
	}
	/* Clic → classe .is-logo ajoutée par JS (auto-revert 5s, même principe que footer VELODISCO) */
	.vd-sectitle--frais.is-logo .vd-sectitle__text,
	.vd-sectitle--aune.is-logo .vd-sectitle__text,
	.vd-sectitle--tend.is-logo .vd-sectitle__text { opacity: 0; }
	.vd-sectitle--frais.is-logo .vd-sectitle__logo,
	.vd-sectitle--aune.is-logo .vd-sectitle__logo,
	.vd-sectitle--tend.is-logo .vd-sectitle__logo { opacity: 1; }
}

/* ================================================================== */
/* Easter egg : clic sur la date d'un article → affiche le n° de post */
/* Desktop uniquement (≥ 881px). Même mécanique que les titres home.  */
/* ================================================================== */
@media (min-width: 881px) {
	.vd-single__date {
		position: relative;
		cursor: default;
	}
	.vd-single__date time {
		display: inline-block;
		transition: opacity 2s ease;
	}
	.vd-single__postid {
		position: absolute;
		left: 0;
		top: 0;
		opacity: 0;
		transition: opacity 2s ease;
		pointer-events: none;
		font-variant-numeric: tabular-nums;
	}
	.vd-single__date.is-id-shown time { opacity: 0; }
	.vd-single__date.is-id-shown .vd-single__postid { opacity: 1; }
}
