/**
 * Modules panier Touchy Idea.
 *
 * Chaque couleur est déclarée en `var(--ti-xxx, #valeur)` : si la charte du
 * site définit déjà ces variables, elles l'emportent ; sinon on retombe sur la
 * valeur de la maquette. Redéfinir `--ti-plum-600` quelque part suffit donc à
 * repeindre les cinq modules d'un coup.
 */

.touchy_cart_items,
.touchy_free_shipping,
.touchy_gift_note,
.touchy_cart_summary,
.touchy_cross_sell {
	--tip-plum: var(--ti-plum-600, #66448f);
	--tip-plum-500: var(--ti-plum-500, #8662b0);
	--tip-plum-dark: var(--ti-plum-700, #4a2f70);
	--tip-elevated: var(--bg-elevated, var(--ti-white, #ffffff));
	--tip-plum-deep: var(--ti-plum-800, #2d1b47);
	--tip-plum-soft: var(--ti-plum-50, #f7eefc);
	--tip-plum-soft2: var(--ti-plum-100, #eeddf8);
	--tip-ink: var(--ti-ink, #2d1b47);
	--tip-mauve: var(--ti-mauve-500, #6f6580);
	--tip-mauve-light: var(--ti-mauve-400, #9c93ab);
	--tip-cream: var(--ti-cream, #f8f7f1);
	--tip-white: var(--ti-white, #ffffff);
	--tip-vanilla: var(--ti-vanilla, #fdfaf3);
	--tip-border: var(--ti-border, #ddd7c8);
	--tip-border-soft: var(--ti-border-soft, #ebe5d9);
	/* Cerise : réservé à ce qui doit attirer l'œil — le bouton d'achat, une
	   promotion, une erreur. Jamais pour un prix ordinaire. */
	--tip-cherry: var(--ti-cherry-500, #ff6fa5);
	--tip-cherry-soft: var(--ti-cherry-100, #ffe3ee);
	/* Pêche : la couleur des montants. Choix assumé de Lucas — le 600 est en
	   dessous du seuil de contraste (2,2:1 sur blanc), mais c'est celui qui
	   tient la charte. Les tons 700 à 900, lisibles, restent disponibles. */
	--tip-peach: var(--ti-peach-600, #f49680);
	--tip-peach-line: var(--ti-peach-500, #fec6b8);
	--tip-peach-tint: var(--ti-peach-300, #ffe3dc);
	--tip-peach-soft: var(--ti-peach-100, #fff6f2);
	--tip-mint: var(--ti-mint-600, #3e9c79);
	--tip-mint-soft: var(--ti-mint-200, #d7f0e6);
	--tip-mint-line: var(--ti-mint-400, #b8e5d4);
	--tip-banana-soft: var(--ti-banana-200, #fff0c2);
	--tip-banana-line: var(--ti-banana-400, #ffdd81);
	--tip-banana: var(--ti-banana-500, #e8bc4a);
	--tip-danger: var(--danger, #d1435b);
	--tip-danger-soft: var(--danger-bg, #fdeaed);
	--tip-shadow-1: 0 1px 2px rgba(45, 27, 71, 0.06), 0 2px 8px rgba(45, 27, 71, 0.05);
	--tip-shadow-2: 0 2px 6px rgba(45, 27, 71, 0.07), 0 12px 28px rgba(45, 27, 71, 0.08);
	--tip-shadow-cherry: 0 6px 18px rgba(255, 111, 165, 0.35);
	/* Halo de focus de la charte : cerise, sur tous les champs. */
	--tip-focus-ring: var(--focus-ring, 0 0 0 4px rgba(255, 111, 165, 0.32));
	--tip-ease: cubic-bezier(0.22, 1, 0.36, 1);

	color: var(--tip-ink);
	box-sizing: border-box;
}

.touchy_cart_items *,
.touchy_free_shipping *,
.touchy_gift_note *,
.touchy_cart_summary *,
.touchy_cross_sell * {
	box-sizing: border-box;
}

/* ==========================================================================
   Boutons partagés
   ========================================================================== */

.tip-btn {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: 8px;
	min-height: 44px;
	padding: 14px 26px;
	border: none;
	border-radius: 999px;
	font-weight: 800;
	font-size: 16px;
	letter-spacing: -0.02em;
	text-decoration: none;
	/* `justify-content` centre le bloc de texte dans le bouton, mais pas les
	   lignes les unes par rapport aux autres : dès que l'intitulé passe sur
	   deux lignes, la seconde se cale à gauche. */
	text-align: center;
	cursor: pointer;
	transition: transform 140ms var(--tip-ease), box-shadow 140ms var(--tip-ease);
}

.tip-btn--primary {
	background: var(--tip-cherry);
	color: #fff;
	box-shadow: var(--tip-shadow-cherry);
}

.tip-btn--soft {
	background: var(--tip-plum-soft);
	color: var(--tip-plum-dark);
	padding: 10px 18px;
	font-size: 15px;
}

.tip-btn:hover {
	transform: translateY(-1px);
}

.tip-btn[disabled],
.tip-btn.is-busy {
	opacity: 0.6;
	pointer-events: none;
}

/* ==========================================================================
   1. Articles du panier
   ========================================================================== */

.tip-items {
	display: flex;
	flex-direction: column;
	gap: 14px;
	/* Les lignes produit se replient selon la largeur de la colonne Divi qui
	   les contient, pas selon celle du navigateur : le module peut très bien
	   vivre dans une colonne étroite sur un grand écran. */
	container-type: inline-size;
	container-name: tip-items;
}

.tip-item {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 18px;
	padding: 16px;
	border: 1px solid var(--tip-border-soft);
	border-radius: 28px;
	background: var(--tip-white);
	box-shadow: var(--tip-shadow-1);
	transition: opacity 160ms var(--tip-ease);
}

.tip-item.is-busy {
	opacity: 0.55;
	pointer-events: none;
}

.tip-item__thumb {
	flex: 0 0 auto;
	display: grid;
	place-items: center;
	width: 118px;
	height: 118px;
	overflow: hidden;
	border-radius: 62% 38% 55% 45% / 50% 55% 45% 50%;
	background: var(--tip-plum-soft);
	text-decoration: none;
}

.tip-item__thumb img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	display: block;
}

.tip-item__info {
	flex: 1 1 200px;
	min-width: 170px;
}

.tip-item__badge {
	display: inline-block;
	margin-bottom: 7px;
	padding: 3px 9px;
	border-radius: 999px;
	background: var(--tip-banana);
	color: var(--tip-plum-deep);
	font-size: 11px;
	font-weight: 700;
}

.tip-item__name {
	display: block;
	margin-bottom: 5px;
	color: var(--tip-ink);
	font-size: 23px;
	font-weight: 800;
	line-height: 1.15;
	letter-spacing: -0.025em;
	text-decoration: none;
}

.tip-item__variant {
	margin-bottom: 8px;
	color: var(--tip-mauve);
	font-size: 14px;
}

.tip-item__stock {
	color: var(--tip-mint);
	font-size: 13px;
	font-weight: 600;
}

.tip-item__stock--out {
	color: var(--tip-danger);
}

/* Contenu d'un lot -------------------------------------------------------- */

.tip-bundle {
	margin: 12px 0 10px;
	padding: 12px 14px 10px;
	border-radius: 16px;
	background: var(--tip-plum-soft);
}

.tip-bundle__label {
	margin: 0 0 8px;
	color: var(--tip-plum-dark);
	font-size: 11px;
	font-weight: 700;
	letter-spacing: 0.08em;
	text-transform: uppercase;
}

.tip-bundle__list {
	margin: 0;
	padding: 0;
	list-style: none;
}

.tip-bundle__item {
	display: flex;
	align-items: center;
	gap: 10px;
	padding: 5px 0;
	color: var(--tip-ink);
	font-size: 14.5px;
	line-height: 1.4;
}

.tip-bundle__item + .tip-bundle__item {
	border-top: 1px solid rgba(102, 68, 143, 0.1);
}

/* Pastille ronde : la quantité se lit d'un coup d'œil, et les chiffres
   tabulaires gardent toutes les pastilles alignées. */
.tip-bundle__qty {
	display: grid;
	flex: 0 0 auto;
	place-items: center;
	width: 24px;
	height: 24px;
	border-radius: 999px;
	background: var(--tip-plum);
	color: #fff;
	font-size: 12.5px;
	font-weight: 700;
	font-variant-numeric: tabular-nums;
	line-height: 1;
}

.tip-bundle__name {
	flex: 1;
	min-width: 0;
	color: var(--tip-ink);
}

.tip-bundle__variant {
	display: block;
	color: var(--tip-mauve-light);
	font-size: 12.5px;
}

.tip-bundle__price {
	flex: 0 0 auto;
	color: var(--tip-mauve);
	font-size: 13px;
	font-weight: 600;
	white-space: nowrap;
}

/* Le lot se lit comme un tout : on appuie légèrement sa ligne pour qu'on ne
   la confonde pas avec un produit ordinaire. */
.tip-item--bundle {
	border-color: var(--tip-plum-soft2);
}

.tip-stepper {
	flex: 0 0 auto;
	display: inline-flex;
	align-items: center;
	gap: 3px;
	padding: 5px;
	border: 1px solid var(--tip-border);
	border-radius: 999px;
	background: var(--tip-cream);
}

/* Les signes sont des SVG et non des caractères : les glyphes « + » et « − »
   n'ont pas de métriques symétriques — le signe moins se cale sur l'axe
   mathématique, pas sur le centre optique — et aucun centrage CSS ne rattrape
   ce décalage. Un tracé dans un carré de 16 se centre, lui, exactement. */
.tip-stepper__btn {
	display: grid;
	place-items: center;
	width: 38px;
	height: 38px;
	padding: 0;
	margin: 0;
	border: none;
	border-radius: 999px;
	background: transparent;
	color: var(--tip-plum-dark);
	line-height: 0;
	cursor: pointer;
	-webkit-appearance: none;
	appearance: none;
	transition: background 140ms var(--tip-ease);
}

.tip-stepper__btn svg {
	display: block;
}

.tip-stepper__btn:hover {
	background: var(--tip-plum-soft2);
}

.tip-stepper__qty {
	min-width: 30px;
	color: var(--tip-ink);
	font-size: 16.5px;
	font-weight: 700;
	/* Chiffres à chasse fixe : sans ça, passer de 9 à 10 élargit le compteur
	   et fait sauter les deux boutons. */
	font-variant-numeric: tabular-nums;
	text-align: center;
}

.tip-item__price {
	flex: 0 0 auto;
	min-width: 96px;
	text-align: right;
}

.tip-item__total {
	color: var(--tip-peach);
	font-size: 24px;
	font-weight: 800;
	line-height: 1.1;
	letter-spacing: -0.025em;
}

.tip-item__unit {
	margin-top: 2px;
	color: var(--tip-mauve-light);
	font-size: 12.5px;
}

/* Économie d'un lot : prix normal barré au-dessus, pastille en dessous. */
.tip-item__was {
	margin-bottom: 1px;
	color: var(--tip-mauve-light);
	font-size: 14px;
	text-decoration: line-through;
	text-decoration-thickness: 1.5px;
}

.tip-item__saving {
	display: inline-block;
	margin-top: 6px;
	padding: 3px 10px;
	border-radius: 999px;
	background: var(--tip-mint-soft);
	color: var(--tip-mint);
	font-size: 12px;
	font-weight: 700;
	white-space: nowrap;
}


/* Panier vide */

.tip-empty {
	padding: clamp(32px, 6vw, 64px);
	border: 1px solid var(--tip-border-soft);
	border-radius: 40px;
	background: var(--tip-white);
	box-shadow: var(--tip-shadow-1);
	text-align: center;
}

.tip-empty__blob {
	display: grid;
	place-items: center;
	width: 130px;
	height: 130px;
	margin: 0 auto 26px;
	border-radius: 62% 38% 55% 45% / 50% 55% 45% 50%;
	background: linear-gradient(140deg, var(--tip-plum-soft2), var(--tip-peach-tint));
	color: var(--tip-plum);
}

.tip-empty__title {
	margin: 0 0 12px;
	color: var(--tip-ink);
	font-size: clamp(26px, 3.4vw, 36px);
	font-weight: 800;
	line-height: 1.1;
	letter-spacing: -0.035em;
}

.tip-empty__text {
	max-width: 44ch;
	margin: 0 auto 28px;
	color: var(--tip-mauve);
	font-size: 17px;
	line-height: 1.65;
}

/* ==========================================================================
   2. Jauge de livraison offerte
   ========================================================================== */

.tip-gauge {
	padding: 20px 22px;
	border: 1px solid var(--tip-banana-line);
	border-radius: 24px;
	background: var(--tip-banana-soft);
}

.tip-gauge--reached {
	border-color: var(--tip-mint-line);
	background: var(--tip-mint-soft);
}

.tip-gauge__head {
	display: flex;
	flex-wrap: wrap;
	align-items: baseline;
	justify-content: space-between;
	gap: 10px;
	margin-bottom: 12px;
}

.tip-gauge__title {
	color: var(--tip-ink);
	font-size: 20px;
	font-weight: 800;
	line-height: 1.2;
	letter-spacing: -0.02em;
}

.tip-gauge__hint {
	color: var(--tip-mauve);
	font-size: 13.5px;
	font-weight: 600;
}

.tip-gauge__track {
	height: 12px;
	overflow: hidden;
	border: 1px solid var(--tip-border-soft);
	border-radius: 999px;
	background: var(--tip-white);
}

.tip-gauge__fill {
	height: 100%;
	border-radius: 999px;
	background: linear-gradient(90deg, var(--tip-cherry), var(--tip-plum));
	transition: width 260ms var(--tip-ease);
}

.tip-gauge--reached .tip-gauge__fill {
	background: linear-gradient(90deg, var(--tip-mint-line), var(--tip-mint));
}

/* ==========================================================================
   3. Petit mot glissé dans le colis
   ========================================================================== */

.tip-gift {
	padding: 20px;
	border: 1px solid var(--tip-border-soft);
	border-radius: 24px;
	background: var(--tip-vanilla);
}

.tip-gift__label {
	display: flex;
	align-items: flex-start;
	gap: 14px;
	cursor: pointer;
}

.tip-gift__label + .tip-gift__label {
	margin-top: 14px;
	padding-top: 14px;
	border-top: 1px solid var(--tip-border-soft);
}

/* La vraie case reste dans le flux pour le clavier et les lecteurs d'écran,
   mais c'est le carré dessiné qui s'affiche. */
.tip-gift__checkbox {
	position: absolute;
	width: 1px;
	height: 1px;
	margin: -1px;
	padding: 0;
	overflow: hidden;
	clip: rect(0 0 0 0);
	white-space: nowrap;
	border: 0;
}

.tip-gift__box {
	position: relative;
	flex: 0 0 auto;
	width: 26px;
	height: 26px;
	margin-top: 1px;
	display: grid;
	place-items: center;
	border: 2px solid var(--tip-border);
	border-radius: 9px;
	background: var(--tip-white);
	color: transparent;
	font-size: 15px;
	line-height: 1;
	transition: all 300ms ease;
}

/* La coche est le caractère U+2713, posé dans une grille centrée. L'ancien
   dessin — deux bordures et une rotation de 45° — ne pouvait pas être centré :
   le carré tourné n'a pas le même centre optique que son cadre. */
.tip-gift__box::after {
	content: "\2713";
	font-weight: 700;
}

.tip-gift__checkbox:checked + .tip-gift__box,
.tip-gift__box--on {
	/* Un état de sélection n'est ni une alerte ni une offre : c'est le prune
	   de la charte qui s'applique, pas le cerise. */
	border-color: var(--tip-plum);
	background: var(--tip-plum);
	color: #fff;
}

.tip-gift__checkbox:focus-visible + .tip-gift__box {
	border-color: var(--tip-plum-500);
	box-shadow: var(--tip-focus-ring);
}

.tip-gift__copy {
	display: block;
}

.tip-gift__title {
	display: block;
	margin-bottom: 4px;
	color: var(--tip-ink);
	font-size: 15.5px;
	font-weight: 700;
}

.tip-gift__text {
	display: block;
	color: var(--tip-mauve);
	font-size: 14px;
	line-height: 1.6;
}

.tip-gift__field {
	margin-top: 14px;
}

.tip-gift__field[hidden] {
	display: none;
}

/* Règle « Form fields » de la charte : input, select et textarea se présentent
   tous de la même façon, et le focus est un halo cerise — jamais prune. */
.tip-gift__input {
	width: 100%;
	padding: 13px 16px;
	border: 1.5px solid var(--tip-border);
	border-radius: 14px;
	background: var(--tip-elevated);
	color: var(--tip-ink);
	font-family: inherit;
	font-size: 15px;
	line-height: 1.5;
	resize: vertical;
	transition: all 300ms ease;
}

.tip-gift__input:focus {
	outline: none;
	border-color: var(--tip-plum-500);
	box-shadow: var(--tip-focus-ring);
}

.tip-gift__meta {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 8px;
	margin-top: 6px;
	color: var(--tip-mauve-light);
	font-size: 12.5px;
	font-variant-numeric: tabular-nums;
}

.tip-gift__status {
	color: var(--tip-mint);
	font-weight: 600;
}

/* ==========================================================================
   4. Récapitulatif
   ========================================================================== */

.tip-summary {
	position: relative;
	/* Même raison que .tip-items : dans une colonne latérale étroite, le total
	   doit se replier même si la fenêtre, elle, est large. */
	container-type: inline-size;
	container-name: tip-summary;
	padding: clamp(18px, 4.5vw, 26px);
	border: 1px solid var(--tip-border);
	border-radius: 32px;
	background: var(--tip-white);
	box-shadow: var(--tip-shadow-2);
}

/* Pendant un recalcul, le récapitulatif se voile et tourne : sans ça, un
   changement de livraison semble ne rien faire. */
.tip-summary.is-loading {
	pointer-events: none;
}

.tip-summary.is-loading::after {
	content: "";
	position: absolute;
	z-index: 1;
	inset: 0;
	border-radius: inherit;
	background: rgba(255, 255, 255, 0.6);
}

.tip-summary.is-loading::before {
	content: "";
	position: absolute;
	z-index: 2;
	top: 50%;
	left: 50%;
	width: 26px;
	height: 26px;
	margin: -13px 0 0 -13px;
	border: 2.5px solid var(--tip-plum-soft2);
	border-top-color: var(--tip-plum);
	border-radius: 999px;
	animation: tip-spin 700ms linear infinite;
}

@keyframes tip-spin {
	to {
		transform: rotate(360deg);
	}
}

.tip-summary__title {
	margin-bottom: 20px;
	color: var(--tip-ink);
	font-size: 27px;
	font-weight: 800;
	line-height: 1.1;
	letter-spacing: -0.03em;
}

.tip-shipping {
	margin-bottom: 20px;
}

.tip-shipping__label {
	margin-bottom: 10px;
	color: var(--tip-mauve-light);
	font-size: 12px;
	font-weight: 700;
	letter-spacing: 0.08em;
	text-transform: uppercase;
}

.tip-shipping__options {
	display: flex;
	flex-direction: column;
	gap: 8px;
}

.tip-shipping__pending {
	margin: 0;
	color: var(--tip-mauve);
	font-size: 14px;
	line-height: 1.55;
}

/* Choix du pays -------------------------------------------------------- */

.tip-country {
	margin-bottom: 10px;
}

/* Le Design System traite `select` exactement comme `input` et `textarea` :
   même règle « .field input, .field select, .field textarea ».
   Repères de la carte « Form fields » : rayon 14 px, bordure 1.5 px, fond
   élevé, et halo cerise au focus. */
.tip-country {
	display: flex;
	flex-direction: column;
	gap: 6px;
	margin-bottom: 14px;
}

.tip-country__label {
	color: var(--tip-ink);
	font-size: 13px;
	font-weight: 600;
}

.tip-country__select {
	width: 100%;
	padding: 12px 40px 12px 14px;
	border: 1.5px solid var(--tip-border);
	border-radius: 14px;
	background-color: var(--tip-elevated);
	color: var(--tip-ink);
	font-family: inherit;
	font-size: 15px;
	line-height: 1.3;
	cursor: pointer;
	-webkit-appearance: none;
	appearance: none;
	transition: all 300ms ease;
	/* Chevron dessiné en SVG encodé : pas de fichier externe à charger. */
	background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath fill='none' stroke='%236F6580' stroke-width='2' stroke-linecap='round' stroke-linejoin='round' d='M4 6l4 4 4-4'/%3E%3C/svg%3E");
	background-repeat: no-repeat;
	background-position: right 14px center;
	background-size: 15px 15px;
}

/* Une seconde règle `:focus` traînait ici, posée avant que le sélecteur ne
   suive la charte : son contour prune écrasait le halo cerise, plus bas dans
   le fichier donc gagnant. C'est ce qu'on voyait à l'écran. */
.tip-country__select:focus {
	outline: none;
	border-color: var(--tip-plum-500);
	box-shadow: var(--tip-focus-ring);
}

.tip-country__select:disabled {
	opacity: 0.6;
	cursor: wait;
}

.tip-ship {
	display: flex;
	align-items: center;
	gap: 12px;
	width: 100%;
	min-height: 44px;
	padding: 14px 16px;
	border: 1px solid var(--tip-border);
	border-radius: 18px;
	background: var(--tip-white);
	color: var(--tip-mauve);
	font-family: inherit;
	text-align: left;
	cursor: pointer;
	transition: all 140ms var(--tip-ease);
}

.tip-ship--on {
	padding: 13px 15px;
	border: 2px solid var(--tip-peach-line);
	background: var(--tip-peach-soft);
	color: var(--tip-plum-deep);
}

.tip-ship__label {
	flex: 1;
	font-size: 14.5px;
	font-weight: 700;
}

.tip-ship__price {
	flex: 0 0 auto;
	font-size: 14.5px;
	font-weight: 700;
}

/* Code promo ------------------------------------------------------------- */

.tip-promo {
	margin-bottom: 18px;
	padding-bottom: 18px;
	border-bottom: 1px dashed var(--tip-border);
}

.tip-promo__label {
	display: block;
	margin-bottom: 7px;
	color: var(--tip-ink);
	font-size: 13px;
	font-weight: 600;
}

.tip-promo__row {
	display: flex;
	flex-wrap: wrap;
	align-items: stretch;
	gap: 8px;
}

/* Règle « Form fields » de la charte, halo cerise compris.
 *
 * `min-height` et non la seule hauteur naturelle : dans une rangée flex, le
 * champ s'étirait à la hauteur du bouton tant qu'ils tenaient côte à côte, et
 * retombait à sa hauteur propre dès que ça passait à la ligne. D'où une
 * hauteur qui semblait dépendre de la largeur de la fenêtre.
 *
 * Le padding est répété avec la classe racine du module : Divi pose ses
 * propres règles sur les `input` avec une spécificité que notre sélecteur seul
 * n'atteint pas, et c'est son padding nul qu'on voyait. */
.tip-promo__input {
	flex: 1 1 130px;
	min-width: 0;
	min-height: 44px;
	padding: 12px 14px;
	border: 1.5px solid var(--tip-border);
	border-radius: 14px;
	background: var(--tip-elevated);
	color: var(--tip-ink);
	font-family: inherit;
	font-size: 15px;
	text-transform: uppercase;
	transition: all 300ms ease;
}

.tip-promo__input::placeholder {
	color: var(--tip-mauve-light);
	text-transform: none;
}

.tip-promo__input:focus {
	outline: none;
	border-color: var(--tip-plum-500);
	box-shadow: var(--tip-focus-ring);
}

/* Rayon repris du formulaire de newsletter du pied de page : 14 px, comme le
   champ. Une pilule à côté d'un champ à 14 px jurait. */
.tip-promo__submit {
	flex: 0 0 auto;
	min-height: 44px;
	border-radius: 14px;
}

/* Reprise sous la classe racine du module, pour passer devant Divi. */
.touchy_cart_summary .tip-promo__input {
	padding: 12px 14px;
	min-height: 44px;
	border-radius: 14px;
}

/* Le retrait à gauche venait de la règle de liste du thème, que notre remise à
   zéro n'atteignait pas : on repasse par la classe racine du module. */
.tip-promo__list,
.touchy_cart_summary .tip-promo__list,
.touchy_checkout_summary .tip-promo__list {
	display: flex;
	flex-direction: column;
	gap: 8px;
	margin: 12px 0 0;
	padding: 0 !important;
	list-style: none;
}

/* La pastille occupe la largeur du bloc. Le code prend la place disponible et
   se coupe s'il est trop long ; le montant de la réduction, lui, reste calé à
   droite et entier — c'est l'information qui compte. */
.tip-promo__chip {
	display: flex;
	align-items: center;
	gap: 10px;
	width: 100%;
	padding: 8px 8px 8px 14px;
	border-radius: 999px;
	background: var(--tip-mint-soft);
	color: var(--tip-mint);
	font-size: 13px;
	font-weight: 700;
}

.tip-promo__code {
	flex: 1 1 auto;
	min-width: 0;
	overflow: hidden;
	white-space: nowrap;
	text-overflow: ellipsis;
}

.tip-promo__amount {
	flex: 0 0 auto;
	font-variant-numeric: tabular-nums;
	white-space: nowrap;
}

.tip-promo__drop {
	display: grid;
	place-items: center;
	width: 22px;
	height: 22px;
	padding: 0;
	border: none;
	border-radius: 999px;
	background: rgba(255, 255, 255, 0.6);
	color: inherit;
	cursor: pointer;
	transition: all 300ms ease;
}

.tip-promo__drop:hover {
	background: var(--tip-danger-soft);
	color: var(--tip-danger);
}

.tip-promo__drop.is-busy {
	opacity: 0.5;
	pointer-events: none;
}

.tip-summary__totals {
	display: flex;
	flex-direction: column;
	gap: 11px;
	margin-bottom: 18px;
}

.tip-total {
	display: flex;
	align-items: baseline;
	justify-content: space-between;
	gap: 12px;
	color: var(--tip-mauve);
	font-size: 15px;
}

.tip-total span:last-child {
	color: var(--tip-ink);
	font-size: 15.5px;
	font-weight: 700;
}

.tip-total--free span:last-child {
	color: var(--tip-mint);
}

.tip-total--warn span:last-child {
	color: var(--tip-danger);
}

.tip-total--muted,
.tip-total--muted span:last-child {
	color: var(--tip-mauve-light);
	font-size: 13.5px;
	font-weight: 600;
}

.tip-summary__grand {
	display: flex;
	align-items: baseline;
	justify-content: space-between;
	gap: 12px;
	padding-top: 18px;
	border-top: 1px solid var(--tip-border);
	color: var(--tip-ink);
	font-size: 24px;
	font-weight: 800;
	letter-spacing: -0.03em;
}

.tip-summary__amount {
	color: var(--tip-peach);
	font-size: 34px;
	line-height: 1;
}

.tip-summary__tax {
	margin-top: 4px;
	color: var(--tip-mauve-light);
	font-size: 12.5px;
	text-align: right;
}

.tip-summary__cta {
	width: 100%;
	margin-top: 20px;
	padding: 17px 26px;
	font-size: 19px;
}

/* Bouton neutralisé : le panier ne peut pas partir en l'état. Il reste lisible
   — le masquer laisserait croire à un bug — mais ne réagit plus. */
.tip-summary__cta.is-blocked {
	background: var(--tip-plum-soft2);
	color: var(--tip-mauve);
	cursor: not-allowed;
	box-shadow: none;
	pointer-events: none;
}

.tip-summary__hint {
	margin: 10px 0 0;
	color: var(--tip-mauve-light);
	font-size: 12.5px;
	line-height: 1.5;
	text-align: center;
}

/* ==========================================================================
   5. Suggestions de fin de page
   ========================================================================== */

.tip-xsell__title {
	margin: 0 0 6px;
	color: var(--tip-ink);
	font-size: clamp(28px, 3.6vw, 40px);
	font-weight: 800;
	line-height: 1.05;
	letter-spacing: -0.035em;
}

.tip-xsell__subtitle {
	margin: 0 0 26px;
	color: var(--tip-mauve);
	font-size: 16px;
}

.tip-xsell__grid {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(min(210px, 100%), 1fr));
	gap: 16px;
}

.tip-xsell__card {
	display: flex;
	flex-direction: column;
	overflow: hidden;
	border: 1px solid var(--tip-border-soft);
	border-radius: 26px;
	background: var(--tip-white);
	box-shadow: var(--tip-shadow-1);
	transition: transform 140ms var(--tip-ease), box-shadow 140ms var(--tip-ease);
}

.tip-xsell__card:hover {
	transform: translateY(-3px);
	box-shadow: var(--tip-shadow-2);
}

.tip-xsell__thumb {
	display: block;
	height: 170px;
	background: var(--tip-plum-soft);
}

.tip-xsell__thumb img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	display: block;
}

.tip-xsell__body {
	display: flex;
	flex: 1;
	flex-direction: column;
	padding: 16px 18px 18px;
}

.tip-xsell__name {
	margin-bottom: 6px;
	color: var(--tip-ink);
	font-size: 21px;
	font-weight: 800;
	line-height: 1.15;
	letter-spacing: -0.025em;
	text-decoration: none;
}

.tip-xsell__blurb {
	flex: 1;
	margin: 0 0 14px;
	color: var(--tip-mauve);
	font-size: 14px;
	line-height: 1.55;
}

.tip-xsell__foot {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 10px;
}

.tip-xsell__price {
	color: var(--tip-peach);
	font-size: 21px;
	font-weight: 800;
	letter-spacing: -0.025em;
}

/* ==========================================================================
   États transverses
   ========================================================================== */

.tip-error {
	margin-top: 12px;
	padding: 12px 16px;
	border: 1px solid var(--tip-danger);
	border-radius: 14px;
	background: var(--tip-danger-soft);
	color: var(--tip-danger);
	font-size: 14px;
}


/* ==========================================================================
   Alertes — bandeau fixe
   ==========================================================================

   Les messages de WooCommerce étaient imprimés par le thème en tête de page,
   en gris et sans fond : au-dessus de la ligne de flottaison sur grand écran,
   invisibles dès qu'on avait fait défiler. Ils sont déplacés ici, en haut de la
   fenêtre, où ils suivent le regard.
   ========================================================================== */

.tip-alerts {
	position: fixed;
	/* Valeur de repli, sous un menu de hauteur courante : le script la remplace
	   par la hauteur réelle de l'en-tête quand il en trouve un, fixe ou
	   collant. Sans ça, le message tombe derrière le menu. */
	top: 200px;
	left: 50%;
	z-index: 99999;
	display: flex;
	flex-direction: column;
	gap: 10px;
	width: min(92vw, 560px);
	transform: translateX(-50%);
	pointer-events: none;
}

.tip-alert {
	display: flex;
	align-items: flex-start;
	gap: 12px;
	padding: 16px 18px;
	border-radius: 20px;
	background: var(--ti-cherry-500, #ff6fa5);
	color: #fff;
	font-family: inherit;
	font-size: 15px;
	font-weight: 600;
	line-height: 1.5;
	text-align: left;
	box-shadow: 0 2px 6px rgba(45, 27, 71, 0.07), 0 12px 28px rgba(45, 27, 71, 0.18);
	pointer-events: auto;
	animation: tip-alert-in 520ms cubic-bezier(0.22, 1, 0.36, 1);
}

.tip-alert::before {
	content: "!";
	flex: 0 0 auto;
	display: grid;
	place-items: center;
	width: 24px;
	height: 24px;
	border-radius: 999px;
	background: rgba(255, 255, 255, 0.28);
	font-size: 15px;
	font-weight: 800;
}

.tip-alert--success {
	background: var(--ti-mint-200, #d7f0e6);
	color: var(--ti-plum-800, #2d1b47);
}

.tip-alert--success::before {
	content: "\2713";
	background: var(--ti-mint-400, #b8e5d4);
	color: var(--ti-mint-600, #3e9c79);
}

.tip-alert--info {
	background: var(--ti-banana-200, #fff0c2);
	color: var(--ti-plum-800, #2d1b47);
}

.tip-alert--info::before {
	background: var(--ti-banana-400, #ffdd81);
	color: var(--ti-plum-800, #2d1b47);
}

.tip-alert__text {
	flex: 1;
	min-width: 0;
}

/* La croix est un tracé SVG : le caractère « × » n'a pas son centre optique au
   milieu de sa boîte, et aucune règle de centrage ne rattrape ça. */
.tip-alert__close {
	flex: 0 0 auto;
	display: grid;
	place-items: center;
	width: 26px;
	height: 26px;
	padding: 0;
	border: none;
	border-radius: 999px;
	background: rgba(255, 255, 255, 0.2);
	color: inherit;
	cursor: pointer;
}

.tip-alert__close svg {
	display: block;
}

/* Une descente franche, puis un léger dépassement : le mouvement attire l'œil
   sans clignoter. */
@keyframes tip-alert-in {
	0%   { opacity: 0; transform: translateY(-24px); }
	60%  { opacity: 1; transform: translateY(5px); }
	100% { opacity: 1; transform: translateY(0); }
}

@media (prefers-reduced-motion: reduce) {
	.tip-alert {
		animation: none;
	}
}

/* ==========================================================================
   Messages de WooCommerce
   ==========================================================================

   WooCommerce dépose ses messages — stock insuffisant, code promo refusé,
   champ manquant — dans une file que le thème affiche à sa manière, ici sans
   fond et en gris. On les reprend pour les rendre nous-mêmes, en tête de page.
   ========================================================================== */

.tip-notices {
	position: sticky;
	top: 0;
	z-index: 60;
	display: flex;
	flex-direction: column;
	gap: 10px;
	margin-bottom: 20px;
}

.tip-notice {
	display: flex;
	align-items: flex-start;
	gap: 12px;
	padding: 15px 18px;
	border-radius: 20px;
	background: var(--tip-cherry);
	color: #fff;
	font-size: 15px;
	font-weight: 600;
	line-height: 1.5;
	box-shadow: var(--tip-shadow-2);
	animation: tip-notice-in 520ms var(--tip-ease);
}

.tip-notice::before {
	content: "!";
	flex: 0 0 auto;
	display: grid;
	place-items: center;
	width: 22px;
	height: 22px;
	border-radius: 999px;
	background: rgba(255, 255, 255, 0.25);
	font-size: 14px;
	font-weight: 800;
}

.tip-notice--success {
	background: var(--tip-mint-soft);
	color: var(--tip-plum-deep);
}

.tip-notice--success::before {
	content: "\2713";
	background: var(--tip-mint-line);
	color: var(--tip-mint);
}

.tip-notice--info {
	background: var(--tip-banana-soft);
	color: var(--tip-plum-deep);
}

.tip-notice--info::before {
	background: var(--tip-banana-line);
	color: var(--tip-plum-deep);
}

.tip-notice__list {
	margin: 6px 0 0;
	padding-left: 18px;
}

/* Une seule oscillation : de quoi accrocher l'œil sans donner l'impression
   que la page a un problème. */
@keyframes tip-notice-in {
	0%   { opacity: 0; transform: translateY(-14px); }
	60%  { opacity: 1; transform: translateY(3px); }
	100% { opacity: 1; transform: translateY(0); }
}

/* ==========================================================================
   Repli — largeur du conteneur, pas de la fenêtre
   ==========================================================================

   Ces modules vivent dans des colonnes Divi. Une barre latérale de 300 px sur
   un écran de 1400 px a la place d'un téléphone, mais aucune `@media` ne le
   sait : elles mesurent la fenêtre. D'où les `@container`.

   Le bloc `@media` d'origine est conservé plus bas, sous `@supports not`, pour
   les navigateurs antérieurs à 2023 qui ignorent les requêtes de conteneur.
   ========================================================================== */

/* Ligne produit : la corbeille passe à gauche de la seconde ligne, quantité et
   prix sont poussés à droite. Ils descendent tous les trois d'un coup, à un
   seuil décidé ici — avant, `flex-wrap` les faisait tomber un par un, et le
   moment où ça cassait dépendait de la longueur du nom du produit. */
/* Palier intermédiaire : la carte n'a plus la place de tenir prix et quantité
   sur la même ligne que le texte, mais elle est encore trop large pour la
   disposition téléphone. Le prix prend sa propre ligne, aligné à droite, et la
   quantité passe dessous. Avant, `flex-wrap` renvoyait le prix seul à la ligne,
   sous le texte, loin de la quantité à laquelle il se rapporte. */
@container tip-items (min-width: 561px) and (max-width: 720px) {
	.tip-item {
		display: grid;
		grid-template-areas:
			"thumb info"
			".     price"
			".     qty";
		grid-template-columns: 118px minmax(0, 1fr);
		align-items: center;
		column-gap: 18px;
		row-gap: 12px;
	}

	.tip-item__thumb {
		grid-area: thumb;
	}

	.tip-item__info {
		grid-area: info;
		min-width: 0;
	}

	.tip-item__price {
		grid-area: price;
		text-align: right;
		white-space: normal;
	}

	.tip-stepper {
		grid-area: qty;
		justify-self: start;
	}
}

@container tip-items (max-width: 560px) {
	/*
	 * Deux lignes : la vignette et le texte, puis la quantité à gauche et le
	 * prix à droite.
	 *
	 * La seconde ligne traverse toute la carte au lieu de se contenter de la
	 * colonne de droite : les deux éléments demandent environ 212 px et la
	 * carte en offre 254 à l'intérieur de ses marges. Ils tiennent donc, alors
	 * qu'ils ne tenaient pas dans les 156 px de la seule colonne de droite —
	 * c'est ce qui écrasait le sélecteur et faisait sortir le prix.
	 *
	 * Ils partagent la même cellule, l'un calé à gauche, l'autre à droite. Rien
	 * ne les autorise à se comprimer, donc rien ne se déforme.
	 */
	.tip-item {
		display: grid;
		grid-template-areas: "thumb info";
		grid-template-columns: 84px minmax(0, 1fr);
		align-items: center;
		column-gap: 14px;
		row-gap: 14px;
		padding: 14px;
		border-radius: 24px;
	}

	.tip-item__thumb {
		grid-area: thumb;
		width: 84px;
		height: 84px;
	}

	.tip-item__info {
		grid-area: info;
		min-width: 0;
	}

	.tip-item__name {
		font-size: 21px;
		line-height: 1.2;
	}


	.tip-stepper {
		grid-column: 1 / -1;
		grid-row: 2;
		justify-self: start;
		/* Le sélecteur ne se comprime jamais : sa pilule perdrait sa forme. */
		flex: 0 0 auto;
	}

	.tip-item__price {
		grid-column: 1 / -1;
		grid-row: 2;
		justify-self: end;
		text-align: right;
		/* La pastille d'économie doit pouvoir passer à la ligne… */
		white-space: normal;
	}

	.tip-item__total {
		/* …mais jamais le montant lui-même. */
		white-space: nowrap;
	}
}

/* Carte vraiment très étroite — colonne latérale, ou téléphone ancien en
   grande police. Les deux éléments ne tiennent plus côte à côte : la quantité
   passe au-dessus du prix, tous deux calés à droite, plutôt que de se
   chevaucher. */
@container tip-items (max-width: 330px) {
	.tip-item__price,
	.tip-stepper {
		grid-column: 2;
	}

	.tip-stepper {
		grid-row: 2;
		justify-self: end;
	}

	.tip-item__price {
		grid-row: 3;
		justify-self: end;
	}
}

/* Récapitulatif : le grand total débordait du cadre dès que la colonne était
   étroite, faute de pouvoir se replier. */
@container tip-summary (max-width: 340px) {
	.tip-summary__grand {
		flex-wrap: wrap;
		row-gap: 2px;
		font-size: 19px;
	}

	.tip-summary__amount {
		margin-left: auto;
		font-size: 28px;
	}

	.tip-total {
		flex-wrap: wrap;
		row-gap: 2px;
	}

	.tip-total span:last-child {
		margin-left: auto;
	}
}

/* ==========================================================================
   Téléphone — repli pour les navigateurs sans `@container`
   ========================================================================== */

@supports not (container-type: inline-size) {

@media (max-width: 700px) {
	.tip-item {
		position: relative;
		display: grid;
		grid-template-areas:
			"thumb info"
			"qty   price";
		grid-template-columns: 84px minmax(0, 1fr);
		column-gap: 14px;
		row-gap: 14px;
		padding: 14px;
		border-radius: 24px;
	}

	.tip-item__thumb {
		grid-area: thumb;
		width: 84px;
		height: 84px;
	}

	.tip-item__info {
		grid-area: info;
		min-width: 0;
	}

	.tip-item__name {
		font-size: 21px;
		line-height: 1.2;
	}

	.tip-stepper {
		grid-area: qty;
		justify-self: start;
	}

	.tip-item__price {
		grid-area: price;
		/* Le montant reste d'un seul tenant, mais la pastille d'économie doit
		   pouvoir passer à la ligne plutôt que de déborder. */
		white-space: normal;
	}

	.tip-item__total {
		white-space: nowrap;
	}


	.tip-summary__amount {
		font-size: 28px;
	}
}

} /* fin de @supports not (container-type: inline-size) */

@media (prefers-reduced-motion: reduce) {
	.tip-btn,
	.tip-gauge__fill,
	.tip-xsell__card,
	.tip-country__select,

	/* Le voile reste — c'est lui qui signale l'attente — mais on arrête la
	   rotation plutôt que de la ralentir. */
	.tip-summary.is-loading::before {
		animation: none;
		border-top-color: var(--tip-plum);
	}
}

/* ==========================================================================
   iOS et petits écrans — garde-fous transverses
   ==========================================================================

   Trois pièges propres aux navigateurs mobiles, et surtout à Safari :

   1. Safari applique son propre habillage aux boutons et aux champs — coins
      arrondis, dégradé gris, ombre interne. Sans `appearance: none`, un bouton
      dessiné ici ne ressemble à rien sur iPhone.

   2. Un champ dont la police descend sous 16 px déclenche un **zoom
      automatique** à la mise au point. La page saute, et l'utilisateur doit
      dézoomer à la main. La charte demande 15 px : on la respecte partout,
      sauf sur les écrans tactiles étroits où la lisibilité prime.

   3. Un mot long — un nom de produit, une adresse mail — ne se coupe pas tout
      seul et pousse son conteneur au-delà de l'écran. D'où les césures et les
      `min-width: 0` en cascade : dans une grille ou un flex, un enfant refuse
      par défaut de descendre sous sa taille minimale, et c'est le parent qui
      déborde.
   ========================================================================== */

.tip-btn,
.tip-stepper__btn,
.tip-promo__submit,
.tip-promo__drop,
.tip-alert__close {
	-webkit-appearance: none;
	appearance: none;
	-webkit-tap-highlight-color: transparent;
}

.tip-promo__input,
.tip-gift__input,
.tip-country__select {
	-webkit-appearance: none;
	appearance: none;
	border-radius: 14px;
}

/* Les images ne débordent jamais de leur carte, quelle que soit leur taille
   d'origine. */
.tip-item__thumb img,
.tip-xsell__thumb img {
	max-width: 100%;
	height: auto;
}

/* Rien ne pousse la page au-delà de la largeur de l'écran. */
.tip-item,
.tip-item__info,
.tip-item__price,
.tip-summary,
.tip-promo__row,
.tip-bundle__item,
.tip-total {
	min-width: 0;
}

.tip-item__name,
.tip-bundle__name,
.tip-xsell__name {
	overflow-wrap: anywhere;
}

@media (max-width: 700px) {
	/* Zoom automatique de Safari : la seule parade est 16 px. */
	.tip-promo__input,
	.tip-gift__input,
	.tip-country__select {
		font-size: 16px;
	}

	/* Une cible tactile se vise mal en dessous de 44 px. */
	.tip-promo__submit,
	.tip-summary__cta {
		min-height: 48px;
	}
}
