/**
 * Filtres et tri Touchy Idea.
 *
 * Les couleurs passent par les variables de la charte, avec un repli codé en
 * dur : si la feuille du thème n'est pas chargée — dans le constructeur, par
 * exemple — les barres gardent leur allure.
 *
 * Le prune signale la sélection, le cerise reste réservé à ce qui doit attirer
 * l'œil : une promotion, une erreur, un bouton d'achat. C'est la règle de la
 * charte, et c'est pour ça que la pilule active n'est pas rose.
 */

.tif {
	--tif-ink: var( --ti-ink, #2d1b47 );
	--tif-muted: var( --ti-mauve-500, #6f6580 );
	--tif-faint: var( --ti-mauve-400, #8d849b );
	--tif-border: var( --border, var( --ti-mist-200, #ddd7c8 ) );
	--tif-border-soft: var( --border-soft, var( --ti-mist-100, #efece3 ) );
	--tif-surface: var( --bg-elevated, #ffffff );
	--tif-cream: var( --ti-cream, #f8f7f1 );
	--tif-active: var( --ti-plum-600, #66448f );
	--tif-active-soft: var( --ti-plum-50, #f7eefc );
	--tif-accent: var( --ti-cherry-500, #ff6fa5 );
	--tif-accent-ink: var( --ti-cherry-700, #c84372 );
	--tif-radius: 999px;
	--tif-ease: cubic-bezier( 0.22, 1, 0.36, 1 );

	font-family: inherit;
	color: var( --tif-ink );

	/* Les rangées collantes de Divi créent leur propre contexte
	   d'empilement : un z-index posé sur le panneau seul y reste
	   prisonnier. C'est la barre entière qu'il faut remonter. */
	position: relative;
	z-index: 60;
}

.tif *,
.tif *::before,
.tif *::after {
	box-sizing: border-box;
}

.tif-icon {
	flex: 0 0 auto;
}

/* ---------------------------------------------------------------------------
 * Pilules
 * ------------------------------------------------------------------------- */

.tif-pill {
	display: inline-flex;
	align-items: center;
	gap: 8px;
	min-height: 46px;
	padding: 0 17px;
	border: 1px solid var( --tif-border );
	border-radius: var( --tif-radius );
	background: var( --tif-surface );
	color: var( --tif-ink );
	font-weight: 700;
	font-size: 14.5px;
	line-height: 1.2;
	text-decoration: none;
	white-space: nowrap;
	cursor: pointer;
	flex: 0 0 auto;
	transition: border-color 140ms var( --tif-ease ), background 140ms var( --tif-ease ), color 140ms var( --tif-ease ), transform 140ms var( --tif-ease );
}

.tif-pill:hover,
.tif-pill:focus-visible {
	border-color: var( --ti-plum-300, #c897ea );
	background: var( --tif-active-soft );
	color: var( --tif-ink );
	text-decoration: none;
}

.tif-pill:active {
	transform: scale( 0.97 );
}

.tif-pill.is-on {
	border-color: transparent;
	background: var( --tif-active );
	color: var( --tif-cream );
}

.tif-pill.is-on:hover,
.tif-pill.is-on:focus-visible {
	border-color: transparent;
	background: var( --ti-plum-700, #4a2f70 );
	color: var( --tif-cream );
}

.tif-pill__count {
	display: grid;
	place-items: center;
	min-width: 24px;
	height: 24px;
	padding: 0 7px;
	border-radius: var( --tif-radius );
	background: var( --tif-cream );
	color: var( --tif-muted );
	font-size: 12.5px;
	font-weight: 800;
}

.tif-pill.is-on .tif-pill__count {
	background: rgba( 248, 247, 241, 0.22 );
	color: var( --tif-cream );
}

.tif-pill__caret {
	display: inline-flex;
	opacity: 0.6;
	transition: transform 300ms ease;
}

/* ---------------------------------------------------------------------------
 * Ligne de rayons qui défile
 * ------------------------------------------------------------------------- */

.tif-scroller {
	position: relative;
	display: flex;
	align-items: center;
	gap: 6px;
}

.tif-scroller__viewport {
	flex: 1 1 auto;
	min-width: 0;
	overflow-x: auto;
	overflow-y: hidden;
	scrollbar-width: none;
	-ms-overflow-style: none;
	scroll-padding: 0 24px;
}

.tif-scroller__viewport::-webkit-scrollbar {
	display: none;
}

.tif-scroller__viewport:focus-visible {
	outline: 2px solid var( --tif-active );
	outline-offset: 3px;
	border-radius: 12px;
}

.tif-scroller__track {
	display: flex;
	gap: 8px;
	min-width: min-content;
	padding: 3px 1px;
}

/* Un dégradé côté bord annonce qu'il reste des rayons plus loin. */
.tif-scroller--overflow:not( .tif-scroller--start ) .tif-scroller__viewport {
	mask-image: linear-gradient( to right, transparent 0, #000 28px, #000 100% );
	-webkit-mask-image: linear-gradient( to right, transparent 0, #000 28px, #000 100% );
}

.tif-scroller--overflow:not( .tif-scroller--end ) .tif-scroller__viewport {
	mask-image: linear-gradient( to left, transparent 0, #000 28px, #000 100% );
	-webkit-mask-image: linear-gradient( to left, transparent 0, #000 28px, #000 100% );
}

.tif-scroller--overflow:not( .tif-scroller--start ):not( .tif-scroller--end ) .tif-scroller__viewport {
	mask-image: linear-gradient( to right, transparent 0, #000 28px, #000 calc( 100% - 28px ), transparent 100% );
	-webkit-mask-image: linear-gradient( to right, transparent 0, #000 28px, #000 calc( 100% - 28px ), transparent 100% );
}

.tif-arrow {
	display: grid;
	place-items: center;
	flex: 0 0 auto;
	width: 40px;
	height: 40px;
	padding: 0;
	border: 1px solid var( --tif-border );
	border-radius: var( --tif-radius );
	background: var( --tif-surface );
	color: var( --tif-ink );
	cursor: pointer;
	transition: background 140ms var( --tif-ease ), border-color 140ms var( --tif-ease ), opacity 140ms var( --tif-ease );
}

.tif-arrow:hover {
	background: var( --tif-active-soft );
	border-color: var( --ti-plum-300, #c897ea );
}

.tif-arrow[disabled] {
	opacity: 0.35;
	cursor: default;
}

.tif-arrow[hidden] {
	display: none;
}

/* Repli sans JavaScript : la ligne défile au doigt, sans flèches. */
.tif-terms--wrap .tif-scroller__viewport {
	overflow: visible;
}

.tif-terms--wrap .tif-scroller__track {
	flex-wrap: wrap;
	min-width: 0;
}

/* ---------------------------------------------------------------------------
 * Barre « affiner »
 * ------------------------------------------------------------------------- */

.tif-refine__row {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 8px;
}

.tif-panel {
	position: relative;
	flex: 0 0 auto;
}

.tif-panel > summary {
	list-style: none;
}

.tif-panel > summary::-webkit-details-marker {
	display: none;
}

.tif-panel > summary::marker {
	content: '';
}

.tif-panel[open] {
	z-index: 3;
}

.tif-panel[open] > summary .tif-pill__caret {
	transform: rotate( 180deg );
}

.tif-panel__body {
	position: absolute;
	top: calc( 100% + 8px );
	left: 0;
	z-index: 80;
	width: min( 320px, calc( 100vw - 32px ) );
	padding: 20px;
	border: 1px solid var( --tif-border-soft );
	border-radius: 24px;
	background: var( --tif-surface );
	box-shadow: 0 18px 44px rgba( 45, 27, 71, 0.16 );
	animation: tif-fade-up 180ms var( --tif-ease );
}

/* Près du bord droit, le panneau se cale sur la droite de sa pilule —
   mais seulement à partir du quatrième. Avec deux ou trois panneaux, la
   rangée ne touche jamais le bord et le calage à droite était un
   décalage gratuit. */
.tif-panel:nth-child( n + 4 ):nth-last-child( -n + 2 ) .tif-panel__body {
	left: auto;
	right: 0;
}

@keyframes tif-fade-up {
	from {
		opacity: 0;
		transform: translateY( 8px );
	}

	to {
		opacity: 1;
		transform: translateY( 0 );
	}
}

.tif-panel__title {
	font-size: 17px;
	font-weight: 800;
	line-height: 1.1;
	color: var( --tif-ink );
}

.tif-panel__hint {
	margin: 14px 0 0;
	font-size: 13.5px;
	line-height: 1.55;
	color: var( --tif-muted );
}

/* ---------------------------------------------------------------------------
 * Options d'un panneau
 * ------------------------------------------------------------------------- */

.tif-opts {
	display: flex;
	flex-direction: column;
	gap: 3px;
}

.tif-opt {
	display: flex;
	align-items: center;
	gap: 11px;
	width: 100%;
	min-height: 46px;
	padding: 0 12px;
	border-radius: 14px;
	background: transparent;
	color: var( --tif-ink );
	font-size: 15px;
	font-weight: 600;
	text-decoration: none;
	transition: background 140ms var( --tif-ease );
}

.tif-opt:hover,
.tif-opt:focus-visible {
	background: var( --tif-active-soft );
	color: var( --tif-ink );
	text-decoration: none;
}

.tif-opt__box {
	display: grid;
	place-items: center;
	flex: 0 0 auto;
	width: 22px;
	height: 22px;
	border: 1px solid var( --tif-border );
	border-radius: 7px;
	background: var( --tif-surface );
	color: #ffffff;
}

.tif-opt__box .tif-icon {
	width: 14px;
	height: 14px;
}

.tif-opt.is-on .tif-opt__box {
	border-color: transparent;
	background: var( --tif-active );
}

.tif-opt__label {
	flex: 1 1 auto;
	min-width: 0;
	text-align: left;
}

.tif-opt__count {
	font-size: 13px;
	color: var( --tif-faint );
}

/* Variante en pilules, pour un champ à valeurs courtes. */
.tif-opts--pills {
	flex-direction: row;
	flex-wrap: wrap;
	gap: 7px;
}

.tif-opts--pills .tif-opt {
	width: auto;
	min-height: 38px;
	padding: 0 14px;
	border: 1px solid var( --tif-border );
	border-radius: var( --tif-radius );
	font-size: 13.5px;
	font-weight: 700;
}

.tif-opts--pills .tif-opt.is-on {
	border-color: transparent;
	background: var( --tif-active );
	color: var( --tif-cream );
}

.tif-opts--pills .tif-opt__box {
	display: none;
}

/* ---------------------------------------------------------------------------
 * Budget
 * ------------------------------------------------------------------------- */

.tif-price__head {
	display: flex;
	align-items: baseline;
	justify-content: space-between;
	gap: 10px;
	margin-bottom: 14px;
}

.tif-price__value {
	font-size: 14.5px;
	font-weight: 700;
	color: var( --tif-accent-ink );
	white-space: nowrap;
}

.tif-price__scale {
	display: flex;
	justify-content: space-between;
	margin-top: 8px;
	font-size: 12.5px;
	color: var( --tif-faint );
}

/* Curseur à deux poignées.
 *
 * HTML n'a pas de champ à double butée : on superpose deux `range` sur une
 * piste dessinée à part. Les `range` eux-mêmes sont rendus transparents — on ne
 * garde que leurs poignées, qui restent de vrais contrôles natifs, donc
 * utilisables au clavier et annoncés correctement.
 */
.tif-range2 {
	position: relative;
	height: 34px;
	margin: 4px 0 2px;
}

.tif-range2__track {
	position: absolute;
	top: 50%;
	left: 0;
	right: 0;
	height: 6px;
	margin-top: -3px;
	border-radius: 999px;
	background: var( --tif-active-soft );
}

.tif-range2__fill {
	position: absolute;
	top: 0;
	bottom: 0;
	border-radius: 999px;
	background: var( --tif-active );
}

.tif-range2__input {
	position: absolute;
	top: 0;
	left: 0;
	width: 100%;
	height: 34px;
	margin: 0;
	padding: 0;
	background: none;
	appearance: none;
	-webkit-appearance: none;
	/* La piste ne doit pas intercepter le clic : sans ça, le `range` posé
	   au-dessus rendrait la poignée de l'autre inatteignable. */
	pointer-events: none;
}

.tif-range2__input::-webkit-slider-thumb {
	pointer-events: auto;
	-webkit-appearance: none;
	width: 24px;
	height: 24px;
	border-radius: 999px;
	border: 3px solid var( --tif-surface );
	background: var( --tif-accent );
	box-shadow: 0 1px 6px -1px rgba( 45, 27, 71, 0.5 );
	cursor: grab;
}

.tif-range2__input::-moz-range-thumb {
	pointer-events: auto;
	width: 24px;
	height: 24px;
	border-radius: 999px;
	border: 3px solid var( --tif-surface );
	background: var( --tif-accent );
	box-shadow: 0 1px 6px -1px rgba( 45, 27, 71, 0.5 );
	cursor: grab;
}

.tif-range2__input:focus-visible::-webkit-slider-thumb {
	outline: 2px solid var( --tif-active );
	outline-offset: 2px;
}

/* Les deux champs chiffrés : volontairement discrets, ils ne doivent pas
   concurrencer le curseur du regard — mais ce sont eux qui sont envoyés. */
.tif-price__exact {
	display: flex;
	align-items: center;
	gap: 10px;
	margin-top: 10px;
}

.tif-price__field {
	display: flex;
	align-items: center;
	gap: 6px;
	flex: 1 1 0;
	min-width: 0;
	font-size: 13px;
	color: var( --tif-muted );
}

.tif-price__field input {
	width: 100%;
	min-width: 0;
	min-height: 36px;
	padding: 0 10px;
	border: 1px solid var( --tif-border );
	border-radius: 10px;
	background: var( --tif-surface );
	color: var( --tif-ink );
	font: inherit;
	font-size: 14px;
	font-weight: 600;
}

.tif-price__field input:focus {
	border-color: var( --tif-active );
	outline: none;
}




.tif-apply {
	margin-top: 14px;
	min-height: 44px;
	padding: 0 18px;
	border: none;
	border-radius: var( --tif-radius );
	background: var( --tif-active );
	color: var( --tif-cream );
	font: inherit;
	font-weight: 700;
	cursor: pointer;
}

.tif-apply--inline {
	margin-top: 0;
}

.tif-apply[hidden] {
	display: none;
}

/* ---------------------------------------------------------------------------
 * Filtres actifs
 * ------------------------------------------------------------------------- */

.tif-chips {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 7px;
	margin-top: 11px;
}

.tif-chips__title {
	margin-right: 3px;
	font-size: 13px;
	font-weight: 700;
	letter-spacing: 0.06em;
	text-transform: uppercase;
	color: var( --tif-faint );
}

.tif-chip {
	display: inline-flex;
	align-items: center;
	gap: 7px;
	min-height: 38px;
	padding: 0 10px 0 14px;
	border: 1px solid transparent;
	border-radius: var( --tif-radius );
	background: var( --tif-surface );
	color: var( --ti-plum-700, #4a2f70 );
	font-size: 13.5px;
	font-weight: 700;
	text-decoration: none;
	transition: background 140ms var( --tif-ease ), color 140ms var( --tif-ease );
}

.tif-chip .tif-icon {
	width: 13px;
	height: 13px;
}

/* Le fond de la pastille est imposé plus bas avec `!important` — sinon Divi
   le reprend. Le survol ne pouvait donc plus jouer que sur la bordure, d'où
   ce cerclage cerise qui apparaissait au toucher. Le survol assombrit
   maintenant le fond, et rien ne cercle la pastille. */
.tif-chip:hover,
.tif-chip:focus-visible {
	border-color: transparent;
	background-color: var( --ti-plum-700, #4a2f70 ) !important;
	color: var( --tif-cream );
	text-decoration: none;
}

/* Un `<a>` reste une boîte en ligne : sa hauteur minimale ne faisait rien et
   le libellé se posait sur la ligne de base, plus haut que les pastilles. */
.tif-reset {
	display: inline-flex;
	align-items: center;
	min-height: 38px;
	padding: 0 8px;
	background: none;
	border: none;
	color: var( --tif-accent-ink );
	font-size: 13.5px;
	font-weight: 700;
	text-decoration: underline;
	text-decoration-thickness: 2px;
	text-underline-offset: 3px;
	cursor: pointer;
}

.tif-count {
	margin: 12px 0 0;
	font-size: 15px;
	color: var( --tif-muted );
}

/* Le fond des pilules actives, mis hors d'atteinte.
 *
 * Sur la pilule du budget, le `color` crème s'appliquait mais pas le fond
 * prune : du crème sur du clair, donc un libellé invisible — et une icône
 * invisible avec lui, puisqu'elle est dessinée en `currentColor`. La pilule
 * paraissait vide alors que son contenu était intact dans le DOM.
 *
 * On a vu aujourd'hui plusieurs règles de Divi, presets compris, l'emporter
 * sur des sélecteurs à deux classes. Un sélecteur d'identifiant met tout le
 * monde d'accord : la colonne des identifiants domine toutes les autres, quel
 * que soit l'empilement de classes en face.
 */
/* `!important` sur le fond, et il est indispensable.
 *
 * Une règle de Divi en porte un sur le fond de ces éléments. Face à un
 * `!important`, la spécificité ne compte plus : `#page-container` ou pas, une
 * déclaration ordinaire perd toujours. Le fond restait donc clair pendant que
 * ma couleur de texte, elle, s'appliquait — du crème sur du clair, invisible,
 * et l'icône avec puisqu'elle est dessinée en `currentColor`.
 *
 * `background-color` et non `background` : la forme courte remettrait à zéro
 * l'image, la position et la répétition que Divi pose sur ses modules. */
#page-container .tif-pill.is-on {
	border-color: transparent;
	background-color: var( --tif-active ) !important;
	color: var( --tif-cream );
}

#page-container .tif-pill.is-on:hover,
#page-container .tif-pill.is-on:focus-visible {
	border-color: transparent;
	background-color: var( --ti-plum-700, #4a2f70 ) !important;
	color: var( --tif-cream );
}

/* Le libellé et l'icône aussi, explicitement : une règle de Divi qui pose une
   couleur sur les `span` d'un module — on en a vu plusieurs aujourd'hui, avec
   des sélecteurs à quatre classes et `!important` — rendrait le texte
   invisible sans toucher au fond, et l'icône avec lui puisqu'elle est dessinée
   en `currentColor`. */
#page-container .tif-pill .tif-pill__label,
#page-container .tif-pill .tif-icon {
	color: inherit;
}

/* `!important` parce qu'on en écrase un autre, et pas par confort.
 *
 * Divi écrit pour chaque module Texte une règle du genre
 * `.et_pb_text_2 .et_pb_text_inner { color: … !important }`. Mes barres vivant
 * dans ces modules, ce prune foncé s'appliquait à mes libellés. Sur une pilule
 * inactive, fond blanc, il se lit très bien. Sur une pilule active, fond prune,
 * c'est du prune sur du prune — et l'icône disparaît avec le texte, puisqu'elle
 * est dessinée en `currentColor`.
 *
 * Une couleur sans `!important` perdait donc systématiquement. */
#page-container .tif-pill.is-on,
#page-container .tif-pill.is-on .tif-pill__label,
#page-container .tif-pill.is-on .tif-icon {
	color: var( --tif-cream ) !important;
}

#page-container .tif-pill.is-on .tif-pill__count {
	background: rgba( 248, 247, 241, 0.22 );
	color: var( --tif-cream );
}

/* Même raison pour les options cochées et les filtres actifs : ils inversent
   leurs couleurs, donc ils se heurtent au même `!important` de Divi. */
#page-container .tif-opt.is-on .tif-opt__label,
#page-container .tif-opt.is-on .tif-icon,
#page-container .tif-opts--pills .tif-opt.is-on,
#page-container .tif-chip,
#page-container .tif-chip .tif-icon {
	color: inherit !important;
}

#page-container .tif-opts--pills .tif-opt.is-on,
#page-container .tif-opts--pills .tif-opt.is-on .tif-opt__label {
	color: var( --tif-cream ) !important;
}

/* Mêmes inversions, même mur : option cochée, pilule d'option, filtre actif. */
#page-container .tif-opt.is-on .tif-opt__box,
#page-container .tif-opts--pills .tif-opt.is-on {
	background-color: var( --tif-active ) !important;
}

#page-container .tif-chip {
	background-color: var( --tif-active ) !important;
	color: var( --tif-cream ) !important;
}

#page-container .tif-price__field input {
	background-color: var( --tif-surface ) !important;
}

/* ---------------------------------------------------------------------------
 * Empilement
 *
 * Trois barres, trois conteneurs `.tif` distincts, et les shortcodes en
 * ajoutent d'autres. À z-index égal, c'est l'élément le plus bas dans le
 * document qui l'emporte : les panneaux de la barre « affiner » passaient donc
 * sous les filtres actifs et sous le tri, qui viennent après elle.
 *
 * On hiérarchise, et la barre qui a un panneau ouvert monte au-dessus de tout
 * le reste — elle seule, et seulement le temps de l'ouverture.
 * ------------------------------------------------------------------------- */

.tif-standalone,
.tif-sort {
	z-index: 10;
}

.tif-refine,
.tif-terms {
	z-index: 20;
}

.tif-refine:has( .tif-panel[open] ),
.tif-terms:has( .tif-panel[open] ),

/* Un panneau déplié déborde de tout ce qui l'entoure, et il faut le régler à
   chaque étage — pas seulement sur mes propres éléments.
   
   La compétition d'empilement ne se joue pas entre le panneau et le select de
   tri : elle se joue entre les conteneurs Divi qui les portent. Sur cette
   page, la barre de tri et les filtres actifs vivent dans des Groupes
   (`et_pb_group`) posés après le module de la barre « affiner ». À z-index
   égal, le groupe le plus bas dans le document gagne — quelle que soit la
   valeur donnée à ce qu'il contient.
   
   On remonte donc toute la branche qui porte le panneau ouvert, étage par
   étage. À chaque niveau, la branche concernée passe devant ses sœurs.
   
   Et le débordement se règle aux mêmes endroits. Divi pose un overflow-y sur
   ses lignes et ses colonnes ; or dès qu'un axe vaut `visible` et l'autre non,
   la spécification force le premier à `auto` — d'où la barre de défilement qui
   apparaît quand on croit avoir tout mis en `visible`. Il faut débloquer les
   deux axes d'un coup. */
.et_pb_section:has( .tif-panel[open] ),
.et_pb_row:has( .tif-panel[open] ),
.et_pb_column:has( .tif-panel[open] ),
.et_pb_group:has( .tif-panel[open] ),
.et_pb_module:has( .tif-panel[open] ) {
	position: relative;
	z-index: 300;
	overflow: visible !important;
	overflow-x: visible !important;
	overflow-y: visible !important;
}

/* ---------------------------------------------------------------------------
 * Recherche
 * ------------------------------------------------------------------------- */

.tif-search {
	position: relative;
	display: flex;
	align-items: center;
	flex: 1 1 220px;
	min-width: 0;
	max-width: 340px;
}

.tif-search__icon {
	position: absolute;
	left: 15px;
	display: inline-flex;
	color: var( --tif-faint );
	pointer-events: none;
}

.tif-search__input {
	width: 100%;
	min-height: 46px;
	padding: 0 17px 0 44px;
	border: 1px solid var( --tif-border );
	border-radius: var( --tif-radius );
	background: var( --tif-surface );
	color: var( --tif-ink );
	font: inherit;
	font-size: 14.5px;
	transition: border-color 180ms var( --tif-ease ), box-shadow 180ms var( --tif-ease );
}

.tif-search__input::placeholder {
	color: var( --tif-faint );
}

.tif-search__input:hover {
	border-color: var( --tif-active );
}

.tif-search__input:focus {
	border-color: var( --ti-plum-500, #8662b0 );
	box-shadow: 0 0 0 4px rgba( 255, 111, 165, 0.2 );
	outline: none;
}

/* La croix native de Safari et Chrome fait doublon avec « Efface tout ». */
.tif-search__input::-webkit-search-cancel-button {
	-webkit-appearance: none;
	appearance: none;
}

/* ---------------------------------------------------------------------------
 * Tri
 * ------------------------------------------------------------------------- */

/* La liste du tri est un panneau comme ceux des filtres : la liste qu'ouvre un
   `select` est dessinée par le système et reste hors de portée du CSS. */
.tif-sort__row {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 9px;
}


.tif-sort__form,
.tif-sort__pills {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 9px;
}

.tif-sort__label {
	font-size: 14.5px;
	color: var( --tif-muted );
	white-space: nowrap;
}

/* Le tri se lit dans la même rangée que les pilules de filtre : lui donner
   l'allure d'un champ de formulaire le faisait détonner. Même hauteur, même
   arrondi, même graisse — avec un chevron dessiné pour remplacer celui du
   navigateur, que `appearance: none` supprime. */
.tif-select {
	appearance: none;
	-webkit-appearance: none;
	min-height: 46px;
	padding: 0 40px 0 17px;
	border: 1px solid var( --tif-border );
	border-radius: var( --tif-radius );
	background-image: url( "data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%236f6580' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M5 9l7 7 7-7'/%3E%3C/svg%3E" );
	background-repeat: no-repeat;
	background-position: right 15px center;
	background-size: 16px 16px;
	background-color: var( --tif-surface );
	color: var( --tif-ink );
	font: inherit;
	font-weight: 700;
	font-size: 14.5px;
	cursor: pointer;
	transition: border-color 180ms var( --tif-ease ), box-shadow 180ms var( --tif-ease );
}

.tif-select:hover {
	border-color: var( --tif-active );
}

.tif-select:focus {
	border-color: var( --ti-plum-500, #8662b0 );
	box-shadow: 0 0 0 4px rgba( 255, 111, 165, 0.2 );
	outline: none;
}

/* ---------------------------------------------------------------------------
 * Macaron de carte produit
 *
 * Aucune mise en forme ici : l'apparence se règle dans Divi, sur le module qui
 * porte le shortcode. Le fond seul vient du shortcode, en style en ligne, parce
 * qu'il dépend de ce que le macaron annonce et que Divi ne sait pas le
 * conditionner.
 * ------------------------------------------------------------------------- */

/* Un produit sans macaron ne doit pas laisser flotter une boîte vide sur sa
   carte. Le shortcode ne renvoie rien dans ce cas — reste le module Divi qui le
   porte, qu'on masque à son tour. La règle vise le module entier plutôt que le
   seul conteneur de texte : c'est lui qui porte le positionnement absolu, et
   donc lui qui se verrait. */
.et_pb_module:has( > .et_pb_text_inner:empty ),
.et_pb_module:has( > .et_pb_code_inner:empty ) {
	display: none;
}

/* ---------------------------------------------------------------------------
 * Aucun résultat
 *
 * Divi rend son message dans une colonne de boucle ordinaire — donc calibrée
 * comme une carte produit, un quart de largeur en bureau et la moitié sur
 * téléphone. Un paragraphe de deux lignes dans une colonne de 240 px, c'est
 * illisible.
 *
 * On rend la colonne pleine largeur et on lui donne l'allure d'un état vide.
 * Le texte reste celui de Divi : il se règle dans le Loop Builder, pas ici.
 * ------------------------------------------------------------------------- */

.tif-loop .et_pb_column:has( > .entry > .not-found-title ),
.tif-loop .et_pb_column:has( > .entry > .not-found-title ) {
	flex: 1 1 100% !important;
	width: 100% !important;
	max-width: none !important;
}

.tif-loop .entry:has( > .not-found-title ) {
	max-width: 46ch;
	margin: 0 auto;
	padding: clamp( 28px, 6vw, 52px ) clamp( 20px, 5vw, 40px );
	border: 1px solid var( --tif-border-soft );
	border-radius: 28px;
	background: var( --tif-surface );
	text-align: center;
}

.tif-loop .entry > .not-found-title {
	margin: 0 0 10px;
	font-size: clamp( 20px, 4vw, 26px );
	line-height: 1.2;
	color: var( --tif-ink );
}

.tif-loop .entry:has( > .not-found-title ) p {
	margin: 0;
	font-size: 15px;
	line-height: 1.6;
	color: var( --tif-muted );
	text-wrap: pretty;
}

/* ---------------------------------------------------------------------------
 * États
 * ------------------------------------------------------------------------- */

.tif-busy {
	opacity: 0.55;
	pointer-events: none;
	transition: opacity 160ms var( --tif-ease );
}

.tif-notice {
	padding: 14px 16px;
	border: 1px dashed var( --tif-border );
	border-radius: 16px;
	background: var( --tif-cream );
	color: var( --tif-muted );
	font-size: 14px;
	line-height: 1.5;
}

/* ---------------------------------------------------------------------------
 * Une ou deux colonnes
 *
 * La bascule ne sert que sous le point de rupture « téléphone » de Divi, seul
 * endroit où la boucle passe à deux colonnes — 767 px, sa valeur à lui et non
 * les 640 px de la feuille de filtres.
 *
 * La largeur imposée reprend la formule de Divi, gouttière comprise :
 * `.et_flex_column_12_24 { width: calc( 50% - var( --horizontal-gap-parent ) / 2 ) }`.
 * `!important` parce qu'on écrase une règle de Divi, et pas par confort.
 * ------------------------------------------------------------------------- */

.tif-cols {
	display: none;
	gap: 4px;
}

.tif-cols__btn {
	display: grid;
	place-items: center;
	width: 42px;
	height: 42px;
	padding: 0;
	border: 1px solid var( --tif-border );
	border-radius: var( --tif-radius );
	background: var( --tif-surface );
	color: var( --tif-ink );
	cursor: pointer;
	transition: background-color 140ms var( --tif-ease ), border-color 140ms var( --tif-ease );
}

.tif-cols__btn .tif-icon {
	width: 17px;
	height: 17px;
}

#page-container .tif-cols__btn.is-on {
	border-color: transparent;
	background-color: var( --tif-active ) !important;
	color: var( --tif-cream ) !important;
}

@media ( max-width: 767px ) {
	.tif-js .tif-cols {
		display: inline-flex;
	}

	html[data-tif-cols="1"] .tif-loop > [class*="et_flex_column"] {
		width: 100% !important;
	}

	/* Sur une seule colonne, la carte se couche.
	 *
	 * Une carte pleine largeur qui empile image, titre et prix mange l'écran :
	 * un produit par écran, et le pouce défile sans rien comparer. Couchée,
	 * elle en montre trois ou quatre.
	 *
	 * La carte n'a que deux enfants directs — l'image, puis le Groupe qui
	 * porte tout le reste. Il suffit donc de retourner la colonne : aucun
	 * balisage à changer, et le `margin-top: auto` qui pousse le prix en bas
	 * du Groupe continue de jouer, le Groupe prenant maintenant la hauteur de
	 * l'image. */
	html[data-tif-cols="1"] .tif-loop > [class*="et_flex_column"] {
		flex-direction: row;
		align-items: stretch;
		gap: 14px;
	}

	html[data-tif-cols="1"] .tif-loop > [class*="et_flex_column"] > .et_pb_image {
		flex: 0 0 auto;
		width: 38%;
		max-width: 160px;
	}

	html[data-tif-cols="1"] .tif-loop > [class*="et_flex_column"] > :not( .et_pb_image ) {
		flex: 1 1 auto;
		min-width: 0;
	}

	/* L'image remplit sa portion.
	 *
	 * Une image carrée dans une portion devenue rectangulaire laisse un vide
	 * sous elle. Trois étages doivent s'étirer pour que `object-fit` ait de la
	 * place à remplir : le module, le `<span>` que Divi glisse à l'intérieur —
	 * celui-là n'a aucun réglage dans l'interface, et c'est lui qui bloquait —
	 * puis l'image elle-même.
	 *
	 * `cover` recadre plutôt que de déformer. Pour voir le produit entier
	 * quitte à laisser des marges, remplacer par `contain` depuis Divi :
	 *   html[data-tif-cols="1"] .tif-loop .et_pb_image img { object-fit: contain; }
	 */
	html[data-tif-cols="1"] .tif-loop > [class*="et_flex_column"] > .et_pb_image,
	html[data-tif-cols="1"] .tif-loop > [class*="et_flex_column"] > .et_pb_image .et_pb_image_wrap {
		display: block;
		height: 100%;
	}

	html[data-tif-cols="1"] .tif-loop > [class*="et_flex_column"] > .et_pb_image img {
		width: 100%;
		height: 100%;
		object-fit: cover;
	}

	html[data-tif-cols="2"] .tif-loop > [class*="et_flex_column"] {
		width: calc( 50% - var( --horizontal-gap-parent, 24px ) * 1 / 2 ) !important;
	}
}

/* ---------------------------------------------------------------------------
 * Feuille de filtres
 *
 * En bureau, rien ne change : le déclencheur est masqué et la rangée s'affiche
 * telle quelle. Le balisage supplémentaire ne coûte rien.
 * ------------------------------------------------------------------------- */

/* Le module posé dans un Groupe Divi.
 *
 * Un Groupe est une boîte flex : le module qui y est posé s'y dimensionne sur
 * son contenu au lieu d'occuper la ligne. La rangée était donc aussi étroite
 * que ses pilules, et la recherche — `flex: 1 1 220px`, plafonnée à 340 px —
 * n'avait plus rien à prendre.
 *
 * `flex` sur un élément qui n'est pas enfant d'une boîte flex ne fait rien :
 * hors d'un Groupe, cette règle est sans effet. Dans un Groupe en colonne non
 * plus, faute de hauteur libre à distribuer. Elle n'agit que là où elle sert :
 * un Groupe en rangée, où le module prend la place laissée par ses voisins. */
.touchy_filter_refine,
.touchy_filter_terms {
	flex: 1 1 auto;
	min-width: 0;
}

.tif-sheet {
	display: contents;
}

/* Les enveloppes de la feuille ne doivent rien peser hors téléphone.
 *
 * `display: contents` sur le `<details>` ne suffisait pas : le panneau reste
 * une boîte, et le navigateur en pose une autre autour du contenu d'un
 * `<details>` ouvert (`::details-content`). La rangée n'était donc plus fille
 * directe de la barre, et la recherche — `flex: 1 1 220px`, plafonnée à
 * 340 px — ne trouvait plus la largeur qu'elle réclamait. Effacées, ces
 * enveloppes rendent à la rangée la place qu'elle avait avant la refonte. */
.tif-sheet__panel,
.tif-sheet::details-content {
	display: contents;
}

.tif-sheet__trigger,
.tif-sheet__head,
.tif-sheet__foot {
	display: none;
}

.tif-sheet > summary {
	list-style: none;
}

.tif-sheet > summary::-webkit-details-marker {
	display: none;
}

@media ( max-width: 640px ) {
	.tif-panel__body {
		width: min( 320px, calc( 100vw - 24px ) );
	}

	.tif-refine__row {
		gap: 6px;
	}

	/* Un seul bouton à la place de six pilules empilées sur quatre lignes. */
	.tif-js .tif-sheet {
		display: block;
	}

	/* La feuille, elle, a besoin de vraies boîtes : c'est le panneau qui
	   couvre l'écran. */
	.tif-js .tif-sheet__panel,
	.tif-js .tif-sheet::details-content {
		display: block;
	}

	.tif-js .tif-sheet__trigger {
		display: inline-flex;
		align-items: center;
		gap: 8px;
		min-height: 46px;
		padding: 0 17px;
		border: 1px solid var( --tif-border );
		border-radius: var( --tif-radius );
		background: var( --tif-surface );
		font-weight: 700;
		font-size: 14.5px;
		cursor: pointer;
	}

	/* La feuille couvre l'écran plutôt que de déborder d'une rangée : plus de
	   positionnement absolu à corriger, plus de conteneur Divi à forcer en
	   `overflow: visible`. Le problème disparaît au lieu d'être contourné. */
	.tif-js .tif-sheet[open] > .tif-sheet__panel {
		position: fixed;
		inset: 0;
		z-index: 100000;
		display: flex;
		flex-direction: column;
		overflow: hidden;
		overscroll-behavior: contain;
		background: var( --tif-cream );
		animation: tif-sheet-up 220ms var( --tif-ease );
	}

	/* Dans la top layer, le navigateur applique ses propres marges, bordure et
	   dimensions « au contenu » : on les efface pour retrouver le plein écran.
	   La règle ci-dessus continue de fournir le reste. */
	.tif-js .tif-sheet[open] > .tif-sheet__panel:popover-open {
		margin: 0;
		border: 0;
		padding: 0;
		width: 100%;
		max-width: none;
		height: 100%;
		max-height: none;
	}

	@keyframes tif-sheet-up {
		from { transform: translateY( 3% ); opacity: 0; }
		to   { transform: none; opacity: 1; }
	}

	.tif-js .tif-sheet[open] > .tif-sheet__panel > .tif-sheet__head {
		display: flex;
		align-items: center;
		justify-content: space-between;
		gap: 12px;
		flex: 0 0 auto;
		padding: 16px 18px;
		border-bottom: 1px solid var( --tif-border-soft );
		background: var( --tif-surface );
		font-weight: 800;
		font-size: 17px;
	}

	/* Reprise du bouton de fermeture du menu mobile : croix Lucide de 40 px
	   dans un rond bordé, transparent, qui se teinte au survol. */
	.tif-js .tif-sheet__close {
		display: grid;
		place-items: center;
		padding: 8px;
		border: 1px solid var( --tif-border );
		border-radius: 999px;
		background: transparent;
		color: var( --tif-ink );
		cursor: pointer;
		transition: background-color 300ms ease;
	}

	.tif-js .tif-sheet__close:hover,
	.tif-js .tif-sheet__close:focus-visible {
		background: var( --tif-active-soft );
	}

	.tif-js .tif-sheet__close svg {
		display: block;
		width: 40px;
		height: 40px;
	}

	/* Les panneaux s'empilent au lieu de se déplier par-dessus. */
	.tif-js .tif-sheet[open] .tif-refine__row {
		flex: 1 1 auto;
		flex-direction: column;
		align-items: stretch;
		justify-content: flex-start;
		gap: 10px;
		overflow-y: auto;
		overscroll-behavior: contain;
		padding: 4px 14px 14px;
	}

	/* En rangée, `flex: 1 1 220px` sur la recherche répartit la largeur. Une
	   fois la rangée basculée en colonne, la même déclaration répartit la
	   *hauteur* : le champ gonflait jusqu'à occuper le milieu de l'écran et
	   poussait les filtres tout en bas. En pile, chaque élément prend sa
	   hauteur et rien d'autre. */
	.tif-js .tif-sheet[open] .tif-refine__row > * {
		flex: 0 0 auto;
	}

	.tif-js .tif-sheet[open] .tif-panel {
		width: 100%;
	}

	/* Le titre garde sa forme de pilule : passer d'un simple titre à une
	   pilule dès qu'un filtre est posé faisait sauter la pile. Seules les
	   couleurs distinguent désormais un panneau rempli d'un panneau vide. */
	.tif-js .tif-sheet[open] .tif-panel > summary {
		width: 100%;
		min-height: 52px;
		padding: 0 16px;
		border: 1px solid var( --tif-border );
		border-radius: var( --tif-radius );
		background: var( --tif-surface );
	}

	.tif-js .tif-sheet[open] .tif-panel .tif-pill__label {
		flex: 1 1 auto;
		text-align: left;
	}

	/* Le titre d'un panneau qui porte un filtre.
	 *
	 * La pilule pleine convient à une rangée : quelques mots sur fond prune.
	 * Étirée sur la largeur d'un téléphone, elle barre la feuille d'un
	 * bandeau prune foncé à chaque panneau rempli. C'est la même pilule, en
	 * clair : fond prune pâle, texte prune, décompte inversé.
	 *
	 * Il faut passer devant les règles `#page-container` qui imposent le fond
	 * prune et le texte crème — d'où la spécificité et les `!important`, qui
	 * en écrasent d'autres et non par confort. */
	html.tif-js .tif-sheet[open] .tif-panel > summary.is-on {
		border-color: transparent;
		background-color: var( --tif-active-soft ) !important;
	}

	html.tif-js .tif-sheet[open] .tif-panel > summary.is-on,
	html.tif-js .tif-sheet[open] .tif-panel > summary.is-on .tif-pill__label,
	html.tif-js .tif-sheet[open] .tif-panel > summary.is-on .tif-icon {
		color: var( --tif-active ) !important;
	}

	html.tif-js .tif-sheet[open] .tif-panel > summary.is-on .tif-pill__count {
		background: var( --tif-active );
		color: var( --tif-cream );
	}

	/* Ouverture et fermeture animées.
	 *
	 * Un `<details>` bascule d'ordinaire d'un coup. Ce qu'on anime ici est
	 * `::details-content`, la boîte que le navigateur pose autour du contenu :
	 * sa hauteur passe de zéro à `auto`, et `allow-discrete` maintient le
	 * contenu visible le temps de la fermeture — sans quoi il disparaîtrait
	 * avant que la hauteur ait bougé.
	 *
	 * `interpolate-size` est ce qui rend `auto` interpolable ; il est posé sur
	 * la feuille seule, pas sur le document, pour ne rien changer ailleurs.
	 * Un navigateur qui l'ignore ouvre le panneau d'un coup, comme avant. */
	.tif-js .tif-sheet {
		interpolate-size: allow-keywords;
	}

	.tif-js .tif-sheet[open] .tif-panel::details-content {
		block-size: 0;
		overflow: hidden;
		transition: all 300ms ease, content-visibility 300ms ease allow-discrete;
	}

	.tif-js .tif-sheet[open] .tif-panel[open]::details-content {
		block-size: auto;
	}

	/* --- 4. Signaler le chargement dans la feuille ---------------------
	 *
	 * La feuille vit dans la « top layer » : le voile posé sur la barre ne
	 * l'atteint pas, et rien n'indiquait qu'une réponse était en route. On
	 * touchait donc un deuxième filtre pendant le premier échange. */
	.tif-js .tif-sheet[open] > .tif-sheet__panel.is-busy::after {
		content: "";
		position: absolute;
		top: 0;
		left: 0;
		z-index: 2;
		width: 40%;
		height: 3px;
		background: var( --tif-active );
		animation: tif-sheet-load 900ms linear infinite;
	}

	@keyframes tif-sheet-load {
		from { transform: translateX( -100% ); }
		to   { transform: translateX( 250% ); }
	}

	/* Les filtres ne répondent plus, mais la croix reste accessible : une
	   requête qui traîne ne doit pas enfermer qui que ce soit. */
	.tif-js .tif-sheet[open] > .tif-sheet__panel.is-busy .tif-refine__row {
		opacity: 0.55;
		pointer-events: none;
		transition: opacity 160ms var( --tif-ease );
	}

	/* Plus de menu flottant : le corps prend sa place dans la pile. */
	.tif-js .tif-sheet[open] .tif-panel__body {
		position: static;
		width: auto;
		max-height: none;
		padding: 14px 16px 4px;
		border: none;
		border-radius: 0;
		background: transparent;
		box-shadow: none;
	}

	.tif-js .tif-sheet[open] .tif-search {
		max-width: none;
		margin: 0;
	}

	.tif-js .tif-sheet[open] > .tif-sheet__panel > .tif-sheet__foot {
		display: block;
		flex: 0 0 auto;
		padding: 12px 14px calc( 12px + env( safe-area-inset-bottom ) );
		border-top: 1px solid var( --tif-border-soft );
		background: var( --tif-surface );
	}

	.tif-js .tif-sheet[open] .tif-sheet__foot .tif-apply {
		width: 100%;
		min-height: 52px;
	}

	/* Les filtres actifs défilent au doigt plutôt que d'empiler des lignes. */
	.tif-chips {
		flex-wrap: nowrap;
		overflow-x: auto;
		scrollbar-width: none;
		padding-bottom: 2px;
	}

	.tif-chips::-webkit-scrollbar {
		display: none;
	}

	.tif-chip {
		flex: 0 0 auto;
	}
}


@media ( prefers-reduced-motion: reduce ) {
	.tif *,
	.tif *::before,
	.tif *::after {
		animation: none !important;
		transition: none !important;
	}

	.tif-scroller__viewport {
		scroll-behavior: auto;
	}
}
