/* Templiz Booking widget — palette/type are CSS vars so the "Apparence"
   setting (auto-inherit from the mini-site, default, or custom) can
   override them inline without touching this file. */

.tzb-widget {
	--tzb-ink: #14130F;
	--tzb-paper: #FFFFFF;
	--tzb-sand: #EFE9DC;
	--tzb-line: #DDD6C6;
	--tzb-muted: #7A7263;
	--tzb-accent: #A08D6B;
	--tzb-font-display: 'Bodoni Moda', Georgia, serif;
	--tzb-font-body: 'Work Sans', Arial, sans-serif;
	/* v1.9.0 — Chloé: "revois le design du bloc de réservation, je veux que
	   ça soit parfait" — a shared corner-radius token so the whole widget
	   (card, buttons, inputs, options) reads as one consistent, slightly
	   softened shape language instead of the previous mix of perfectly
	   square edges everywhere; kept modest (6px) to stay true to the
	   existing editorial/boutique look rather than turning it into pills. */
	--tzb-radius: 6px;
	font-family: var(--tzb-font-body);
	color: var(--tzb-ink);
	/* item #329 (17e vague, retour Chloé) — "Agrandi un peu le panneau de
	   réservation pour que toutes les étapes soient bien visibles" : voir
	   aussi le correctif min-width:0 sur .tzb-step plus bas, cause principale
	   du problème — cette largeur un peu plus généreuse (760px → 860px)
	   réduit surtout le besoin d'y recourir en donnant plus de place aux 4
	   étapes ("Choisissez une prestation" / "Choisissez un professionnel" /
	   "Choisissez une date" / "Vos coordonnées") avant que leur texte n'ait à
	   passer sur deux lignes. */
	/* 62e vague, retour Chloé — "agrandi un peu le panneau de réservation en
	   largeur" : porté 860px → 960px, même logique que ci-dessus.
	   64e vague, retour Chloé — "remets la taille initiale 640px mais de
	   forme rectangulaire pour que tout soit plus lisible (rends cela
	   responsive sur tous les appareils)" : après avoir vu le panneau
	   réellement à 960px (une fois le bug de synchro avec
	   .tsb-booking-widget-wrap corrigé au 63e vague), retour à 640px — la
	   largeur qu'elle a toujours connue. Aucun `width` fixe n'est déclaré
	   ici (seulement max-width) : le panneau reste donc fluide à 100% de
	   son conteneur sur tout écran plus étroit que cette limite. */
	max-width: 640px;
	/* 64e vague — "rends cela responsive sur tous les appareils" : la
	   bascule sidebar/contenu en une seule colonne ci-dessous (voir
	   "@container" plus bas) se basait jusqu'ici UNIQUEMENT sur
	   `@media (max-width: 640px)`, qui regarde la largeur de la FENÊTRE du
	   navigateur, pas celle réellement disponible pour le widget. Problème
	   concret : le widget intégré dans une colonne étroite d'une page (ex.
	   une sidebar, une mise en page à plusieurs colonnes) sur un grand
	   écran (fenêtre large, donc le @media ne se déclenche jamais) restait
	   coincé en 2 colonnes (220px + le reste) même quand l'espace réel
	   disponible est bien plus petit que 640px — texte écrasé, tout sauf
	   "lisible"/"rectangulaire". `container-type: inline-size` fait de
	   .tzb-widget un "query container" : le `@container` ci-dessous peut
	   alors réagir à la largeur RÉELLEMENT disponible pour le widget
	   lui-même, quel que soit l'écran ou l'emplacement où il est intégré —
	   une vraie réactivité "sur tous les appareils", pas seulement en
	   plein écran. Le `@media (max-width: 640px)` existant plus bas est
	   conservé tel quel (ne fait plus de mal, redondant dans le cas simple
	   où le widget occupe toute la largeur de l'écran, et sert de filet de
	   sécurité pour les très rares navigateurs sans support des container
	   queries). */
	container-type: inline-size;
	background: var(--tzb-paper);
	border: 1px solid var(--tzb-line);
	border-radius: var(--tzb-radius);
	box-shadow: 0 2px 24px rgba(20, 19, 15, 0.06);
	overflow: hidden;
}

.tzb-widget * { box-sizing: border-box; }
.tzb-widget-inner { border-radius: inherit; overflow: hidden; }

.tzb-widget-inner {
	display: grid;
	grid-template-columns: 220px 1fr;
}

/* Persistent summary sidebar — always visible, fills in as the client progresses */
.tzb-summary-panel {
	background: var(--tzb-sand);
	padding: 28px 22px;
	border-right: 1px solid var(--tzb-line);
}
.tzb-summary-empty { font-size: 14px; color: var(--tzb-muted); margin: 0; }
.tzb-summary-row { font-size: 14px; margin: 0 0 14px; line-height: 1.4; }
.tzb-summary-row:last-child { margin-bottom: 0; }
.tzb-summary-service { font-family: var(--tzb-font-display); font-size: 17px; }
/* item (52e vague, retour Chloé) — nom de la caractéristique choisie (ex.
   "Taille S"), juste sous le nom de la prestation — même resserrement
   (margin-top négatif) que .tzb-summary-service-price juste en dessous, pour
   lire comme un sous-titre du nom de prestation plutôt qu'une ligne à part. */
.tzb-summary-variant { font-size: 13px; color: var(--tzb-muted); margin-top: -10px; }
/* item #275 (12e vague, retour Chloé) — prix de base de la prestation, sous
   son nom. Contrairement aux lignes "+X€" en couleur accent (suppléments/
   déplacement/extras ci-dessous), c'est le prix de DÉPART et non un ajout —
   couleur neutre (muted) pour rester visuellement distinct de ces lignes. */
.tzb-summary-service-price { font-size: 13px; color: var(--tzb-muted); margin-top: -10px; }
.tzb-summary-price { font-weight: 600; padding-top: 14px; border-top: 1px solid var(--tzb-line); }
/* item #188 (5e vague) — ligne dédiée au supplément (nocturne ou autre) dans
   le récapitulatif, voir updateSummarySurcharge() dans booking-widget.js. */
.tzb-summary-surcharge { font-size: 12.5px; color: var(--tzb-accent, #B08968); margin-top: -8px; }
/* item #198 (6e vague) — même style que .tzb-summary-surcharge ci-dessus,
   pour la ligne dédiée au supplément déplacement (voir updateSummaryTravel()
   dans booking-widget.js). */
.tzb-summary-travel { font-size: 12.5px; color: var(--tzb-accent, #B08968); margin-top: -8px; }
/* item #265 (11e vague, retour Chloé) — le résumé affichait un total unique
   calculé directement dès qu'une option (extra) était choisie ; elle veut un
   détail séparé (une ligne par option) avant le total. Voir
   renderSummaryExtras() dans booking-widget.js — un conteneur pour plusieurs
   lignes possibles (une par extra sélectionné), avec le même style que
   .tzb-summary-surcharge / .tzb-summary-travel ci-dessus. */
.tzb-summary-extras { margin: -8px 0 14px; }
.tzb-summary-extras:empty { margin: 0; }
.tzb-summary-extra { font-size: 12.5px; color: var(--tzb-accent, #B08968); margin: 0 0 4px; line-height: 1.4; }
.tzb-summary-extra:last-child { margin-bottom: 0; }
/* 56e vague, retour Chloé — "Le code promo utilisé doit apparaître dans le
   détail à gauche" : même style/emplacement que .tzb-summary-surcharge/
   .tzb-summary-extra ci-dessus (une ligne juste au-dessus du total), mais en
   vert plutôt qu'en accent — c'est une RÉDUCTION, pas un ajout, même couleur
   "succès" que .tzb-promo-success (message sous le champ code promo) pour
   rester cohérent. Voir updateSummaryPromo() dans booking-widget.js. */
.tzb-summary-promo { font-size: 12.5px; color: #2E6B2E; margin-top: -8px; font-weight: 600; }

.tzb-main { padding: 0; min-width: 0; }

/* Named step breadcrumb */
.tzb-steps {
	display: flex;
	list-style: none;
	margin: 0;
	padding: 20px 28px 0;
	gap: 4px;
}
.tzb-step {
	flex: 1;
	/* item #329 (17e vague, retour Chloé) — "toutes les étapes soient bien
	   visibles" : cause réelle du problème, plus que la largeur globale du
	   panneau (voir max-width ci-dessus, .tzb-widget) — un élément flex a par
	   défaut min-width:auto, ce qui l'empêche de rétrécir en dessous de la
	   largeur intrinsèque de son contenu. Avec 4 libellés d'étape parfois
	   longs ("Choisissez un professionnel") dans une rangée flex serrée,
	   ça les faisait DÉBORDER de leur colonne au lieu de passer à la ligne —
	   d'où des étapes qui se chevauchaient/débordaient plutôt que d'être
	   "bien visibles". min-width:0 autorise le retour à la ligne normal du
	   texte dans .tzb-step-label ci-dessous dès que la place manque.
	*/
	min-width: 0;
	display: flex;
	align-items: center;
	gap: 8px;
	padding-bottom: 16px;
	border-bottom: 3px solid var(--tzb-sand);
	font-size: 12px;
	color: var(--tzb-muted);
}
.tzb-step.is-active,
.tzb-step.is-done {
	border-color: var(--tzb-ink);
	color: var(--tzb-ink);
}
.tzb-step-num {
	width: 20px; height: 20px;
	border-radius: 50%;
	border: 1px solid currentColor;
	display: flex; align-items: center; justify-content: center;
	font-size: 11px;
	flex-shrink: 0;
}
.tzb-step.is-done .tzb-step-num { background: var(--tzb-ink); color: var(--tzb-paper); border-color: var(--tzb-ink); }
.tzb-step-label { display: none; }
@media (min-width: 640px) {
	/**
	 * item #329 (suite) — display:block (au lieu de inline) + overflow-wrap
	 * pour que le libellé puisse proprement passer à la ligne dans l'espace
	 * restant (voir min-width:0 sur .tzb-step ci-dessus) plutôt que de
	 * déborder d'un seul bloc de texte non coupable.
	 *
	 * 61e vague, retour Chloé — item 5 : "Les textes des étapes sur le
	 * panneau de réservation se chevauchent." Le min-width:0 de la 17e
	 * vague (ci-dessus, sur .tzb-step) ne portait QUE sur .tzb-step
	 * lui-même — l'élément flex externe, dans la rangée .tzb-steps. Mais
	 * .tzb-step est LUI-MÊME un conteneur flex (display:flex, pour aligner
	 * .tzb-step-num et .tzb-step-label côte à côte), et .tzb-step-label en
	 * est un élément flex interne, avec sa propre valeur par défaut
	 * min-width:auto (= la largeur de son mot le plus long, jamais 0) —
	 * donc dès que 4 libellés français parfois longs ("Choisissez un
	 * professionnel") se partageaient une rangée étroite, le TEXTE refusait
	 * de rétrécir sous cette largeur minimale et débordait par-dessus
	 * l'étape suivante au lieu de passer correctement à la ligne, d'où le
	 * chevauchement signalé (différent du débordement/troncature déjà
	 * corrigé en 17e vague). min-width:0 doit être répété à CHAQUE niveau
	 * flex imbriqué pour que le retour à la ligne se propage jusqu'au texte
	 * — flex:1 en plus pour que le libellé utilise tout l'espace restant
	 * une fois le numéro (largeur fixe, flex-shrink:0) retiré.
	 */
	.tzb-step-label { display: block; flex: 1; min-width: 0; overflow-wrap: break-word; line-height: 1.25; }
}
/* v1.9.0 — the "staff" step is hidden via the `hidden` attribute (skipped
   when a service has only one staff member); `.tzb-step` already sets its
   own `display: flex`, which — being an author rule — otherwise wins over
   the UA stylesheet's `[hidden]{display:none}`, so without this the step
   would stay visible as an empty flex item. */
.tzb-step[hidden] { display: none; }

.tzb-panel { padding: 24px 28px 32px; }

.tzb-panel-title {
	font-family: var(--tzb-font-display);
	font-weight: 500;
	font-size: 20px;
	margin: 0 0 20px;
	line-height: 1.3;
}

.tzb-staff-list { display: flex; flex-direction: column; }

/**
 * 65e vague, retour Chloé — "sur la page de The Barbie Effect le panneau de
 * réservation ne doit pas être aussi long à l'étape 1, ajoute la
 * possibilité de swipe pour que les clients voient toutes les prestations
 * (avec une hauteur du bloc similaire à l'étape 3) [...] mieux dans le cas
 * où un prestataire propose un large choix". Avant ce lot, .tzb-service-list
 * était une simple colonne (comme .tzb-staff-list ci-dessus) qui grandissait
 * sans limite avec le nombre de prestations — 16 prestations chez The
 * Barbie Effect (vérifié en direct) donnaient un panneau bien plus long que
 * les autres étapes.
 *
 * 66e vague, retour Chloé — "le swipe pour voir toute les prestations doit
 * être de haut en bas et pas de gauche à droite". La 65e vague avait mis en
 * place un défilement HORIZONTAL (colonnes en `column wrap`) ; ce lot le
 * remplace par un défilement VERTICAL classique dans une zone de hauteur
 * fixe (493px, mesurée sur la hauteur réelle de .tzb-calendar — l'étape
 * "Choisissez une date", qui reste la même quel que soit le nombre de
 * prestations) — `overflow-y: auto` + `scroll-snap-type: y proximity` rend
 * la liste swipeable (tactile, de haut en bas) ou défilable (molette),
 * sans dépendre d'une librairie JS de carousel. Un indice visuel ("↕
 * swipe", voir .tzb-service-list-hint plus bas et toggleServiceListHint()
 * dans booking-widget.js) n'apparaît QUE si la liste déborde réellement —
 * une prestataire avec peu de prestations garde exactement le rendu
 * d'avant (tout tient dans la hauteur visible, rien à swiper).
 */
.tzb-service-list {
	display: flex;
	flex-direction: column;
	height: 493px;
	max-height: 70vh;
	overflow-x: hidden;
	overflow-y: auto;
	scroll-snap-type: y proximity;
	padding-bottom: 4px;
	/* un peu d'air à droite pour que la scrollbar ne colle pas au contenu. */
	padding-right: 4px;
}
.tzb-service-list .tzb-option-row {
	flex: 0 0 auto;
	width: 100%;
	scroll-snap-align: start;
}
.tzb-service-list .tzb-service-category-heading { width: 100%; }
/* Scrollbar discrète plutôt que la barre épaisse par défaut du
   navigateur — la liste reste swipeable/défilable, juste moins envahissante
   visuellement à droite du bloc. */
.tzb-service-list { scrollbar-width: thin; scrollbar-color: var(--tzb-line) transparent; }
.tzb-service-list::-webkit-scrollbar { width: 6px; }
.tzb-service-list::-webkit-scrollbar-track { background: transparent; }
.tzb-service-list::-webkit-scrollbar-thumb { background: var(--tzb-line); border-radius: 3px; }

/* Nouvelle demande de Chloé : "rends visibles les catégories dans le
   panneau de réservation" — n'apparaît que si 2+ catégories sont utilisées
   (voir loadServices() dans booking-widget.js). */
.tzb-service-category-heading {
	font-size: 12px; font-weight: 700; letter-spacing: .04em; text-transform: uppercase;
	color: var(--tzb-muted); margin: 20px 0 4px;
}
.tzb-service-category-heading:first-child { margin-top: 0; }

/* 65e vague — indice de swipe, affiché seulement quand la liste déborde
   réellement (voir toggleServiceListHint() dans booking-widget.js). */
.tzb-service-list-hint {
	display: none;
	align-items: center;
	gap: 6px;
	font-size: 12px;
	color: var(--tzb-muted);
	margin: -8px 0 12px;
}
.tzb-service-list-hint.is-visible { display: flex; }

.tzb-option-row {
	display: flex;
	align-items: center;
	gap: 14px;
	padding: 16px 0;
	border-bottom: 1px solid var(--tzb-line);
	cursor: pointer;
	background: none;
	border-left: none; border-right: none; border-top: none;
	width: 100%;
	text-align: left;
	font: inherit;
	color: inherit;
}
.tzb-option-row:first-child { padding-top: 0; }
.tzb-option-row {
	transition: background .12s ease, color .12s ease;
	border-radius: 4px;
	padding-left: 8px; padding-right: 8px;
	margin: 0 -8px;
}
.tzb-option-row:hover { color: var(--tzb-accent); background: var(--tzb-sand); }
/* item 3 (51e vague, retour Chloé) — étape "Option" : la sélection d'une
   caractéristique n'avance plus automatiquement à l'étape suivante (voir
   goToOptionsStep()/updateOptionsContinueState() dans booking-widget.js, le
   bouton "Continuer" prend ce rôle) — il faut donc un état visuel persistant
   pour la ligne choisie, pas seulement :hover. */
.tzb-option-row.is-selected { color: var(--tzb-accent); background: var(--tzb-sand); border-color: var(--tzb-accent, #B08968); }

.tzb-option-photo {
	width: 44px; height: 44px;
	border-radius: 4px;
	object-fit: cover;
	flex-shrink: 0;
}
.tzb-option-color {
	width: 3px;
	align-self: stretch;
	min-height: 32px;
	flex-shrink: 0;
}

.tzb-option-main { flex: 1; display: flex; flex-direction: column; }
.tzb-option-name { font-size: 16px; }
.tzb-option-meta { display: block; font-size: 13px; color: var(--tzb-muted); margin-top: 2px; }
.tzb-option-price { font-size: 15px; white-space: nowrap; }

/* Visual month calendar */
.tzb-calendar { margin-bottom: 20px; }
.tzb-calendar-header {
	display: flex;
	align-items: center;
	justify-content: space-between;
	margin-bottom: 12px;
}
.tzb-cal-month-label { font-family: var(--tzb-font-display); font-size: 16px; text-transform: capitalize; }
.tzb-cal-nav {
	/* v1.9.0 — "le calendrier s'affiche mal" was the native <button> chrome:
	   without appearance:none/font:inherit/margin:0, browsers render their
	   own button face (padding, border style, system font) on top of ours,
	   throwing off the 30x30 sizing and header alignment. Same fix applied
	   to .tzb-cal-day below. */
	appearance: none;
	-webkit-appearance: none;
	font: inherit;
	margin: 0;
	width: 30px; height: 30px;
	border: 1px solid var(--tzb-line);
	border-radius: 50%;
	background: var(--tzb-paper);
	color: var(--tzb-ink);
	cursor: pointer;
	font-size: 16px;
	line-height: 1;
	display: flex;
	align-items: center;
	justify-content: center;
}
.tzb-cal-nav:hover:not(:disabled) { border-color: var(--tzb-ink); }
.tzb-cal-nav:disabled { opacity: 0.3; cursor: default; }

.tzb-calendar-weekdays,
.tzb-calendar-grid {
	display: grid;
	grid-template-columns: repeat(7, 1fr);
	gap: 4px;
}
.tzb-calendar-weekdays {
	font-size: 11px;
	text-transform: uppercase;
	color: var(--tzb-muted);
	margin-bottom: 6px;
	text-align: center;
}
.tzb-cal-day {
	appearance: none;
	-webkit-appearance: none;
	font: inherit;
	margin: 0;
	padding: 0;
	width: 100%;
	aspect-ratio: 1;
	display: flex;
	align-items: center;
	justify-content: center;
	font-size: 14px;
	border: 1px solid transparent;
	border-radius: 50%;
	background: none;
	cursor: default;
	color: var(--tzb-muted);
	transition: background .12s ease, color .12s ease, border-color .12s ease;
}
.tzb-cal-day.is-empty { visibility: hidden; }
.tzb-cal-day.is-available {
	cursor: pointer;
	color: var(--tzb-ink);
	border-color: var(--tzb-line);
}
.tzb-cal-day.is-available:hover { border-color: var(--tzb-ink); background: var(--tzb-sand); }
.tzb-cal-day.is-selected,
.tzb-cal-day.is-selected:hover { background: var(--tzb-ink); color: var(--tzb-paper); border-color: var(--tzb-ink); }
.tzb-cal-day.is-today:not(.is-selected) { font-weight: 700; color: var(--tzb-accent); border-color: var(--tzb-accent); }
.tzb-cal-day:disabled:not(.is-empty) { cursor: default; }

.tzb-slot-panel { margin-top: 8px; }
.tzb-slot-panel-title { font-size: 13px; color: var(--tzb-muted); margin: 0 0 10px; }

.tzb-slot-list {
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(84px, 1fr));
	gap: 8px;
}
.tzb-slot {
	appearance: none;
	-webkit-appearance: none;
	border: 1px solid var(--tzb-line);
	border-radius: 4px;
	padding: 10px 4px;
	margin: 0;
	text-align: center;
	background: var(--tzb-paper);
	color: var(--tzb-ink);
	cursor: pointer;
	font: inherit;
	font-size: 14px;
	transition: border-color .12s ease, background .12s ease, color .12s ease;
}
.tzb-slot:hover { border-color: var(--tzb-ink); background: var(--tzb-sand); }
.tzb-slot.is-selected,
.tzb-slot.is-selected:hover { background: var(--tzb-ink); color: var(--tzb-paper); border-color: var(--tzb-ink); }

/* item #161 (retour Chloé) — "ajoute le supplément nocturne à l'étape 2 si
   configuré" : créneau concerné par une règle de supplément (Mon Espace >
   Suppléments) — étiquette discrète sous l'heure, jamais affichée quand
   aucune règle ne s'applique (voir get_availability() côté serveur). */
.tzb-slot-surcharge { display: flex; flex-direction: column; gap: 2px; padding: 8px 4px; border-color: var(--tzb-accent, #B08968); }
.tzb-slot-time { font-size: 14px; }
.tzb-slot-surcharge-tag { font-size: 10px; line-height: 1.2; color: var(--tzb-accent, #B08968); }
.tzb-slot-surcharge.is-selected .tzb-slot-surcharge-tag,
.tzb-slot-surcharge.is-selected:hover .tzb-slot-surcharge-tag { color: var(--tzb-paper); opacity: 0.85; }

.tzb-empty-note, .tzb-loading { color: var(--tzb-muted); font-size: 14px; padding: 12px 0; }

/* item #176 (4e vague, retour Chloé) — "Présente les suppléments nocturnes
   comme les horaires classiques" : grille de créneaux cliquables, sous les
   mêmes codes visuels que .tzb-travel-fee-box (fond sable, bordure en
   pointillés couleur accent). item #234 (9e vague) était passé par un
   sélecteur d'heure libre entre-temps ; item #2 (51e vague) revient à la
   grille — voir selectSurchargeSlot() dans booking-widget.js. */
.tzb-night-option, .tzb-morning-option { margin-top: 14px; padding: 12px 14px; background: var(--tzb-sand); border: 1px dashed var(--tzb-accent, #B08968); border-radius: 4px; }
.tzb-night-toggle, .tzb-morning-toggle { display: flex; align-items: flex-start; gap: 10px; font-size: 13px; cursor: pointer; }
.tzb-night-picker, .tzb-morning-picker { margin-top: 10px; padding-top: 10px; border-top: 1px solid var(--tzb-line); }
/* item #225 (8e vague) — plage horaire de/à, visible dès l'affichage du
   bloc (avant même de cocher la case), voir updateNightRangeInfo()/
   updateMorningRangeInfo() dans booking-widget.js. */
.tzb-night-range-info, .tzb-morning-range-info { font-size: 12px; color: var(--tzb-muted); margin: 4px 0 0 24px; }
/* item #213 (7e vague) — bloc "supplément matinal", pendant du bloc nocturne
   ci-dessus (voir updateMorningOption() dans booking-widget.js) : même
   style, affiché indépendamment au-dessus. */
.tzb-morning-option { margin-bottom: 10px; }
/* item #2 (51e vague, retour Chloé) — titre + note "aucun créneau" de la
   grille de créneaux nocturne/matinale (voir bind() dans booking-widget.js,
   qui les remplit à l'ouverture du picker) ; .tzb-slot-list/.tzb-slot/
   .tzb-empty-note ci-dessus fournissent déjà le rendu de la grille
   elle-même (classes partagées avec loadSlotsForSelectedDay()). */
.tzb-night-slot-title, .tzb-morning-slot-title { font-size: 13px; color: var(--tzb-muted); margin: 0 0 8px; }
.tzb-night-empty-note, .tzb-morning-empty-note { color: var(--tzb-muted); font-size: 13px; margin: 0; }

/* item #198 (6e vague, retour Chloé) — case "Déplacement" de l'étape "Vos
   coordonnées" : mêmes codes visuels que .tzb-night-option ci-dessus (fond
   sable, bordure en pointillés couleur accent) pour rester cohérent avec le
   seul autre "supplément optionnel" déjà présent dans le widget. */
.tzb-travel-fee-box { margin: 4px 0; padding: 12px 14px; background: var(--tzb-sand); border: 1px dashed var(--tzb-accent, #B08968); border-radius: 4px; }
.tzb-travel-toggle { display: flex; align-items: flex-start; gap: 10px; font-size: 13px; cursor: pointer; }

/**
 * item #269 (11e vague, retour Chloé) — "Partout ou il y a des cases à
 * cocher mets plutôt des interrupteurs à bascule (toggle switch) c'est plus
 * esthétique". Composant partagé pour les 3 cases à cocher du widget
 * (nocturne/matinal/déplacement ci-dessus) — mêmes checkbox natives dessous
 * (inputs inchangés, JS de bind()/renderTravelFee()/etc. non impacté) mais
 * habillées visuellement en interrupteur, plutôt que la case native du
 * navigateur. Même principe que .tpd-toggle-switch côté Provider Dashboard.
 */
.tzb-toggle-switch { position: relative; display: inline-block; width: 38px; height: 22px; flex-shrink: 0; }
/**
 * item #274 (12e vague, retour Chloé) — "le checkbox apparaît sous le
 * toggle switch" (panneau de réservation) : appearance:none manquant sur la
 * case masquée — certains navigateurs/modes d'accessibilité (contraste
 * élevé, forced-colors) ignorent opacity:0 sur les contrôles de formulaire
 * natifs et continuent d'afficher leur apparence par défaut par-dessus.
 * appearance:none la supprime pour de bon ; z-index explicite en plus, par
 * sécurité, pour garantir que .tzb-toggle-switch-track reste au-dessus.
 */
.tzb-toggle-switch input {
	position: absolute; inset: 0; width: 100%; height: 100%; margin: 0;
	opacity: 0; cursor: pointer; z-index: 2;
	appearance: none; -webkit-appearance: none; -moz-appearance: none;
}
.tzb-toggle-switch-track {
	position: absolute; inset: 0; z-index: 1;
	background: var(--tzb-line);
	border-radius: 999px;
	transition: background .15s ease;
}
.tzb-toggle-switch-track::before {
	content: "";
	position: absolute; top: 2px; left: 2px;
	width: 18px; height: 18px;
	background: #fff;
	border-radius: 50%;
	box-shadow: 0 1px 2px rgba(0,0,0,0.25);
	transition: transform .15s ease;
}
.tzb-toggle-switch input:checked + .tzb-toggle-switch-track { background: var(--tzb-ink); }
/**
 * 130e vague, retour Chloé (suite) — "le bouton on/off pour les
 * déplacements activé ça doit être visible [...] il n'y a pas de couleur"
 * (saas.templiz.com/lrzbarber, thème "Apparence" sombre de cette
 * prestataire). Le rond du bouton restait figé en blanc (#fff) quel que
 * soit l'état, alors que le fond de la piste à l'état activé suit
 * `--tzb-ink` (voir TZB_Shortcode::resolve_appearance_vars()) — qui, dans
 * un thème sombre, est justement la couleur CLAIRE du texte (ex. #ede7da
 * chez lrzbarber), l'équivalent du "paper" clair des thèmes par défaut.
 * Résultat : piste quasi blanche + rond blanc, interrupteur activé
 * invisible. `--tzb-ink`/`--tzb-paper` forment déjà, partout ailleurs dans
 * ce fichier (ex. .tzb-step.is-done, .tzb-cal-day.is-selected), une paire
 * garantie contrastée quel que soit le thème (l'une est toujours la
 * couleur sombre, l'autre la couleur claire) — le rond suit maintenant
 * `--tzb-paper` uniquement à l'état activé (blanc par défaut, donc aucun
 * changement visuel pour les prestataires en thème clair) pour rester
 * lisible sur la piste `--tzb-ink` dans tous les cas.
 */
.tzb-toggle-switch input:checked + .tzb-toggle-switch-track::before { transform: translateX(16px); background: var(--tzb-paper); }
.tzb-toggle-switch input:focus-visible + .tzb-toggle-switch-track { outline: 2px solid var(--tzb-accent); outline-offset: 2px; }
.tzb-travel-address { margin-top: 10px; padding-top: 10px; border-top: 1px solid var(--tzb-line); display: flex; flex-direction: column; gap: 4px; position: relative; }
.tzb-travel-address label { font-size: 12px; color: var(--tzb-muted); }
.tzb-travel-address input { border: 1px solid var(--tzb-line); border-radius: 4px; padding: 10px 12px; font: inherit; }

/**
 * item #267 (11e vague, retour Chloé) — liste de suggestions pour
 * l'autocomplétion d'adresse via la Base Adresse Nationale (voir
 * tzbInitBanAutocomplete() dans booking-widget.js) : Google Places fournit
 * son propre menu déroulant tout fait, mais l'API de la BAN ne renvoie que
 * du JSON — ce menu est donc construit ici à la main.
 *
 * 130e vague, retour Chloé (suite) — "la liste des adresses est coupée" :
 * cette liste vivait jusqu'ici DANS le widget (position:absolute calée sur
 * .tzb-travel-address, voir l'historique de ce fichier), où elle se faisait
 * rogner par le `overflow: hidden` de .tzb-widget/.tzb-widget-inner dès
 * qu'elle dépassait la hauteur déjà occupée par le panneau — voir le
 * docblock de tzbPositionBanBox()/tzbBanSuggestionsBox() dans
 * booking-widget.js pour le détail. Déplacée dans <body>, en dehors de cet
 * ancêtre, et positionnée entièrement en JS (position:fixed + left/top/
 * width calculés sur le champ, voir ces deux fonctions) — left/top/right
 * ci-dessous n'ont donc plus lieu d'être : seuls z-index et l'apparence
 * (fond, bordure, ombre, défilement interne) restent du ressort de cette
 * règle.
 */
.tzb-address-suggestions {
	position: fixed;
	z-index: 10000;
	background: var(--tzb-paper, #fff);
	border: 1px solid var(--tzb-line);
	border-radius: 4px;
	margin-top: 2px;
	max-height: 220px;
	overflow-y: auto;
	box-shadow: 0 4px 12px rgba(0,0,0,0.08);
}
.tzb-address-suggestion {
	display: block;
	width: 100%;
	text-align: left;
	background: none;
	border: 0;
	border-bottom: 1px solid var(--tzb-line);
	padding: 9px 12px;
	font: inherit;
	font-size: 13px;
	color: inherit;
	cursor: pointer;
}
.tzb-address-suggestion:last-child { border-bottom: 0; }
.tzb-address-suggestion:hover,
.tzb-address-suggestion:focus { background: var(--tzb-sand); }

.tzb-details-form { display: flex; flex-direction: column; gap: 12px; }
/* v1.9.1 — `flex-wrap` + an explicit min-width floor let a field drop to
   its own line instead of getting crushed when the widget itself is
   embedded in a narrow column (this can happen well above the 640px
   stacking breakpoint below, which only reacts to viewport width). */
.tzb-field-row { display: flex; flex-wrap: wrap; gap: 12px; }
.tzb-field-row input { flex: 1 1 140px; min-width: 140px; }
/* 75e vague, retour Chloé — "laisse un espace entre les balises 'Nom du
   proche' et 'Email du proche'" (capture d'écran iPhone, étape
   "Coordonnées" du panneau de réservation). Cause : .tzb-beneficiary-fields
   (le bloc "pour un proche", voir widget.php) enveloppe sa note + ses deux
   .tzb-field-row dans un simple <div> sans gap — contrairement à
   .tzb-details-form ci-dessus qui, lui, est en flex-column avec gap:12px
   et espace donc uniformément TOUS ses champs, y compris les paires
   prénom/nom et email/téléphone du formulaire principal une fois empilées
   en colonne (voir le point de rupture plus bas). Résultat : la ligne
   "Prénom + Nom du proche" et la ligne "Email + Téléphone du proche"
   n'avaient aucun espace entre elles (seuls les champs à l'INTÉRIEUR d'une
   même .tzb-field-row profitaient du gap:12px de cette dernière). Même
   traitement flex-column + gap:12px appliqué ici pour retrouver un espacement
   cohérent avec le reste du formulaire. */
.tzb-beneficiary-fields { display: flex; flex-direction: column; gap: 12px; }
/* item #316 (82e vague, retour Chloé) — "bug sur le on/off de 'je prends ce
   rendez-vous pour un proche'" : la règle display:flex ci-dessus (75e vague,
   pour l'espacement) s'applique aussi quand le JS pose l'attribut [hidden]
   sur ce même bloc (voir booking-widget.js, le toggle .tzb-beneficiary-toggle
   se contente de basculer .hidden) — une règle d'auteur avec display explicite
   l'emporte toujours sur la règle UA [hidden]{display:none}, quelle que soit
   la spécificité, donc le bloc restait visible. Même correctif déjà en place
   ailleurs dans ce fichier pour exactement ce problème : .tzb-step[hidden],
   .tzb-attachment-preview[hidden], .tzb-waitlist-form[hidden]. */
.tzb-beneficiary-fields[hidden] { display: none; }
.tzb-beneficiary-note { margin: 0; }
.tzb-details-form input,
.tzb-details-form textarea {
	border: 1px solid var(--tzb-line);
	border-radius: 4px;
	padding: 12px 14px;
	font: inherit;
	background: var(--tzb-paper);
	color: var(--tzb-ink);
	width: 100%;
	transition: border-color .12s ease;
}
.tzb-details-form input:focus,
.tzb-details-form textarea:focus {
	outline: none;
	border-color: var(--tzb-ink);
}
.tzb-details-form textarea { min-height: 70px; resize: vertical; }

/* v1.9.1 — reference photo attached at booking time (Chloé item #6). */
.tzb-attachment-field { display: flex; flex-direction: column; gap: 6px; margin-top: -4px; }
.tzb-attachment-label { font-size: 13px; color: var(--tzb-muted); }
.tzb-attachment-input { font-size: 13px; width: 100%; max-width: 100%; }
.tzb-attachment-preview { display: flex; align-items: center; gap: 10px; }
.tzb-attachment-preview[hidden] { display: none; }
.tzb-attachment-preview img { width: 56px; height: 56px; object-fit: cover; border-radius: 6px; border: 1px solid var(--tzb-line); }
/**
 * 61e vague, retour Chloé — item 5 : "Prestation souhaitée — photo
 * (facultatif) : quand une photo est ajoutée la croix apparaît mais est
 * mal cadrée." Ce bouton n'avait ni padding ni centrage explicites — un
 * <button> garde par défaut le padding natif du navigateur (quelques
 * pixels, variable selon navigateur/OS), qui, combiné à une boîte fixe de
 * 26×26px, pousse le "×" hors du centre au lieu de le centrer dedans
 * (parfois même rogné visuellement sur un bord). padding: 0 supprime ce
 * padding natif, et display: flex + centrage verrouille le glyphe
 * exactement au milieu de la boîte quel que soit le navigateur.
 */
.tzb-attachment-remove {
	appearance: none; -webkit-appearance: none;
	display: flex; align-items: center; justify-content: center;
	border: 1px solid var(--tzb-line); border-radius: 4px;
	background: var(--tzb-paper); color: var(--tzb-muted);
	width: 26px; height: 26px; padding: 0; margin: 0;
	font-size: 16px; line-height: 1; cursor: pointer;
}
.tzb-attachment-status { font-size: 12px; color: var(--tzb-muted); margin: 0; }
.tzb-attachment-status.tzb-attachment-error { color: #B3554A; }

/* Phone field — dial-code select + local-number input, side by side.
   v1.9.0, see tzbEnhancePhoneField() in booking-widget.js. */
/**
 * item #304 (15e vague, retour Chloé) — "les drapeaux en fonction des
 * indicatifs ne sont plus visibles remets les" : en creusant, le code
 * (tzbEnhancePhoneField() dans booking-widget.js) construisait bien les
 * <option> avec un émoji drapeau — mais un émoji drapeau DANS un <option>
 * de <select> natif ne s'affiche pas de façon fiable sur toutes les
 * plateformes (Windows en particulier n'a jamais eu de police d'émoji
 * drapeau native, quel que soit le site) : ce n'était donc pas une
 * régression du code, mais une limite plate-forme qui ne pouvait qu'empirer
 * avec le temps. Remplacé par de vraies icônes de drapeau (SVG, licence
 * MIT, projet flag-icons) affichées à part, juste devant le <select> — un
 * vrai drapeau visible sur toutes les plates-formes, plus jamais dépendant
 * d'une police d'émoji. Voir .tzb-phone-flag / .tzb-flag-XX plus bas et
 * tzbEnhancePhoneField() pour la structure HTML.
 */
/**
 * 61e vague, retour Chloé — item 5 : "l'indicatif du numéro de téléphone
 * s'affiche mal". Avant cette vague, le drapeau (.tzb-phone-flag) était
 * positionné en absolute PAR-DESSUS le <select>, calé à l'œil sur son
 * padding-left (32px) — un équilibre fragile entre 2 règles dans 2 endroits
 * différents du CSS, déjà retouché 2 fois (11e puis 15e vague) sans jamais
 * vraiment se stabiliser sur tous les navigateurs/tailles de police
 * (chaque moteur de rendu calcule un peu différemment la hauteur réelle
 * d'un <select> à padding custom, ce qui décale le centrage vertical du
 * badge absolu). Remplacé par une disposition flex toute simple : le
 * drapeau redevient un vrai élément de la ligne (flex, gap), juste à côté
 * du <select> plutôt que superposé dedans — plus aucun calcul de
 * positionnement à faire correspondre entre les deux, donc plus rien à
 * décaler quel que soit le navigateur.
 */
.tzb-phone-field { display: flex; gap: 8px; }
.tzb-phone-dial-wrap { display: flex; align-items: center; gap: 6px; flex: 0 0 auto; }
.tzb-phone-flag {
	flex: 0 0 auto;
	width: 18px;
	height: 13px;
	background-size: cover;
	background-position: center;
	background-repeat: no-repeat;
	border-radius: 2px;
	box-shadow: 0 0 0 1px rgba(0, 0, 0, .12);
	pointer-events: none;
}
/* v1.9.1 — was `min-width: 0`, which let this wrapper (and therefore the
   number input inside it) get squeezed down to almost nothing whenever it
   shares a row with the email field in a narrow container: the dial-code
   select never shrinks (flex-shrink: 0 below) and the email field has its
   own default minimum width, so the number input absorbed all the loss.
   A real floor here, combined with the `input[type="tel"]` floor below and
   `flex-wrap` on `.tzb-field-row`, keeps the number field readable — it
   drops to its own line instead of collapsing. */
.tzb-field-row .tzb-phone-field { flex: 1 1 220px; min-width: 220px; }
/* Nouvelle demande de Chloé : "sur mobile [...] l'indicatif on le voit pas
   en entier" — à 96px max-width, l'indicatif le plus long ("🇱🇺 +352",
   "🇲🇨 +377"...) se faisait couper par la flèche native du <select>, qui
   prend elle-même de la place dans cette même boîte. Élargi + une marge de
   sécurité (ellipsis) si jamais un terminal réduit encore l'espace dispo. */
/* item #268 (11e vague, retour Chloé) — "dans « vos coordonnés » l'indicatif
   n'est pas bien visible" : le <select> partageait le même fond blanc et la
   même bordure discrète que le champ numéro juste à côté, du coup rien ne
   distinguait visuellement l'indicatif (facile à ne pas remarquer, voire à
   prendre pour du texte non modifiable). Fond teinté + bordure plus marquée
   + indicatif en gras + flèche personnalisée (plus visible que la flèche
   native, très fine sur certains navigateurs) pour que ce soit clairement un
   sélecteur à part entière. */
.tzb-phone-field .tzb-phone-dial {
	width: auto;
	/**
	 * 61e vague — élargi à nouveau (168px -> 188px) : le drapeau n'est plus
	 * superposé par-dessus le <select> (voir .tzb-phone-dial-wrap ci-dessus),
	 * donc son padding-left n'a plus besoin de lui réserver de la place —
	 * cette largeur récupérée profite directement à la lisibilité du texte
	 * de l'indicatif choisi ("+225 Côte d'Ivoire" et consorts, qui se
	 * faisaient tronquer en ellipsis à 168px).
	 */
	max-width: 188px;
	border: 1px solid var(--tzb-accent, #A08D6B);
	border-radius: 4px;
	background: var(--tzb-sand) url("data:image/svg+xml;charset=UTF-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6' viewBox='0 0 10 6'%3E%3Cpath d='M1 1l4 4 4-4' fill='none' stroke='%2314130F' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") no-repeat right 8px center;
	color: var(--tzb-ink);
	font: inherit;
	font-size: 14px;
	font-weight: 600;
	/**
	 * 62e vague, retour Chloé — item 2/5 : "l'indicatif du numéro de
	 * téléphone s'affiche pas entièrement." Cause trouvée : `font: inherit`
	 * ci-dessus réinitialise AUSSI line-height (le raccourci `font`
	 * réinitialise tous ses sous-réglages, line-height compris) pour
	 * qu'il hérite du contexte parent — donc, le plus souvent, du thème
	 * WordPress de la prestataire (jamais garanti ≥ 1 ligne confortable
	 * pour ce texte, certains thèmes vont jusqu'à line-height:1 sur les
	 * champs de formulaire). Combiné à `overflow: hidden` juste en dessous
	 * (nécessaire pour l'ellipsis), un line-height hérité trop serré coupe
	 * le haut/bas des lettres. Fixé en dur ici (indépendant du thème de la
	 * prestataire, comme le reste des styles de ce panneau) plutôt que de
	 * dépendre d'un héritage jamais garanti.
	 */
	line-height: 1.3;
	/* 61e vague — 10px à gauche (était 32px) : plus de drapeau à superposer
	   par-dessus ce <select> (voir .tzb-phone-flag ci-dessus, maintenant un
	   élément flex à part, juste avant ce <select>). */
	padding: 12px 22px 12px 10px;
	cursor: pointer;
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
	appearance: none;
	-webkit-appearance: none;
	-moz-appearance: none;
}
/**
 * item #304 (15e vague) — icônes de drapeau réelles (SVG intégrés en
 * data-URI, licence MIT, projet "flag-icons" github.com/lipis/flag-icons)
 * pour les mêmes pays que TZB_DIAL_CODES dans booking-widget.js — une par
 * classe .tzb-flag-XX (XX = code pays), appliquée par JS sur .tzb-phone-flag
 * ci-dessus selon la sélection en cours. Le drapeau Espagne a été simplifié
 * (bandes rouge/jaune/rouge, sans les armoiries) : la version complète du
 * projet source pèse à elle seule ~80 Ko pour un détail invisible à la
 * taille d'affichage réelle (18×13px) — la version simplifiée suffit
 * largement et garde l'ensemble des 19 drapeaux sous les 15 Ko au total.
 */
.tzb-flag-FR { background-image: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGlkPSJmbGFnLWljb25zLWZyIiB2aWV3Qm94PSIwIDAgNjQwIDQ4MCI+CiAgPHBhdGggZmlsbD0iI2ZmZiIgZD0iTTAgMGg2NDB2NDgwSDB6Ii8+CiAgPHBhdGggZmlsbD0iIzAwMDA5MSIgZD0iTTAgMGgyMTMuM3Y0ODBIMHoiLz4KICA8cGF0aCBmaWxsPSIjZTEwMDBmIiBkPSJNNDI2LjcgMEg2NDB2NDgwSDQyNi43eiIvPgo8L3N2Zz4K"); }
.tzb-flag-BE { background-image: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGlkPSJmbGFnLWljb25zLWJlIiB2aWV3Qm94PSIwIDAgNjQwIDQ4MCI+CiAgPGcgZmlsbC1ydWxlPSJldmVub2RkIiBzdHJva2Utd2lkdGg9IjFwdCI+CiAgICA8cGF0aCBmaWxsPSIjMDAwMDAxIiBkPSJNMCAwaDIxMy4zdjQ4MEgweiIvPgogICAgPHBhdGggZmlsbD0iI2ZmZDkwYyIgZD0iTTIxMy4zIDBoMjEzLjR2NDgwSDIxMy4zeiIvPgogICAgPHBhdGggZmlsbD0iI2YzMTgzMCIgZD0iTTQyNi43IDBINjQwdjQ4MEg0MjYuN3oiLz4KICA8L2c+Cjwvc3ZnPgo="); }
.tzb-flag-CH { background-image: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGlkPSJmbGFnLWljb25zLWNoIiB2aWV3Qm94PSIwIDAgNjQwIDQ4MCI+CiAgPGcgZmlsbC1ydWxlPSJldmVub2RkIiBzdHJva2Utd2lkdGg9IjFwdCI+CiAgICA8cGF0aCBmaWxsPSJyZWQiIGQ9Ik0wIDBoNjQwdjQ4MEgweiIvPgogICAgPGcgZmlsbD0iI2ZmZiI+CiAgICAgIDxwYXRoIGQ9Ik0xNzAgMTk1aDMwMHY5MEgxNzB6Ii8+CiAgICAgIDxwYXRoIGQ9Ik0yNzUgOTBoOTB2MzAwaC05MHoiLz4KICAgIDwvZz4KICA8L2c+Cjwvc3ZnPgo="); }
.tzb-flag-LU { background-image: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGlkPSJmbGFnLWljb25zLWx1IiB2aWV3Qm94PSIwIDAgNjQwIDQ4MCI+CiAgPHBhdGggZmlsbD0iI2VkMjkzOSIgZD0iTTAgMGg2NDB2MTYwSDB6Ii8+CiAgPHBhdGggZmlsbD0iI2ZmZiIgZD0iTTAgMTYwaDY0MHYxNjBIMHoiLz4KICA8cGF0aCBmaWxsPSIjMDBhMWRlIiBkPSJNMCAzMjBoNjQwdjE2MEgweiIvPgo8L3N2Zz4K"); }
.tzb-flag-MC { background-image: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGlkPSJmbGFnLWljb25zLW1jIiB2aWV3Qm94PSIwIDAgNjQwIDQ4MCI+CiAgPGcgZmlsbC1ydWxlPSJldmVub2RkIiBzdHJva2Utd2lkdGg9IjFwdCI+CiAgICA8cGF0aCBmaWxsPSIjZjMxODMwIiBkPSJNMCAwaDY0MHYyNDBIMHoiLz4KICAgIDxwYXRoIGZpbGw9IiNmZmYiIGQ9Ik0wIDI0MGg2NDB2MjQwSDB6Ii8+CiAgPC9nPgo8L3N2Zz4K"); }
.tzb-flag-CA { background-image: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGlkPSJmbGFnLWljb25zLWNhIiB2aWV3Qm94PSIwIDAgNjQwIDQ4MCI+CiAgPHBhdGggZmlsbD0iI2ZmZiIgZD0iTTE1MC4xIDBoMzM5Ljd2NDgwSDE1MHoiLz4KICA8cGF0aCBmaWxsPSIjZDUyYjFlIiBkPSJNLTE5LjcgMGgxNjkuOHY0ODBILTE5Ljd6bTUwOS41IDBoMTY5Ljh2NDgwSDQ4OS45ek0yMDEgMjMybC0xMy4zIDQuNCA2MS40IDU0YzQuNyAxMy43LTEuNiAxNy44LTUuNiAyNWw2Ni42LTguNC0xLjYgNjcgMTMuOS0uMy0zLjEtNjYuNiA2Ni43IDhjLTQuMS04LjctNy44LTEzLjMtNC0yNy4ybDYxLjMtNTEtMTAuNy00Yy04LjgtNi44IDMuOC0zMi42IDUuNi00OC45IDAgMC0zNS43IDEyLjMtMzggNS44bC05LjItMTcuNS0zMi42IDM1LjhjLTMuNS45LTUtLjUtNS45LTMuNWwxNS03NC44LTIzLjggMTMuNHEtMy4yIDEuMy01LjItMi4ybC0yMy00Ni0yMy42IDQ3LjhxLTIuOCAyLjUtNSAuN0wyNjQgMTMwLjhsMTMuNyA3NC4xYy0xLjEgMy0zLjcgMy44LTYuNyAyLjJsLTMxLjItMzUuM2MtNCA2LjUtNi44IDE3LjEtMTIuMiAxOS41cy0yMy41LTQuNS0zNS42LTdjNC4yIDE0LjggMTcgMzkuNiA5IDQ3LjciLz4KPC9zdmc+Cg=="); }
.tzb-flag-MA { background-image: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGlkPSJmbGFnLWljb25zLW1hIiB2aWV3Qm94PSIwIDAgNjQwIDQ4MCI+CiAgPHBhdGggZmlsbD0iI2MxMjcyZCIgZD0iTTY0MCAwSDB2NDgwaDY0MHoiLz4KICA8cGF0aCBmaWxsPSJub25lIiBzdHJva2U9IiMwMDYyMzMiIHN0cm9rZS13aWR0aD0iMTEuNyIgZD0iTTMyMCAxNzkuNCAyODQuNCAyODlsOTMuMi02Ny42SDI2Mi40bDkzLjIgNjcuNnoiLz4KPC9zdmc+Cg=="); }
.tzb-flag-DZ { background-image: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGlkPSJmbGFnLWljb25zLWR6IiB2aWV3Qm94PSIwIDAgNjQwIDQ4MCI+CiAgPHBhdGggZmlsbD0iI2ZmZiIgZD0iTTMyMCAwaDMyMHY0ODBIMzIweiIvPgogIDxwYXRoIGZpbGw9IiMwMDYyMzMiIGQ9Ik0wIDBoMzIwdjQ4MEgweiIvPgogIDxwYXRoIGZpbGw9IiNkMjEwMzQiIGQ9Ik00MjQgMTgwYTEyMCAxMjAgMCAxIDAgMCAxMjAgOTYgOTYgMCAxIDEgMC0xMjBtNCA2MC0xMDgtMzUuMiA2Ny4yIDkyVjE4My4ybC02Ny4yIDkyeiIvPgo8L3N2Zz4K"); }
.tzb-flag-TN { background-image: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGlkPSJmbGFnLWljb25zLXRuIiB2aWV3Qm94PSIwIDAgNjQwIDQ4MCI+CiAgPHBhdGggZmlsbD0iI2U3MDAxMyIgZD0iTTAgMGg2NDB2NDgwSDB6Ii8+CiAgPHBhdGggZmlsbD0iI2ZmZiIgZD0iTTMyMCAxMTkuMmExIDEgMCAwIDAtMSAyNDAuMyAxIDEgMCAwIDAgMS0yNDAuM00zOTIgMjkzYTkwIDkwIDAgMSAxIDAtMTA3IDcyIDcyIDAgMSAwIDAgMTA3bS00LjctMjEuNy0zNy40LTEyLjEtMjMuMSAzMS44di0zOS4zbC0zNy40LTEyLjIgMzcuNC0xMi4yVjE4OGwyMy4xIDMxLjggMzcuNC0xMi4xLTIzLjEgMzEuOHoiLz4KPC9zdmc+Cg=="); }
.tzb-flag-SN { background-image: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGlkPSJmbGFnLWljb25zLXNuIiB2aWV3Qm94PSIwIDAgNjQwIDQ4MCI+CiAgPGcgZmlsbC1ydWxlPSJldmVub2RkIiBzdHJva2Utd2lkdGg9IjFwdCI+CiAgICA8cGF0aCBmaWxsPSIjMGI3MjI2IiBkPSJNMCAwaDIxMy4zdjQ4MEgweiIvPgogICAgPHBhdGggZmlsbD0iI2ZmMCIgZD0iTTIxMy4zIDBoMjEzLjN2NDgwSDIxMy4zeiIvPgogICAgPHBhdGggZmlsbD0iI2JjMDAwMCIgZD0iTTQyNi42IDBINjQwdjQ4MEg0MjYuNnoiLz4KICA8L2c+CiAgPHBhdGggZmlsbD0iIzBiNzIyNiIgZD0iTTM0MiAyMTguOGg3MS44bC01Ni42IDQzLjYgMjAuNyA2OS4zLTU2LjYtNDMuNi01Ni42IDQxLjYgMjAuNy02Ny4zLTU2LjYtNDMuNmg2OS44bDIyLjctNzEuM3oiLz4KPC9zdmc+Cg=="); }
.tzb-flag-CI { background-image: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGlkPSJmbGFnLWljb25zLWNpIiB2aWV3Qm94PSIwIDAgNjQwIDQ4MCI+CiAgPGcgZmlsbC1ydWxlPSJldmVub2RkIj4KICAgIDxwYXRoIGZpbGw9IiMwMGNkMDAiIGQ9Ik00MjYuOCAwSDY0MHY0ODBINDI2Ljh6Ii8+CiAgICA8cGF0aCBmaWxsPSIjZmY5YTAwIiBkPSJNMCAwaDIxMi45djQ4MEgweiIvPgogICAgPHBhdGggZmlsbD0iI2ZmZiIgZD0iTTIxMi45IDBoMjE0djQ4MGgtMjE0eiIvPgogIDwvZz4KPC9zdmc+Cg=="); }
.tzb-flag-CM { background-image: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiBpZD0iZmxhZy1pY29ucy1jbSIgdmlld0JveD0iMCAwIDY0MCA0ODAiPgogIDxwYXRoIGZpbGw9IiMwMDdhNWUiIGQ9Ik0wIDBoMjEzLjN2NDgwSDB6Ii8+CiAgPHBhdGggZmlsbD0iI2NlMTEyNiIgZD0iTTIxMy4zIDBoMjEzLjR2NDgwSDIxMy4zeiIvPgogIDxwYXRoIGZpbGw9IiNmY2QxMTYiIGQ9Ik00MjYuNyAwSDY0MHY0ODBINDI2Ljd6Ii8+CiAgPGcgZmlsbD0iI2ZjZDExNiIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMzIwIDI0MClzY2FsZSg3LjExMTEpIj4KICAgIDxnIGlkPSJjbS1iIj4KICAgICAgPHBhdGggaWQ9ImNtLWEiIGQ9Ik0wLTgtMi41LS40IDEuMy45eiIvPgogICAgICA8dXNlIHhsaW5rOmhyZWY9IiNjbS1hIiB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiB0cmFuc2Zvcm09InNjYWxlKC0xIDEpIi8+CiAgICA8L2c+CiAgICA8dXNlIHhsaW5rOmhyZWY9IiNjbS1iIiB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiB0cmFuc2Zvcm09InJvdGF0ZSg3MikiLz4KICAgIDx1c2UgeGxpbms6aHJlZj0iI2NtLWIiIHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIHRyYW5zZm9ybT0icm90YXRlKDE0NCkiLz4KICAgIDx1c2UgeGxpbms6aHJlZj0iI2NtLWIiIHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIHRyYW5zZm9ybT0icm90YXRlKC0xNDQpIi8+CiAgICA8dXNlIHhsaW5rOmhyZWY9IiNjbS1iIiB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiB0cmFuc2Zvcm09InJvdGF0ZSgtNzIpIi8+CiAgPC9nPgo8L3N2Zz4K"); }
.tzb-flag-GB { background-image: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGlkPSJmbGFnLWljb25zLWdiIiB2aWV3Qm94PSIwIDAgNjQwIDQ4MCI+CiAgPHBhdGggZmlsbD0iIzAxMjE2OSIgZD0iTTAgMGg2NDB2NDgwSDB6Ii8+CiAgPHBhdGggZmlsbD0iI0ZGRiIgZD0ibTc1IDAgMjQ0IDE4MUw1NjIgMGg3OHY2Mkw0MDAgMjQxbDI0MCAxNzh2NjFoLTgwTDMyMCAzMDEgODEgNDgwSDB2LTYwbDIzOS0xNzhMMCA2NFYweiIvPgogIDxwYXRoIGZpbGw9IiNDODEwMkUiIGQ9Im00MjQgMjgxIDIxNiAxNTl2NDBMMzY5IDI4MXptLTE4NCAyMCA2IDM1TDU0IDQ4MEgwek02NDAgMHYzTDM5MSAxOTFsMi00NEw1OTAgMHpNMCAwbDIzOSAxNzZoLTYwTDAgNDJ6Ii8+CiAgPHBhdGggZmlsbD0iI0ZGRiIgZD0iTTI0MSAwdjQ4MGgxNjBWMHpNMCAxNjB2MTYwaDY0MFYxNjB6Ii8+CiAgPHBhdGggZmlsbD0iI0M4MTAyRSIgZD0iTTAgMTkzdjk2aDY0MHYtOTZ6TTI3MyAwdjQ4MGg5NlYweiIvPgo8L3N2Zz4K"); }
.tzb-flag-DE { background-image: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGlkPSJmbGFnLWljb25zLWRlIiB2aWV3Qm94PSIwIDAgNjQwIDQ4MCI+CiAgPHBhdGggZmlsbD0iI2ZjMCIgZD0iTTAgMzIwaDY0MHYxNjBIMHoiLz4KICA8cGF0aCBmaWxsPSIjMDAwMDAxIiBkPSJNMCAwaDY0MHYxNjBIMHoiLz4KICA8cGF0aCBmaWxsPSJyZWQiIGQ9Ik0wIDE2MGg2NDB2MTYwSDB6Ii8+Cjwvc3ZnPgo="); }
.tzb-flag-ES { background-image: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA2NDAgNDgwIj48cmVjdCB3aWR0aD0iNjQwIiBoZWlnaHQ9IjQ4MCIgZmlsbD0iI2M2MGIxZSIvPjxyZWN0IHdpZHRoPSI2NDAiIGhlaWdodD0iMjQwIiB5PSIxMjAiIGZpbGw9IiNmZmM0MDAiLz48L3N2Zz4K"); }
.tzb-flag-IT { background-image: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGlkPSJmbGFnLWljb25zLWl0IiB2aWV3Qm94PSIwIDAgNjQwIDQ4MCI+CiAgPGcgZmlsbC1ydWxlPSJldmVub2RkIiBzdHJva2Utd2lkdGg9IjFwdCI+CiAgICA8cGF0aCBmaWxsPSIjZmZmIiBkPSJNMCAwaDY0MHY0ODBIMHoiLz4KICAgIDxwYXRoIGZpbGw9IiMwMDkyNDYiIGQ9Ik0wIDBoMjEzLjN2NDgwSDB6Ii8+CiAgICA8cGF0aCBmaWxsPSIjY2UyYjM3IiBkPSJNNDI2LjcgMEg2NDB2NDgwSDQyNi43eiIvPgogIDwvZz4KPC9zdmc+Cg=="); }
.tzb-flag-PT { background-image: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiBpZD0iZmxhZy1pY29ucy1wdCIgdmlld0JveD0iMCAwIDY0MCA0ODAiPgogIDxwYXRoIGZpbGw9InJlZCIgZD0iTTI1NiAwaDM4NHY0ODBIMjU2eiIvPgogIDxwYXRoIGZpbGw9IiMwNjAiIGQ9Ik0wIDBoMjU2djQ4MEgweiIvPgogIDxnIGZpbGw9IiNmZjAiIGZpbGwtcnVsZT0iZXZlbm9kZCIgc3Ryb2tlPSIjMDAwIiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiIHN0cm9rZS13aWR0aD0iLjYiPgogICAgPHBhdGggZD0iTTMzOS41IDMwNi4yYy0zMi4zLTEtMTgwLTkzLjItMTgxLTEwOGw4LjEtMTMuNWMxNC43IDIxLjMgMTY1LjcgMTExIDE4MC42IDEwNy44eiIvPgogICAgPHBhdGggZD0iTTE2NC45IDE4Mi44Yy0yLjkgNy44IDM4LjYgMzMuNCA4OC40IDYzLjhzOTIuOSA0OSA5NiA0Ni40bDEuNS0yLjhxLS45IDEuNi00LjMuNmMtMTMuNS0zLjktNDguNi0yMC05Mi4xLTQ2LjQtNDMuNi0yNi40LTgxLjQtNTAuNy04Ny4zLTYxYTYgNiAwIDAgMS0uNi0zLjFoLS4ybC0xLjIgMi4yem0xNzUuMyAxMjMuOHEtLjcgMS4zLTMuNS44Yy0xMi0xLjMtNDguNi0xOS4xLTkxLjktNDUtNTAuNC0zMC4yLTkyLTU3LjYtODcuNC02NC44bDEuMi0yLjIuMi4xYy00IDEyLjIgODIuMSA2MS40IDg3LjIgNjQuNiA0OS44IDMwLjggOTEuOCA0OC45IDk1LjUgNDQuMnoiLz4KICAgIDxwYXRoIGQ9Ik0yNTYuMiAyMDcuMmMzMi4yLS4zIDcyLTQuNCA5NS0xMy42bC01LThjLTEzLjUgNy41LTUzLjUgMTIuNS05MC4zIDEzLjItNDMuNC0uNC03NC4xLTQuNS04OS41LTE0LjhsLTQuNiA4LjZjMjguMiAxMiA1Ny4yIDE0LjUgOTQuNCAxNC42Ii8+CiAgICA8cGF0aCBkPSJNMzUyLjUgMTkzLjhjLS44IDEuMy0xNS44IDYuNC0zNy44IDEwLjJhMzgxIDM4MSAwIDAgMS01OC42IDQuMyA0MTYgNDE2IDAgMCAxLTU2LjItMy42Yy0yMy4xLTMuNi0zNS04LjYtMzkuNS0xMC40bDEuMS0yLjJjMTIuNyA1IDI0LjcgOCAzOC43IDEwLjJBNDEyIDQxMiAwIDAgMCAyNTYgMjA2YTM5MiAzOTIgMCAwIDAgNTguMy00LjNjMjIuNS0zLjcgMzQuOC04LjQgMzYuNi0xMC41em0tNC40LTguMWMtMi40IDItMTQuNiA2LjMtMzYgOS43YTM4OCAzODggMCAwIDEtNTUuOCA0Yy0yMiAwLTQwLjEtMS42LTUzLjgtMy42LTIxLjgtMi44LTMzLjQtOC0zNy42LTkuNGwxLjMtMi4yYzMuMyAxLjcgMTQuNCA2LjIgMzYuNSA5LjNhMzg1IDM4NSAwIDAgMCA1My42IDMuNCAzODQgMzg0IDAgMCAwIDU1LjQtNGMyMS41LTMgMzMuMS04LjQgMzQuOS05Ljh6TTE1MC4zIDI0NmMxOS44IDEwLjcgNjMuOSAxNiAxMDUuNiAxNi40IDM4IC4xIDg3LjQtNS44IDEwNS45LTE1LjZsLS41LTEwLjdjLTUuOCA5LTU4LjggMTcuNy0xMDUuOCAxNy40cy05MC43LTcuNi0xMDUuMy0xN3Y5LjUiLz4KICAgIDxwYXRoIGQ9Ik0zNjIuOCAyNDQuNXYyLjVjLTIuOCAzLjQtMjAuMiA4LjQtNDIgMTJhNDM0IDQzNCAwIDAgMS02NS40IDQuNCA0MDAgNDAwIDAgMCAxLTYyLTQuMyAxNTUgMTU1IDAgMCAxLTQ0LjQtMTJ2LTIuOWM5LjcgNi40IDM1LjkgMTEuMiA0NC43IDEyLjYgMTUuOCAyLjQgMzYuMSA0LjIgNjEuNyA0LjIgMjYuOSAwIDQ4LjQtMS45IDY1LTQuNCAxNS43LTIuMyAzOC04LjIgNDIuNC0xMi4xbTAtOXYyLjVjLTIuOCAzLjMtMjAuMiA4LjMtNDIgMTEuOWE0MzQgNDM0IDAgMCAxLTY1LjQgNC41IDQxNCA0MTQgMCAwIDEtNjItNC4zIDE1NSAxNTUgMCAwIDEtNDQuNC0xMnYtM2M5LjcgNi41IDM2IDExLjIgNDQuNyAxMi42YTQwOCA0MDggMCAwIDAgNjEuNyA0LjNjMjYuOSAwIDQ4LjUtMiA2NS00LjUgMTUuNy0yLjIgMzgtOC4xIDQyLjQtMTJtLTEwNyA2OC44Yy00NS42LS4yLTg0LjctMTIuNC05My0xNC40bDYgOS40YTI1MCAyNTAgMCAwIDAgODcuNCAxNC4zYzM0LjctMSA2NS0zLjcgODYuMy0xNC4xbDYuMi05LjhjLTE0LjUgNi45LTY0IDE0LjYtOTMgMTQuNiIvPgogICAgPHBhdGggZD0ibTM0NC45IDI5Ny4zLTIuOCA0Yy0xMCAzLjYtMjYgNy40LTMyLjYgOC40YTI5NiAyOTYgMCAwIDEtNTMuNyA1Yy00MC40LS42LTczLjUtOC41LTg5LTE1LjNsLTEuMy0yLjEuMi0uNCAyLjEuOWEyODcgMjg3IDAgMCAwIDg4LjIgMTQuNWMxOC44IDAgMzcuNS0yLjEgNTIuNi00LjggMjMuMi00LjcgMzIuNi04LjIgMzUuNS05LjhsLjctLjR6bTUuMy04LjgtMiAzLjVjLTUuNCAyLTIwIDYuMi00MS4zIDkuMi0xNCAxLjktMjIuNyAzLjgtNTAuNiA0LjNhMzQ3IDM0NyAwIDAgMS05NC4yLTE0TDE2MSAyODlhMzkwIDM5MCAwIDAgMCA5NS40IDE0YzI1LjUtLjUgMzYuNC0yLjQgNTAuMy00LjMgMjQuOC0zLjggMzcuMy04IDQxLTkuMXYtLjJsMi42LTF6Ii8+CiAgICA8cGF0aCBkPSJNMzUwLjggMjM3LjZjLjEgMzAtMTUuMyA1Ny0yNy42IDY4LjhhOTkgOTkgMCAwIDEtNjcuOCAyOC4yYy0zMC4zLjUtNTguOC0xOS4yLTY2LjUtMjcuOWExMDEgMTAxIDAgMCAxLTI3LjUtNjcuNGMxLjgtMzIuOCAxNC43LTU1LjYgMzMuMy03MS4zYTEwMCAxMDAgMCAwIDEgNjQuMi0yMi43IDk4IDk4IDAgMCAxIDcxIDM1LjZjMTIuNSAxNS4yIDE4IDMxLjcgMjAuOSA1Ni43TTI1NS42IDEzNWExMDYgMTA2IDAgMCAxIDEwNiAxMDUuMiAxMDUuNiAxMDUuNiAwIDEgMS0yMTEuNCAwYy0uMS01OCA0Ny4zLTEwNS4yIDEwNS40LTEwNS4yIi8+CiAgICA8cGF0aCBkPSJNMjU1LjkgMTM0LjVjNTguMiAwIDEwNS42IDQ3LjQgMTA1LjYgMTA1LjZTMzE0LjEgMzQ1LjcgMjU2IDM0NS43cy0xMDUuNi00Ny40LTEwNS42LTEwNS42UzE5Ny44IDEzNC41IDI1NiAxMzQuNXpNMTUyLjYgMjQwYzAgNTYuOCA0Ni43IDEwMy4zIDEwMy4zIDEwMy4zUzM1OS4yIDI5Ni44IDM1OS4yIDI0MHMtNDYuNy0xMDMuMy0xMDMuMy0xMDMuM1MxNTIuNiAxODMuMiAxNTIuNiAyNDAiLz4KICAgIDxwYXRoIGQ9Ik0yNTYgMTQzLjNhOTcgOTcgMCAwIDEgOTYuNyA5Ni43IDk3IDk3IDAgMCAxLTk2LjcgOTYuOGMtNTMgMC05Ni43LTQzLjYtOTYuNy05Ni44YTk3IDk3IDAgMCAxIDk2LjctOTYuN00xNjEuNiAyNDBjMCA1MiA0Mi42IDk0LjQgOTQuNCA5NC40czk0LjQtNDIuNSA5NC40LTk0LjQtNDIuNi05NC40LTk0LjQtOTQuNGE5NSA5NSAwIDAgMC05NC40IDk0LjQiLz4KICAgIDxwYXRoIGQ9Ik0yNjAuMyAxMzRoLTkuMXYyMTIuM2g5eiIvPgogICAgPHBhdGggZD0iTTI1OS4zIDEzMi44aDIuM3YyMTQuN2gtMi4yVjEzMi44em0tOSAwaDIuNHYyMTQuN2gtMi4zeiIvPgogICAgPHBhdGggZD0iTTM2MS42IDI0NC4ydi03LjhsLTYuNC02LTM2LjMtOS42LTUyLjItNS4zLTYzIDMuMi00NC44IDEwLjYtOSA2Ljd2Ny45bDIyLjktMTAuMyA1NC40LTguNWg1Mi4zbDM4LjQgNC4yIDI2LjYgNi40eiIvPgogICAgPHBhdGggZD0iTTI1NiAyMjMuOGMyNC45IDAgNDkgMi4zIDY4LjMgNiAxOS44IDQgMzMuNyA5IDM4LjUgMTQuNXYyLjhjLTUuOC03LTI0LjUtMTItMzktMTUtMTktMy42LTQzLTYtNjcuOS02LTI2LjEgMC01MC41IDIuNi02OS4zIDYuMi0xNSAzLTM1LjEgOS0zNy42IDE0Ljh2LTIuOWMxLjMtNCAxNi4zLTEwIDM3LjMtMTQuMyAxOC45LTMuNyA0My4zLTYuMSA2OS42LTYuMXptMC05LjFhMzgzIDM4MyAwIDAgMSA2OC4zIDZjMTkuOCA0IDMzLjcgOSAzOC41IDE0LjZ2Mi43Yy01LjgtNi45LTI0LjUtMTItMzktMTQuOS0xOS0zLjctNDMtNi02Ny45LTZhMzc2IDM3NiAwIDAgMC02OS4yIDYuMmMtMTQuNSAyLjctMzUuNCA4LjktMzcuNyAxNC43di0yLjhjMS40LTQgMTYuNi0xMC4zIDM3LjMtMTQuMyAxOS0zLjcgNDMuMy02LjIgNjkuNy02LjJtLS42LTQ2LjJjMzkuMy0uMiA3My42IDUuNSA4OS4zIDEzLjVsNS43IDEwYy0xMy42LTcuNC01MC42LTE1LTk0LjktMTQtMzYuMS4zLTc0LjcgNC05NCAxNC40bDYuOC0xMS40YzE1LjktOC4zIDUzLjMtMTIuNSA4Ny4xLTEyLjUiLz4KICAgIDxwYXRoIGQ9Ik0yNTYgMTc2LjdhMzU0IDM1NCAwIDAgMSA2MS4zIDQuM2MxNiAzIDMxLjMgNy40IDMzLjUgOS44bDEuNyAzYy01LjMtMy40LTE4LjYtNy4zLTM1LjYtMTAuNXMtMzguNy00LjMtNjEtNC4yYy0yNS4zLS4xLTQ1IDEuMi02MS44IDQuMmExMDkgMTA5IDAgMCAwLTMzLjMgMTAuM2wxLjctMy4xYzYtMyAxNS4zLTYuNyAzMS4xLTkuNiAxNy41LTMuMiAzNy40LTQuMSA2Mi40LTQuMm0wLTljMjEuNC0uMiA0Mi42IDEgNTkuMSA0YTk2IDk2IDAgMCAxIDMwLjYgMTBsMi41IDRjLTQuMi00LjctMjAtOS4yLTM0LjEtMTEuNi0xNi40LTIuOS0zNi43LTQtNTguMS00LjJhMzYxIDM2MSAwIDAgMC01OS41IDQuNCA5NyA5NyAwIDAgMC0yOS42IDkuMWwyLjItMy4zYzUuOC0zIDE1LjItNS44IDI3LTguMWEzNTcgMzU3IDAgMCAxIDU5LjktNC40ek0zMDguNCAyODRhMjc2IDI3NiAwIDAgMC01Mi41LTRjLTY1LjUuOC04Ni42IDEzLjUtODkuMiAxNy4zbC01LThjMTYuOC0xMiA1Mi40LTE4LjggOTQuNi0xOC4ycTMyLjkuNSA1Ni42IDVsLTQuNSA4Ii8+CiAgICA8cGF0aCBkPSJNMjU1LjYgMjc4LjljMTguMi4zIDM2IDEgNTMuMyA0LjJsLTEuMiAyLjJjLTE2LTMtMzMuMi00LTUyLTQtMjQuMy0uMi00OC43IDIuMS03MCA4LjItNi43IDEuOS0xNy44IDYuMi0xOSA5LjhsLTEuMi0yYy40LTIuMiA3LTYuNiAxOS42LTEwIDI0LjQtNyA0Ny4yLTguMyA3MC41LTguNG0uOC05LjJhMzI3IDMyNyAwIDAgMSA1Ny4zIDVsLTEuMyAyLjNhMjk5IDI5OSAwIDAgMC01Ni00LjljLTI0LjIgMC00OS45IDEuOC03My4zIDguNi03LjUgMi4yLTIwLjYgNy0yMSAxMC43bC0xLjItMi4yYy4yLTMuNCAxMS41LTcuOSAyMS43LTEwLjggMjMuNS02LjkgNDkuMy04LjYgNzMuOC04LjciLz4KICAgIDxwYXRoIGQ9Im0zNDkuNCAyOTAuNS03LjggMTIuMy0yMi43LTIwLjEtNTguNi0zOS41LTY2LjItMzYuMy0zNC4zLTExLjcgNy4zLTEzLjYgMi41LTEuMyAyMS4zIDUuMyA3MC40IDM2LjMgNDAuNiAyNS42TDMzNiAyNzJsMTMuOSAxNnoiLz4KICAgIDxwYXRoIGQ9Ik0xNTguNiAxOTUuNWM2LTQgNTAuMiAxNS42IDk2LjYgNDMuNiA0Ni4xIDI4IDkwLjMgNTkuNiA4Ni4zIDY1LjVsLTEuMyAyLjEtLjYuNWMuMS0uMS44LTEgMC0zLjEtMi02LjUtMzMuNC0zMS41LTg1LjMtNjIuOS01MC43LTMwLjEtOTIuOS00OC4zLTk3LTQzLjF6TTM1MSAyOTAuNGMzLjgtNy42LTM3LjItMzguNS04OC4xLTY4LjYtNTItMjkuNS04OS42LTQ2LjktOTYuNS00MS43TDE2NSAxODNsLjQtLjVjMS4yLTEgMy4zLTEgNC4yLTEgMTEuOC4yIDQ1LjUgMTUuNyA5Mi44IDQyLjggMjAuOCAxMiA4Ny42IDU1IDg3LjMgNjcgMCAxIC4xIDEuMi0uMyAxLjhsMS43LTIuNnoiLz4KICA8L2c+CiAgPGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMCAyNi43KXNjYWxlKDEuMDY2NjcpIj4KICAgIDxwYXRoIGZpbGw9IiNmZmYiIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLXdpZHRoPSIuNyIgZD0iTTE4MC42IDIxMWE1OSA1OSAwIDAgMCAxNy41IDQxLjcgNTkgNTkgMCAwIDAgNDEuOCAxNy42IDU5IDU5IDAgMCAwIDQyLTE3LjQgNTkgNTkgMCAwIDAgMTcuNC00MS44di03OS4ybC0xMTguNy0uMnoiLz4KICAgIDxwYXRoIGZpbGw9InJlZCIgc3Ryb2tlPSIjMDAwIiBzdHJva2Utd2lkdGg9Ii41IiBkPSJNMTgzIDIxMS4xYTU2IDU2IDAgMCAwIDE2LjggNDAgNTcgNTcgMCAwIDAgNDAuMiAxNi44IDU3IDU3IDAgMCAwIDQwLjItMTYuNiA1NiA1NiAwIDAgMCAxNi43LTQwdi03N0gxODN2NzYuOG05MS01My43djQ4LjlsLS4xIDUuMWEzMyAzMyAwIDAgMS0xMCAyNCAzNCAzNCAwIDAgMS0yNCAxMGMtOS40IDAtMTcuNy00LTIzLjktMTAuMmEzNCAzNCAwIDAgMS0xMC0yNHYtNTR6Ii8+CiAgICA8ZyBpZD0icHQtZSI+CiAgICAgIDxnIGlkPSJwdC1kIiBmaWxsPSIjZmYwIiBzdHJva2U9IiMwMDAiIHN0cm9rZS13aWR0aD0iLjUiPgogICAgICAgIDxwYXRoIHN0cm9rZT0ibm9uZSIgZD0iTTE5MC4yIDE1NC40Yy4xLTUuNSA0LTYuOCA0LTYuOC4xIDAgNC4zIDEuNCA0LjMgNi45eiIvPgogICAgICAgIDxwYXRoIGQ9Im0xODYuOCAxNDcuNy0uNyA2LjNoNC4yYzAtNS4yIDQtNiA0LTYgLjEgMCA0IDEuMSA0LjEgNmg0LjJsLS44LTYuNHptLTEgNi40aDE3cS41IDAgLjYuNyAwIC44LS42LjhoLTE3cS0uNSAwLS42LS44IDAtLjcuNy0uN3oiLz4KICAgICAgICA8cGF0aCBkPSJNMTkyIDE1NGMwLTMuMyAyLjMtNC4yIDIuMy00LjJzMi4zIDEgMi4zIDQuMkgxOTJtLTUuOC05aDE2LjNxLjUuMS42LjggMCAuNS0uNi42aC0xNi4zcS0uNSAwLS42LS43IDAtLjUuNi0uNnptLjQgMS41SDIwMnEuNSAwIC42Ljd0LS42LjdoLTE1LjVxLS42IDAtLjYtLjd0LjYtLjd6bTUtMTAuNmgxLjJ2LjhoLjl2LS44aDEuM3YuOWguOXYtMWgxLjJ2MnEwIC42LS41LjZoLTQuNHEtLjUgMC0uNi0uNXptNC42IDIuNy4zIDYuNGgtNC4zbC4zLTYuNWgzLjciLz4KICAgICAgICA8cGF0aCBpZD0icHQtYSIgZD0iTTE5MSAxNDEuNnYzLjRoLTR2LTMuNHoiLz4KICAgICAgICA8dXNlIHhsaW5rOmhyZWY9IiNwdC1hIiB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiB4PSIxMC42Ii8+CiAgICAgICAgPHBhdGggaWQ9InB0LWIiIGQ9Ik0xODYuMyAxMzloMS4ydjFoLjl2LTFoMS4ydjFoLjl2LTFoMS4ydjJxMCAuNi0uNS42aC00LjNsLS42LS42eiIvPgogICAgICAgIDx1c2UgeGxpbms6aHJlZj0iI3B0LWIiIHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIHg9IjEwLjYiLz4KICAgICAgICA8cGF0aCBmaWxsPSIjMDAwMDAxIiBzdHJva2U9Im5vbmUiIGQ9Ik0xOTMuOSAxNDAuNmMwLS42LjktLjYuOSAwdjEuNmgtLjl6Ii8+CiAgICAgICAgPHBhdGggaWQ9InB0LWMiIGZpbGw9IiMwMDAwMDEiIHN0cm9rZT0ibm9uZSIgZD0iTTE4OC42IDE0Mi44YzAtLjYuOC0uNi44IDB2MS4yaC0uOHoiLz4KICAgICAgICA8dXNlIHhsaW5rOmhyZWY9IiNwdC1jIiB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiB4PSIxMC42Ii8+CiAgICAgIDwvZz4KICAgICAgPHVzZSB4bGluazpocmVmPSIjcHQtZCIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgeT0iNDYuMyIvPgogICAgICA8dXNlIHhsaW5rOmhyZWY9IiNwdC1kIiB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiB0cmFuc2Zvcm09InJvdGF0ZSgtNDUuMiAzMTIuOCAxODApIi8+CiAgICA8L2c+CiAgICA8dXNlIHhsaW5rOmhyZWY9IiNwdC1kIiB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiB4PSI0NS43Ii8+CiAgICA8dXNlIHhsaW5rOmhyZWY9IiNwdC1lIiB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiB0cmFuc2Zvcm09Im1hdHJpeCgtMSAwIDAgMSA0NzkuOCAwKSIvPgogICAgPGcgaWQ9InB0LWYiIGZpbGw9IiNmZmYiPgogICAgICA8cGF0aCBmaWxsPSIjMDM5IiBkPSJNMjMyLjYgMjAyLjRhOCA4IDAgMCAwIDIuMiA1LjcgNyA3IDAgMCAwIDUuMyAyLjRxMy4yLS4yIDUuMy0yLjRhOCA4IDAgMCAwIDIuMi01Ljd2LTEwLjhoLTE1eiIvPgogICAgICA8Y2lyY2xlIGN4PSIyMzYuMSIgY3k9IjE5NS43IiByPSIxLjUiLz4KICAgICAgPGNpcmNsZSBjeD0iMjQ0LjQiIGN5PSIxOTUuNyIgcj0iMS41Ii8+CiAgICAgIDxjaXJjbGUgY3g9IjI0MC4yIiBjeT0iMTk5LjciIHI9IjEuNSIvPgogICAgICA8Y2lyY2xlIGN4PSIyMzYuMSIgY3k9IjIwMy45IiByPSIxLjUiLz4KICAgICAgPGNpcmNsZSBjeD0iMjQ0LjQiIGN5PSIyMDMuOSIgcj0iMS41Ii8+CiAgICA8L2c+CiAgICA8dXNlIHhsaW5rOmhyZWY9IiNwdC1mIiB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiB5PSItMjYiLz4KICAgIDx1c2UgeGxpbms6aHJlZj0iI3B0LWYiIHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIHg9Ii0yMC44Ii8+CiAgICA8dXNlIHhsaW5rOmhyZWY9IiNwdC1mIiB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiB4PSIyMC44Ii8+CiAgICA8dXNlIHhsaW5rOmhyZWY9IiNwdC1mIiB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiB5PSIyNS44Ii8+CiAgPC9nPgo8L3N2Zz4K"); }
.tzb-flag-NL { background-image: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGlkPSJmbGFnLWljb25zLW5sIiB2aWV3Qm94PSIwIDAgNjQwIDQ4MCI+CiAgPHBhdGggZmlsbD0iI2FlMWMyOCIgZD0iTTAgMGg2NDB2MTYwSDB6Ii8+CiAgPHBhdGggZmlsbD0iI2ZmZiIgZD0iTTAgMTYwaDY0MHYxNjBIMHoiLz4KICA8cGF0aCBmaWxsPSIjMjE0NjhiIiBkPSJNMCAzMjBoNjQwdjE2MEgweiIvPgo8L3N2Zz4K"); }
.tzb-flag-US { background-image: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGlkPSJmbGFnLWljb25zLXVzIiB2aWV3Qm94PSIwIDAgNjQwIDQ4MCI+CiAgPHBhdGggZmlsbD0iI2JkM2Q0NCIgZD0iTTAgMGg2NDB2NDgwSDAiLz4KICA8cGF0aCBzdHJva2U9IiNmZmYiIHN0cm9rZS13aWR0aD0iMzciIGQ9Ik0wIDU1LjNoNjQwTTAgMTI5aDY0ME0wIDIwM2g2NDBNMCAyNzdoNjQwTTAgMzUxaDY0ME0wIDQyNWg2NDAiLz4KICA8cGF0aCBmaWxsPSIjMTkyZjVkIiBkPSJNMCAwaDM2NC44djI1OC41SDAiLz4KICA8bWFya2VyIGlkPSJ1cy1hIiBtYXJrZXJIZWlnaHQ9IjMwIiBtYXJrZXJXaWR0aD0iMzAiPgogICAgPHBhdGggZmlsbD0iI2ZmZiIgZD0ibTE0IDAgOSAyN0wwIDEwaDI4TDUgMjd6Ii8+CiAgPC9tYXJrZXI+CiAgPHBhdGggZmlsbD0ibm9uZSIgbWFya2VyLW1pZD0idXJsKCN1cy1hKSIgZD0ibTAgMCAxNiAxMWg2MSA2MSA2MSA2MSA2MEw0NyAzN2g2MSA2MSA2MCA2MUwxNiA2M2g2MSA2MSA2MSA2MSA2MEw0NyA4OWg2MSA2MSA2MCA2MUwxNiAxMTVoNjEgNjEgNjEgNjEgNjBMNDcgMTQxaDYxIDYxIDYwIDYxTDE2IDE2Nmg2MSA2MSA2MSA2MSA2MEw0NyAxOTJoNjEgNjEgNjAgNjFMMTYgMjE4aDYxIDYxIDYxIDYxIDYweiIvPgo8L3N2Zz4K"); }
.tzb-phone-field .tzb-phone-dial:hover,
.tzb-phone-field .tzb-phone-dial:focus { border-color: var(--tzb-ink); }
/* v1.9.1 — Chloé: "à l'étape 3 agrandi la balise pour saisir le numéro de
   téléphone". Was `min-width: 0`, the actual root cause of the tiny box. */
.tzb-phone-field input[type="tel"] { flex: 1; min-width: 110px; }
.tzb-staff-list .tzb-phone-field,
.tzb-waitlist-form .tzb-phone-field { margin-bottom: 10px; }
.tzb-staff-list .tzb-phone-field input,
.tzb-waitlist-form .tzb-phone-field input { margin-bottom: 0; }

.tzb-payment-methods { margin-top: 8px; }
.tzb-payment-title { font-size: 13px; font-weight: 600; margin: 0 0 8px; }
.tzb-payment-list { display: flex; flex-direction: column; gap: 8px; }
.tzb-payment-option {
	position: relative;
	display: flex; align-items: center; gap: 12px;
	border: 1px solid var(--tzb-line);
	border-radius: 4px;
	padding: 10px 14px;
	cursor: pointer;
	transition: border-color .12s ease, background .12s ease;
}
.tzb-payment-option:hover { background: var(--tzb-sand); }
.tzb-payment-option.is-selected { border-color: var(--tzb-ink); background: var(--tzb-sand); }
/* v1.9.1 — Chloé: "revois l'affichage des modes de paiement". The icon and
   label were landing in a corner instead of inline next to the radio.
   Root cause: the host theme/page-builder (Astra + Spectra, on the
   Templiz sites) styles native `input[type=radio]`/`[type=checkbox]`
   globally with `position: absolute; opacity: 0` to hide them behind a
   custom-drawn control — a very common pattern, but since our own radio
   never reset `position`/`opacity`, it inherited that and got pulled out
   of the normal flow, which then dragged the rest of the row's layout
   with it. `.tzb-widget input[type="radio"], .tzb-widget
   input[type="checkbox"]` below forces them back to `static`/opaque
   everywhere in the widget (extras checkboxes included), and
   `position: relative` above keeps this option a safe containing block
   in case any other host rule still tries to position something inside
   it absolutely. */
.tzb-payment-option input[type="radio"] { margin: 0; accent-color: var(--tzb-ink); flex-shrink: 0; }
.tzb-payment-icon { display: inline-flex; align-items: center; flex-shrink: 0; line-height: 0; height: 22px; }
.tzb-payment-icon img { height: 22px; width: auto; max-width: 52px; object-fit: contain; }
.tzb-payment-icon svg { display: block; }
.tzb-payment-label { font-size: 14px; }

.tzb-widget input[type="radio"],
.tzb-widget input[type="checkbox"] {
	position: static !important;
	opacity: 1 !important;
	width: 16px;
	height: 16px;
	margin: 0;
}
/**
 * item #278 (13e vague, retour Chloé) — "le checkbox apparaît sous le
 * toggle switch [...] toujours visible quand j'active le toggle switch" :
 * la vraie cause, ratée aux deux tentatives précédentes (lot 11 : vérif de
 * la structure DOM/CSS ; lot 12 : renfort appearance:none + z-index) parce
 * qu'elle ne se trouvait pas du tout dans les règles ".tzb-toggle-switch"
 * elles-mêmes, mais ICI : la règle générique juste au-dessus (ajoutée en
 * v1.9.1 pour réafficher les vrais boutons radio/case du paiement et des
 * extras, que le thème hôte masque globalement) force TOUTE case à cocher
 * du widget en `position:static !important; opacity:1 !important` — donc
 * absolument toutes, y compris la case cachée derrière chaque interrupteur
 * à bascule (.tzb-toggle-switch input), qu'on voulait au contraire garder
 * hors du flux et invisible derrière la piste dessinée en CSS. `!important`
 * bat notre déclaration normale (.tzb-toggle-switch input) quelle que soit
 * sa spécificité — d'où la case native qui redevenait pleinement visible
 * ET repassait dans le flux normal du document juste après l'interrupteur
 * (donc "sous" lui), history vécue plus nettement une fois cochée car la
 * coche colorée du navigateur est plus visible qu'une case vide. Fix :
 * règle dédiée ci-dessous, plus spécifique ET elle aussi !important (pour
 * rivaliser dans le même palier de priorité), qui restaure explicitement
 * le comportement voulu uniquement pour les cases des interrupteurs.
 */
.tzb-widget .tzb-toggle-switch input[type="checkbox"] {
	position: absolute !important;
	opacity: 0 !important;
	width: 100% !important;
	height: 100% !important;
	margin: 0 !important;
}
.tzb-payment-note { font-size: 12px; color: var(--tzb-muted); margin: 8px 0 0; }
/* retour Chloé (oct. 2026) — note "Paiement sur place" quand aucun moyen de
   paiement en ligne n'est configuré (voir renderPaymentMethods()) ; variante
   -warning quand un acompte était normalement dû mais ne peut pas être
   collecté en ligne, pour la distinguer visuellement du cas sans acompte. */
.tzb-payment-onsite { margin-top: 0; }
.tzb-payment-onsite-warning { color: var( --tzb-accent, #B08968 ); }

.tzb-nav {
	display: flex;
	justify-content: space-between;
	gap: 16px;
	margin-top: 24px;
}
.tzb-nav .tzb-btn { flex-shrink: 0; }

@media (max-width: 480px) {
	.tzb-nav { flex-wrap: wrap; }
	/* Nouvelle demande de Chloé : "revois la taille des balises prénom nom
	   e-mail" — .tzb-field-row laissait deux champs (ex. prénom + nom, ou
	   e-mail + téléphone) se partager la largeur dès que chacun dépassait
	   son min-width (140px/220px), les rendant étroits et le texte saisi
	   à moitié caché sur un petit écran. Chacun prend sa propre ligne en
	   dessous de ce seuil, comme l'attachment/textarea juste au-dessus.
	*/
	.tzb-field-row { flex-direction: column; }
	.tzb-field-row input,
	.tzb-field-row .tzb-phone-field { flex-basis: auto; min-width: 0; width: 100%; }
}

/* 64e vague — twin container-query of the @media block just above, same
   reasoning as the one near .tzb-widget-inner plus haut : largeur RÉELLE
   du widget plutôt que celle de la fenêtre. */
@container (max-width: 480px) {
	.tzb-nav { flex-wrap: wrap; }
	.tzb-field-row { flex-direction: column; }
	.tzb-field-row input,
	.tzb-field-row .tzb-phone-field { flex-basis: auto; min-width: 0; width: 100%; }
}

.tzb-btn {
	appearance: none;
	-webkit-appearance: none;
	font: inherit;
	font-size: 14px;
	font-weight: 500;
	padding: 13px 26px;
	border: 1px solid var(--tzb-ink);
	border-radius: var(--tzb-radius);
	background: var(--tzb-ink);
	color: var(--tzb-paper);
	cursor: pointer;
	transition: background .15s ease, color .15s ease, border-color .15s ease, opacity .15s ease;
}
.tzb-btn:hover:not(:disabled) { background: #2b291f; border-color: #2b291f; }
.tzb-btn-ghost { background: transparent; color: var(--tzb-ink); }
.tzb-btn-ghost:hover:not(:disabled) { background: var(--tzb-sand); border-color: var(--tzb-ink); }
.tzb-btn:disabled { opacity: 0.4; cursor: default; }
.tzb-btn-small { padding: 9px 16px; font-size: 13px; }

.tzb-confirmation { text-align: center; padding: 20px 0; }
.tzb-confirmation-icon {
	width: 44px; height: 44px;
	margin: 0 auto 20px;
	border: 1px solid var(--tzb-ink);
	border-radius: 50%;
	position: relative;
}
.tzb-confirmation-icon::after {
	content: "";
	position: absolute;
	left: 13px; top: 21px;
	width: 6px; height: 12px;
	border-right: 2px solid var(--tzb-ink);
	border-bottom: 2px solid var(--tzb-ink);
	transform: rotate(45deg) translateY(-4px);
}
/* v1.9.0 — a deposit-pending booking gets a "waiting" ring instead of a
   checkmark, so the confirmation screen doesn't visually read as "all
   done" when it isn't yet — see showConfirmation()'s isPending branch. */
.tzb-confirmation-icon.is-pending { border-color: var(--tzb-accent); }
.tzb-confirmation-icon.is-pending::after {
	left: 50%; top: 50%;
	width: 2px; height: 10px;
	border-right: none; border-bottom: none;
	background: var(--tzb-accent);
	transform: translate(-50%, -100%);
	border-radius: 1px;
}
.tzb-confirmation-icon.is-pending::before {
	content: "";
	position: absolute;
	left: 50%; top: 50%;
	width: 7px; height: 2px;
	background: var(--tzb-accent);
	transform: translate(0, -1px);
	border-radius: 1px;
}
.tzb-confirmation-title { font-family: var(--tzb-font-display); font-size: 22px; margin: 0 0 8px; }
.tzb-confirmation-text { color: var(--tzb-muted); }

.tzb-error {
	margin: 0 28px 24px;
	padding: 12px 14px;
	border: 1px solid #B3554A;
	color: #B3554A;
	font-size: 14px;
}

/**
 * 65e vague, retour Chloé — "sur desktop et tablette les balises prénom,
 * nom, email sont trop grandes [...] doivent être de la même taille que la
 * balise téléphone" : cause trouvée en inspectant le rendu réel sur
 * saas.templiz.com/thebarbieeffect — `.tzb-field-row input { flex: 1 1
 * 140px; min-width: 140px; }` (plus bas dans ce fichier) donne à chaque
 * champ une largeur plancher de 140px quand la ligne est en row (cas
 * normal). Mais dès que `.tzb-field-row` passe en `flex-direction: column`
 * ci-dessous (widget étroit — exactement le cas de cette page, panneau
 * encadré par la colonne "Comment ça marche ?"), le MÊME `flex-basis:
 * 140px` s'applique au nouvel axe principal, devenu vertical : chaque
 * champ se retrouvait donc avec une HAUTEUR plancher de 140px (resp. 220px
 * pour .tzb-phone-field) au lieu d'une largeur — d'où des balises Prénom/
 * Nom/Email démesurément hautes. Un correctif existait déjà pour le cas
 * encore plus étroit (`@media`/`@container (max-width: 480px)` plus haut
 * dans ce fichier, qui remet `flex-basis: auto`) mais s'arrêtait à 480px
 * alors que la bascule column démarre à 640px — d'où un "trou" entre 480
 * et 640px où les champs restaient en column SANS ce correctif, exactement
 * la largeur à laquelle ce panneau s'affiche ici. Le correctif est donc
 * descendu ici, au même seuil que la bascule column elle-même (640px),
 * pour que les deux changent toujours ensemble.
 */
@media (max-width: 640px) {
	.tzb-widget-inner { grid-template-columns: 1fr; }
	.tzb-summary-panel { border-right: none; border-bottom: 1px solid var(--tzb-line); padding: 16px 20px; }
	.tzb-summary-row { margin-bottom: 6px; }
	.tzb-panel { padding: 20px; }
	.tzb-steps { padding: 16px 20px 0; }
	.tzb-field-row { flex-direction: column; }
	.tzb-field-row input,
	.tzb-field-row .tzb-phone-field { flex-basis: auto; min-width: 0; width: 100%; }
}

/* 64e vague, retour Chloé — "rends cela responsive sur tous les
   appareils" : même bascule qu'au-dessus (sidebar + contenu en une seule
   colonne), mais déclenchée par la largeur RÉELLE du widget
   (`container-type: inline-size` posé sur .tzb-widget plus haut) plutôt
   que par la largeur de la fenêtre — couvre le cas d'un widget intégré
   dans une colonne étroite sur un grand écran, que le @media ci-dessus ne
   peut pas voir. Les navigateurs ne supportant pas les container queries
   (très rares en 2026) retombent simplement sur le @media ci-dessus.
   65e vague — même correctif flex-basis que le @media jumeau ci-dessus
   (voir son docblock), pour la même raison : SANS lui, c'est précisément
   via CE bloc-ci (container query, pas le @media) que le bug des balises
   Prénom/Nom/Email trop hautes se déclenchait sur un panneau large de 640px
   mais rendu plus étroit par sa page (cas réel constaté). */
@container (max-width: 640px) {
	.tzb-widget-inner { grid-template-columns: 1fr; }
	.tzb-summary-panel { border-right: none; border-bottom: 1px solid var(--tzb-line); padding: 16px 20px; }
	.tzb-summary-row { margin-bottom: 6px; }
	.tzb-panel { padding: 20px; }
	.tzb-steps { padding: 16px 20px 0; }
	.tzb-field-row { flex-direction: column; }
	.tzb-field-row input,
	.tzb-field-row .tzb-phone-field { flex-basis: auto; min-width: 0; width: 100%; }
}

/* Caractéristiques (ex. longueurs de cheveux à prix différents) : depuis la
   nouvelle demande de Chloé, ce choix vit dans sa propre étape ("variant",
   voir goToOptionsStep() dans booking-widget.js, qui y affiche aussi les
   extras depuis l'item 3 de la 51e vague) et réutilise directement
   .tzb-option-row/.tzb-option-main/.tzb-option-price (déjà stylées pour la
   liste des professionnels) — aucune classe dédiée n'est plus nécessaire ici.
*/

/* Extras (services supplémentaires) */
.tzb-extras-list { display: flex; flex-direction: column; gap: 8px; margin: 4px 0 4px; }
.tzb-extras-title { font-size: 13px; font-weight: 600; margin: 0; }
.tzb-extras-note { font-size: 12px; color: var(--tzb-muted); margin: 0 0 4px; }
.tzb-extra-option {
	display: flex; align-items: center; gap: 8px;
	border: 1px solid var(--tzb-line);
	border-radius: 4px;
	padding: 10px 12px;
	font-size: 14px;
	cursor: pointer;
	transition: background .12s ease;
}
.tzb-extra-option:hover { background: var(--tzb-sand); }
.tzb-extra-meta { margin-left: auto; color: var(--tzb-muted); font-size: 13px; white-space: nowrap; }

/* Payment link + QR shown on the confirmation screen */
.tzb-confirmation-payment { margin-top: 20px; }
/**
 * item #284 (14e vague, retour Chloé) — "le CTA contient un texte en noir
 * le texte doit être blanc" : .tzb-btn règle déjà color: var(--tzb-paper)
 * (blanc) sur fond var(--tzb-ink) (foncé), donc ce bouton devrait déjà être
 * lisible — mais .tzb-btn n'est pas scopé sous .tzb-widget et n'a pas de
 * !important, exactement le même genre de collision qu'item #278 (le thème
 * du site, Astra + Spectra, définit ses propres couleurs de lien "a" pour
 * le contenu, parfois en !important, qui l'emportent alors sur cette seule
 * règle de classe). Sélecteur plus spécifique + !important pour que ce CTA
 * précis résiste à ça, sans toucher .tzb-btn globalement (qui fonctionne
 * correctement partout ailleurs dans le widget).
 */
.tzb-confirmation-payment .tzb-btn { color: var(--tzb-paper) !important; }

/**
 * 61e vague, retour Chloé — item 4 : "ajoute un bouton qui doit renvoyer
 * vers le site des prestataires et un bouton où le client peux se connecter
 * à son espace client" — les 2 liens ajoutés par showConfirmation() dans
 * booking-widget.js (.tzb-confirmation-actions, voir widget.php), affichés
 * côte à côte, repliés sur mobile comme .tzb-nav un peu plus haut dans ce
 * fichier.
 */
.tzb-confirmation-actions { display: flex; justify-content: center; gap: 10px; flex-wrap: wrap; margin-top: 20px; }
.tzb-confirmation-qr { margin-top: 16px; }

/**
 * item #342 (21e vague, retour Chloé) — message affiché à la place du
 * bouton "Payer maintenant" une fois le paiement PayPal confirmé
 * automatiquement (voir pollPaymentStatus() dans booking-widget.js),
 * sans recharger la page.
 */
.tzb-payment-confirmed { color: #2E7D45; font-weight: 600; margin: 0; }
.tzb-confirmation-qr img { display: block; margin: 0 auto; border: 1px solid var(--tzb-line); }
.tzb-confirmation-qr p { font-size: 13px; color: var(--tzb-muted); margin-top: 8px; }

/* Promo code */
.tzb-promo-box { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; margin: 4px 0; }
.tzb-promo-input { flex: 1; min-width: 140px; border: 1px solid var(--tzb-line); border-radius: 4px; padding: 10px 12px; font: inherit; background: var(--tzb-paper); color: var(--tzb-ink); }
.tzb-promo-message { flex-basis: 100%; font-size: 13px; margin: 4px 0 0; }
.tzb-promo-success { color: #2E6B2E; }
.tzb-promo-error { color: #B3554A; }

/* Waitlist */
.tzb-waitlist-box { margin-top: 16px; padding: 14px; background: var(--tzb-sand); border: 1px solid var(--tzb-line); border-radius: 4px; }
.tzb-waitlist-intro { font-size: 13px; color: var(--tzb-muted); margin: 0 0 10px; }
.tzb-waitlist-form { display: flex; flex-direction: column; gap: 8px; }
/* item #331 (18e vague, retour Chloé) — même bug/correctif que .tzb-step et
   .tzb-attachment-preview ailleurs dans ce fichier : la règle `display: flex`
   d'auteur ci-dessus l'emportait sur l'attribut `hidden` (UA stylesheet),
   donc submitWaitlist() qui pose `.tzb-waitlist-form.hidden = true` après un
   envoi réussi n'avait en réalité aucun effet visuel — le formulaire restait
   affiché. C'est aussi ce qui produisait le double bouton "Rejoindre la
   liste d'attente" signalé par Chloé (voir widget.php). */
.tzb-waitlist-form[hidden] { display: none; }
.tzb-waitlist-form input { border: 1px solid var(--tzb-line); border-radius: 4px; padding: 10px 12px; font: inherit; background: var(--tzb-paper); color: var(--tzb-ink); }
.tzb-waitlist-message { font-size: 13px; margin: 4px 0 0; }

/* Quote request form (services sur devis) */
.tzb-quote-intro { font-size: 14px; color: var(--tzb-muted); margin: 0 0 14px; }
/* item (100e vague, retour Chloé) — étiquette du bloc date/heure souhaitées
   facultatif, même traitement visuel que .tzb-quote-intro mais plus proche
   de son champ (margin réduit) puisqu'il n'introduit pas tout le formulaire,
   juste les 2 champs juste en dessous. */
.tzb-quote-pref-label { font-size: 13px; color: var(--tzb-muted); margin: 2px 0 6px; }
/* item (101e vague, retour Chloé) — "doivent prendre en compte le planning
   des prestataires" : .tzb-slot-list/.tzb-slot (voir loadPreferredSlotsForQuote())
   sont déjà stylées plus haut dans ce fichier pour l'étape "Choisissez une
   date" normale — réutilisées telles quelles ici, seul un peu de marge au-
   dessus est nécessaire pour les détacher du champ date juste au-dessus.
   .tzb-quote-pref-empty reprend le même traitement que .tzb-quote-message-
   status (texte d'état discret) mais en neutre plutôt qu'en rouge : l'absence
   de créneau un jour donné n'est pas une erreur, juste une invitation à
   choisir une autre date. */
.tzb-quote-pref-slots { margin: 4px 0 10px; }
.tzb-quote-pref-empty { font-size: 13px; color: var(--tzb-muted); margin: 4px 0 10px; }
/**
 * 129e vague, retour Chloé (suite) — "Dans le panneau de réservation la
 * balise date et heure est trop grande dépasse côté droit" : cet
 * <input type="date"> natif (voir booking-widget.js) ne reposait jusqu'ici
 * que sur la règle générique ".tzb-staff-list input" juste en dessous
 * (width:100%) — insuffisante sur certains navigateurs mobiles (le rendu
 * natif du sélecteur de date de Safari iOS, notamment, peut ignorer
 * width:100% et garder une largeur minimale intrinsèque plus grande que
 * son conteneur, le faisant déborder à droite comme sur la capture de
 * Chloé). max-width:100% le plafonne explicitement quel que soit ce que
 * le navigateur voudrait lui donner comme largeur par défaut ; box-sizing
 * est déjà en border-box via ".tzb-widget *" plus haut dans ce fichier,
 * répété ici en toute sécurité au cas où ce champ serait un jour déplacé
 * hors de ".tzb-widget".
 */
.tzb-quote-preferred-date { width: 100%; max-width: 100%; box-sizing: border-box; }
.tzb-staff-list textarea, .tzb-staff-list input { border: 1px solid var(--tzb-line); padding: 10px 12px; font: inherit; width: 100%; margin-bottom: 10px; }
.tzb-staff-list textarea { min-height: 70px; resize: vertical; }
.tzb-quote-success { font-size: 15px; text-align: center; padding: 20px 0; }
.tzb-quote-message-status { font-size: 13px; color: #B3554A; }

/* First-visit onboarding tip */
.tzb-onboarding-tip {
	display: flex;
	align-items: flex-start;
	gap: 10px;
	background: var(--tzb-sand);
	border-left: 3px solid var(--tzb-accent);
	border-radius: 0 4px 4px 0;
	padding: 12px 14px;
	margin-bottom: 16px;
	font-size: 13px;
}
.tzb-onboarding-tip p { margin: 0; flex: 1; color: var(--tzb-muted); }
.tzb-onboarding-dismiss { background: none; border: none; cursor: pointer; font-size: 16px; color: var(--tzb-muted); line-height: 1; padding: 0; }
