/**
 * Médilocal — séquences animées au scroll.
 *
 * Portage de animated.html. Les tokens sont déclarés sur `.ml-story` et non sur `:root` :
 * le plugin ne doit pas redéfinir --color-text / --color-bg pour tout le site.
 *
 * Le fichier est volontairement autonome (il redéclare les palettes) : le Custom CSS du
 * Kit Elementor, où vivent aujourd'hui ces mêmes valeurs, dépend d'un module de
 * pro-elements sous contrôle de licence et est régénéré à chaque « Régénérer les
 * fichiers ». Cette page ne doit pas en dépendre.
 *
 * Rien n'anime autre chose que `opacity` et `transform` — sauf le flou, cantonné au
 * desktop. Aucun `will-change` : la promotion en couche se fait d'elle-même pendant la
 * transition, et `visibility:hidden` libère la couche au repos.
 */

/* ────────────────────────────────────────────────────────────────────────────────────
   1. Tokens
   ──────────────────────────────────────────────────────────────────────────────────── */

.ml-story {
	/* Palettes — échantillonnées sur le logo, cf. _ds/…/readme.md */
	--blue-50: #EAF2FD;
	--blue-100: #CFE3FB;
	--blue-400: #3D8BEA;
	--blue-500: #0B5FCB;
	--blue-600: #0950AC;
	--blue-700: #073E89;
	--teal-50: #E6FAF7;
	--teal-100: #BFF0E7;
	--teal-500: #00A79A;
	--teal-600: #008C82;
	--teal-700: #036F69;
	--teal-800: #065450;
	--sun-50: #FFEEE9;
	--sun-200: #FFAF8D;
	--sun-500: #FF5433;
	--sun-600: #E8391A;
	--sun-700: #B92C12;
	--red-50: #FDEBE8;
	--red-700: #9E1E0C;
	--amber-50: #FFF6E5;
	--amber-700: #A66A08;
	--slate-0: #FFFFFF;
	--slate-50: #F6F8FB;
	--slate-200: #D7DEE8;
	--slate-300: #B7C1D1;
	--slate-400: #8C9AB0;
	--slate-500: #657189;
	--slate-900: #11141C;

	/* Alias sémantiques */
	--color-bg: var(--slate-0);
	--color-bg-subtle: var(--slate-50);
	--color-bg-tinted: var(--blue-50);
	--color-surface: var(--slate-0);
	--color-border: var(--slate-200);
	--color-border-strong: var(--slate-300);
	--color-text: var(--slate-900);
	--color-text-muted: var(--slate-500);
	--color-text-on-color: var(--slate-0);
	--color-primary: var(--blue-500);
	--color-primary-hover: var(--blue-600);
	--color-primary-active: var(--blue-700);
	--color-primary-tint: var(--blue-50);
	--color-secondary: var(--teal-500);
	--color-secondary-hover: var(--teal-600);
	--color-secondary-active: var(--teal-700);
	--color-secondary-tint: var(--teal-50);
	--color-cta: var(--sun-500);
	--color-cta-hover: var(--sun-600);
	--color-success-strong: var(--teal-700);
	--color-success-bg: var(--teal-50);
	--color-warning-strong: var(--amber-700);
	--color-warning-bg: var(--amber-50);
	--color-error-strong: var(--red-700);
	--color-error-bg: var(--red-50);
	--color-focus-ring: rgba(11, 95, 203, 0.28);

	/* Typographie — les 3 familles sont déjà mises en file par le Kit Elementor,
	   aucun @import ici. */
	--font-display: "Montserrat", sans-serif;
	--font-body: "Nunito Sans", sans-serif;
	--font-accent: "Poppins", sans-serif;
	--text-xs: 0.75rem;
	--text-sm: 0.875rem;
	--text-base: 1rem;
	--text-lg: 1.125rem;
	--text-xl: 1.375rem;
	--text-2xl: 1.75rem;
	--lh-tight: 1.1;
	--lh-snug: 1.3;
	--lh-relaxed: 1.65;
	--fw-semibold: 600;
	--fw-bold: 700;
	--fw-extrabold: 800;
	--fw-black: 900;

	/* Formes et mouvement */
	--radius-sm: 8px;
	--radius-md: 12px;
	--radius-lg: 16px;
	--radius-xl: 24px;
	--radius-pill: 999px;
	--shadow-sm: 0 1px 2px rgba(17, 20, 28, 0.06), 0 1px 1px rgba(17, 20, 28, 0.04);
	--shadow-md: 0 4px 12px rgba(17, 20, 28, 0.08), 0 2px 4px rgba(17, 20, 28, 0.05);
	--shadow-lg: 0 16px 40px rgba(17, 20, 28, 0.14), 0 4px 10px rgba(17, 20, 28, 0.06);
	--shadow-focus: 0 0 0 3px var(--color-focus-ring);
	--ease-standard: cubic-bezier(0.2, 0.8, 0.2, 1);
	--duration-fast: 120ms;
	--duration-base: 200ms;
	--container-max: 1200px;

	/* Hauteur occupée par la barre haute fixe : 16 px de gouttière + 44 px de logo + 16 px.
	   Elle est `position: fixed` en z-index 100, donc elle recouvre les 76 premiers pixels
	   de tout panneau épinglé. Déclarée ici pour que la réservation soit un calcul et non
	   un nombre magique recopié. */
	--ml-topbar-h: 76px;

	/* Paramètres de la séquence — surchargés plus bas selon la largeur et la
	   préférence de mouvement. */
	--ml-beat-shift: 34px;
	--ml-beat-scale: 0.94;
	--ml-beat-dur: 560ms;

	font-family: var(--font-body);
	color: var(--color-text);

	/* La typographie globale du Kit pose `letter-spacing:-0.1px` sur le body, qui hérite
	   partout. La maquette est en `normal`. L'écart paraît négligeable, il ne l'est pas :
	   sur les 20 caractères de « médicament peut vite » il retire 2 px, ce qui fait
	   passer la ligne de 721,9 px à 719,9 px pour 720 px disponibles — assez pour
	   changer le titre de 5 lignes à 4. */
	letter-spacing: normal;
}

/* Les dégradés sont plein cadre : sans ça, une barre de défilement horizontale
   apparaît. `clip` et non `hidden` — `hidden` sur un ancêtre casse position:sticky. */
html,
body {
	overflow-x: clip;
}

/* ────────────────────────────────────────────────────────────────────────────────────
   2. Géométrie du groupe épinglé
   ──────────────────────────────────────────────────────────────────────────────────── */

.ml-group {
	--ml-m: 120; /* vh par étape ; --ml-n vient de l'attribut style inline */
	--ml-band: calc((var(--ml-n) * var(--ml-m) - 100) * 1vh / var(--ml-n));

	position: relative;
	width: 100%;
	height: calc(var(--ml-n) * var(--ml-m) * 1vh);
}

/* Rythme de lecture. Chaque étape tient --ml-m centièmes de viewport de défilement avant de
   basculer. Valeurs relevées d'environ un tiers en juillet 2026 sur retour client (« défiler
   plus longtemps avant que le message change ») :
   - `intro` prend la hausse la plus forte, c'est la séquence qui se termine sur la révélation
     du logo, à laquelle la cliente veut « légèrement plus » de temps ;
   - `benefits` est laissé tel quel, son rythme intérieur a été jugé bon. */
.ml-group[data-ml-group="intro"] { --ml-m: 175; }
.ml-group[data-ml-group="how"] { --ml-m: 165; background: var(--color-bg); }
.ml-group[data-ml-group="benefits"] { --ml-m: 105; background: var(--color-bg-subtle); }
.ml-group[data-ml-group="local"] { --ml-m: 155; background: var(--color-bg-tinted); }

/* Seuil unique de mise en page, celui de la maquette (`innerWidth < 860`).
   Changer --ml-m suffit : les rects des sentinelles bougent, l'IO recalcule seule.
   Aucun listener resize. */
@media (max-width: 859px) {
	.ml-group[data-ml-group="intro"] { --ml-m: 145; }
	.ml-group[data-ml-group="how"] { --ml-m: 135; }
	.ml-group[data-ml-group="benefits"] { --ml-m: 95; }
	.ml-group[data-ml-group="local"] { --ml-m: 130; }
}

/* Bandes de détection. Le +1px comble tout trou sous-pixel entre deux bandes
   (`top` et `top + height` sont arrondis indépendamment) ; le JS déduplique avec max().
   `visibility:hidden` et non `display:none` : l'IO doit continuer à les rapporter. */
.ml-sentinel {
	position: absolute;
	left: 0;
	width: 1px;
	top: calc(var(--ml-i) * var(--ml-band));
	height: calc(var(--ml-band) + 1px);
	visibility: hidden;
	pointer-events: none;
}

/* Les deux bandes extrêmes sont prolongées d'un viewport, pour que TOUTE position de
   scroll où le groupe est visible soit couverte par une bande.
   Sans ça, un saut de scroll (retour en haut de page, restauration de position, ancre)
   vide l'ensemble des bandes intersectantes sans avoir traversé les bandes
   intermédiaires : l'état resterait figé sur la dernière étape vue, et le panneau
   réapparaîtrait sur la mauvaise étape.
   - vers le haut : couvre l'approche du groupe, où la maquette clampe progress à 0.
     Gratuit, le débordement en direction block-start n'est pas défilable.
   - vers le bas : couvre la queue où progress est clampé à 1. La bande finit
     exactement sur le bord bas du groupe ((N−1)/N·(h−vh) + band + vh = h), donc
     n'ajoute aucune hauteur défilable. */
.ml-sentinel--first {
	top: calc(0px - 100vh);
	height: calc(var(--ml-band) + 100vh + 1px);
}

.ml-sentinel--last {
	height: calc(var(--ml-band) + 100vh);
}

.ml-topbar-sentinel {
	position: absolute;
	left: 0;
	top: 0;
	width: 1px;
	height: 60vh;
	visibility: hidden;
	pointer-events: none;
}

/* Panneau visuel. `100dvh` est sans danger ici : sa hauteur n'entre dans aucun calcul,
   contrairement au `window.innerHeight` de la maquette. */
.ml-pane {
	position: sticky;
	top: 0;
	height: 100vh;
	height: 100dvh;
	z-index: 1;
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	padding: clamp(20px, 4vw, 24px);
	padding-bottom: calc(clamp(20px, 4vw, 24px) + env(safe-area-inset-bottom, 0px));
}

.ml-group[data-ml-group="intro"] .ml-pane {
	padding: 0;
	padding-bottom: env(safe-area-inset-bottom, 0px);
	overflow: hidden;
}

.ml-group[data-ml-group="local"] .ml-pane {
	text-align: center;
}

/* Calques de dégradé de l'intro : ils couvrent le *large* viewport, sinon une bande
   blanche du wrapper apparaît sous le panneau `100dvh` quand la barre d'URL se déplie.
   La marge négative annule leur contribution au flux, pour que le panneau démarre bien
   à la position 0 du groupe et soit épinglé dès le premier pixel. */
.ml-bgs {
	position: sticky;
	top: 0;
	height: 100vh;
	height: 100lvh;
	margin-bottom: -100vh;
	margin-bottom: -100lvh;
	z-index: 0;
	overflow: clip;
}

.ml-bg {
	position: absolute;
	inset: 0;
	opacity: 0;
	transition: opacity 650ms ease;
}

.ml-bg[data-ml-state="active"] { opacity: 1; }

.ml-bgs .ml-bg:nth-child(1) {
	background:
		radial-gradient(circle at 22% 18%, rgba(255, 255, 255, 0.18), transparent 55%),
		linear-gradient(135deg, var(--blue-400), var(--blue-600));
}

.ml-bgs .ml-bg:nth-child(2) {
	background:
		radial-gradient(circle at 78% 82%, rgba(255, 84, 51, 0.35), transparent 55%),
		linear-gradient(135deg, var(--blue-600), var(--teal-600));
}

.ml-bgs .ml-bg:nth-child(3) {
	background: linear-gradient(135deg, var(--teal-500), var(--blue-400));
}

.ml-bgs .ml-bg:nth-child(4) {
	background: var(--color-bg);
}

/* ────────────────────────────────────────────────────────────────────────────────────
   3. États des étapes
   ──────────────────────────────────────────────────────────────────────────────────── */

.ml-beats { position: relative; width: 100%; }
.ml-beats--fill { position: absolute; inset: 0; }
.ml-beats--benefit { max-width: 560px; height: 220px; }
.ml-beats--local { max-width: 640px; height: 300px; }

@media (max-width: 859px) {
	.ml-beats--benefit { height: 260px; }
	.ml-beats--local { height: 340px; }
}

.ml-beat {
	position: absolute;
	inset: 0;
	width: 100%;
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	text-align: center;
	opacity: 0;
	visibility: hidden;
	pointer-events: none;
	z-index: 1;
	transform: translateY(var(--ml-beat-shift)) scale(var(--ml-beat-scale));
	transition:
		opacity var(--ml-beat-dur) cubic-bezier(0.22, 0.8, 0.25, 1),
		transform var(--ml-beat-dur) cubic-bezier(0.22, 0.8, 0.25, 1),
		filter var(--ml-beat-dur) ease,
		visibility 0s linear var(--ml-beat-dur);
}

/* `visibility` différée retire les 11 étapes inactives de l'arbre d'accessibilité et de
   l'ordre de tabulation — défaut de la maquette, où les 12 titres étaient annoncés — et
   libère leurs couches de composition. */
.ml-beat[data-ml-state="active"] {
	opacity: 1;
	visibility: visible;
	pointer-events: auto;
	z-index: 2;
	transform: translateY(0) scale(1);
	filter: none;
	transition-delay: 0s;
}

.ml-beat[data-ml-state="before"] {
	transform: translateY(calc(-1 * var(--ml-beat-shift))) scale(var(--ml-beat-scale));
}

.ml-beat[data-ml-state="after"] {
	transform: translateY(var(--ml-beat-shift)) scale(var(--ml-beat-scale));
}

.ml-beat--left { align-items: flex-start; text-align: left; }
.ml-beat-inner { min-width: 0; }
.ml-beat-inner--720 { max-width: 720px; }

/* Gouttières latérales des étapes de l'intro (`pad` dans renderVals()). */
.ml-group[data-ml-group="intro"] .ml-beat:not(.ml-beat--flush) { padding: 0 24px; }

@media (max-width: 859px) {
	.ml-group[data-ml-group="intro"] .ml-beat:not(.ml-beat--flush) { padding: 0 20px; }
}

/* Le flou est le principal coût de rendu de la maquette : il force une rasterisation à
   chaque frame de la transition, sur des blocs plein écran. Réservé au desktop. */
@media (min-width: 1024px) and (prefers-reduced-motion: no-preference) {
	.ml-beat[data-ml-state="before"],
	.ml-beat[data-ml-state="after"] { filter: blur(5px); }
}

/* En dessous, translate et scale compensent la profondeur perdue. */
@media (max-width: 1023px) {
	.ml-story { --ml-beat-shift: 44px; --ml-beat-scale: 0.92; }
}

/* Mockups iPhone : même mécanique, sans notion de direction. */
.ml-phone-stage {
	position: relative;
	width: 320px;
	height: 694px;
	flex-shrink: 0;
}

/* Pas de réduction de la taille LOGIQUE du châssis sur mobile : voir la mise à l'échelle
   dans la section « Comment ça marche ». Le châssis a des cotes en dur calibrées sur 320 px
   — la Dynamic Island fait 126 px, la barre d'état réclame 48 + 126 + 78 = 252 px — donc le
   rétrécir à 230 px tronquait l'heure et la batterie, et forçait à compacter les écrans. */

.ml-phone {
	position: absolute;
	inset: 0;
	opacity: 0;
	visibility: hidden;
	transform: scale(0.95);
	pointer-events: none;
	z-index: 1;
	transition:
		opacity 480ms ease,
		transform 480ms ease,
		visibility 0s linear 480ms;
}

.ml-phone[data-ml-state="active"] {
	opacity: 1;
	visibility: visible;
	transform: scale(1);
	pointer-events: auto;
	z-index: 2;
	transition-delay: 0s;
}

/* ────────────────────────────────────────────────────────────────────────────────────
   4. Barre haute et révélations
   ──────────────────────────────────────────────────────────────────────────────────── */

.ml-topbar {
	position: fixed;
	top: 0;
	left: 0;
	right: 0;
	z-index: 100;
	background: transparent;
	opacity: 0;
	transform: translateY(-16px);
	pointer-events: none;
	transition:
		opacity 300ms var(--ease-standard),
		transform 300ms var(--ease-standard);
}

/* La gouttière est en clamp(), non exprimable dans les contrôles Elementor.
   `nowrap` reproduit la maquette : sous 400 px de large, le logo et le bouton ne tiennent
   plus côte à côte. La maquette laisse le bouton se comprimer et son libellé passer sur
   deux lignes (barre de 88 px) ; les containers Elementor sont en `wrap` par défaut et
   feraient descendre le bouton sous le logo, par-dessus le contenu. */
.e-con.ml-topbar {
	padding: 16px clamp(16px, 4vw, 28px);
	flex-wrap: nowrap;
}

:root[data-ml-past] .ml-topbar {
	opacity: 1;
	transform: none;
	pointer-events: auto;
}

/* La classe est posée sur le widget image Elementor, qui enveloppe le <img>. */
.ml-topbar-logo,
.ml-topbar-logo img {
	height: 44px;
	width: auto;
	display: block;
}

.ml-reveal {
	opacity: 0;
	transform: translateY(20px);
	transition:
		opacity 480ms var(--ease-standard),
		transform 480ms var(--ease-standard);
}

[data-ml-visible="true"] .ml-reveal {
	opacity: 1;
	transform: none;
}

/* Cascade exacte de la maquette (animated.html:241-273 et :310-312). */
.ml-delay-80 { transition-delay: 80ms; }
.ml-delay-180 { transition-delay: 180ms; }
.ml-delay-200 { transition-delay: 200ms; }
.ml-delay-260 { transition-delay: 260ms; }
.ml-delay-320 { transition-delay: 320ms; }
.ml-delay-380 { transition-delay: 380ms; }
.ml-delay-460 { transition-delay: 460ms; }

/* ────────────────────────────────────────────────────────────────────────────────────
   5. Typographie et blocs de contenu
   ──────────────────────────────────────────────────────────────────────────────────── */

.ml-eyebrow {
	font-family: var(--font-display);
	font-weight: var(--fw-extrabold);
	font-size: var(--text-sm);
	letter-spacing: 2px;
	text-transform: uppercase;
	margin-bottom: 20px;
}

/* Un surtitre vidé depuis le panneau Elementor laisse un `<div>` présent dans le DOM : sans
   ceci, ses 20 px de marge basse subsistent et décalent le titre. */
.ml-eyebrow:empty { display: none; }

.ml-eyebrow--sky { color: var(--blue-100); }
.ml-eyebrow--sun { color: var(--sun-200); }
.ml-eyebrow--primary { color: var(--color-primary); }
.ml-eyebrow--secondary { color: var(--color-secondary); }
.ml-eyebrow--mb28 { margin-bottom: 28px; }
.ml-eyebrow--mb32 { margin-bottom: 32px; }

/* Les sélecteurs de titres et de paragraphes sont préfixés par `.ml-story` pour passer
   à 2 classes : le Kit Elementor pose ses typographies globales via `.elementor-kit-6 h1`
   (spécificité 0,1,1), qui battrait une classe seule — il imposerait ses couleurs et,
   plus grave, une taille fixe en px à la place des `clamp()` responsives. */

.ml-story .ml-beat-heading {
	font-family: var(--font-display);
	font-weight: var(--fw-black);
	font-size: clamp(1.75rem, 4vw, 2.25rem);
	line-height: var(--lh-tight);
	margin: 0;
	color: var(--color-text);
	overflow-wrap: anywhere;
	min-width: 0;
	letter-spacing: normal;
}

.ml-story .ml-beat-heading--xl {
	color: #fff;
	font-size: clamp(1.75rem, 5vw, 3rem);
}

.ml-story .ml-intro-h1 {
	font-family: var(--font-display);
	font-weight: var(--fw-black);
	font-size: clamp(2.25rem, 6vw, 3.75rem);
	line-height: var(--lh-tight);
	margin: 0;
	color: #fff;
	overflow-wrap: anywhere;
	min-width: 0;
	letter-spacing: normal;
}

.ml-story .ml-intro-lede {
	font-size: clamp(1rem, 2vw, 1.125rem);
	color: rgba(255, 255, 255, 0.88);
	line-height: var(--lh-relaxed);
	max-width: 560px;
	margin: 24px auto 0;
}

.ml-pill-row {
	display: flex;
	gap: 10px;
	flex-wrap: wrap;
	justify-content: center;
	margin-top: 28px;
}

.ml-pill {
	display: inline-flex;
	align-items: center;
	padding: 6px 14px;
	border-radius: var(--radius-pill);
	color: #fff;
	font-family: var(--font-display);
	font-weight: var(--fw-bold);
	font-size: var(--text-xs);
	letter-spacing: 1px;
}

.ml-pill--sun { background: var(--sun-500); }
.ml-pill--ghost { background: rgba(255, 255, 255, 0.22); }

.ml-emph {
	font-size: clamp(1.125rem, 2.5vw, 1.375rem);
	color: #fff;
	font-weight: var(--fw-bold);
	max-width: 600px;
	margin: 28px auto 0;
	line-height: var(--lh-snug);
}

.ml-accent-line {
	font-family: var(--font-accent);
	font-style: italic;
	font-weight: var(--fw-bold);
	font-size: clamp(1.75rem, 4vw, 3rem);
	color: var(--blue-100);
	line-height: var(--lh-snug);
}

.ml-accent-strong {
	font-family: var(--font-display);
	font-weight: var(--fw-black);
	font-size: clamp(2.25rem, 5vw, 3.75rem);
	color: #fff;
	margin-top: 12px;
}

.ml-brand-logo {
	width: min(340px, 60vw);
	height: auto;
	display: block;
	margin: 0 auto;
}

/* La marge basse de 1em reproduit celle que le navigateur applique au <p> de la
   maquette, dont seule la marge haute était fixée en inline. */
.ml-story .ml-brand-claim {
	font-family: var(--font-display);
	font-weight: var(--fw-extrabold);
	font-size: clamp(1.375rem, 3vw, 1.75rem);
	color: var(--color-text);
	margin: 28px 0 1em;
	max-width: 560px;
	letter-spacing: normal;
}

.ml-pane-head {
	text-align: center;
	margin-bottom: clamp(32px, 5vw, 56px);
}

.ml-icon-circle {
	width: 72px;
	height: 72px;
	border-radius: 50%;
	display: flex;
	align-items: center;
	justify-content: center;
	margin: 0 auto 20px;
}

.ml-icon-circle--tint { background: var(--color-primary-tint); color: var(--color-primary); }
.ml-icon-circle--solid { background: var(--color-primary); color: #fff; }

.ml-icon-circle-sm {
	width: 48px;
	height: 48px;
	border-radius: 50%;
	display: flex;
	align-items: center;
	justify-content: center;
	margin-bottom: 16px;
	flex-shrink: 0;
	background: var(--teal-800);
	color: var(--teal-100);
}

.ml-story .ml-benefit-title {
	font-family: var(--font-display);
	font-weight: var(--fw-extrabold);
	font-size: var(--text-2xl);
	color: var(--color-text);
	margin: 0 0 10px;
	letter-spacing: normal;
}

.ml-story .ml-benefit-desc {
	font-size: var(--text-lg);
	color: var(--color-text-muted);
	line-height: var(--lh-relaxed);
	margin: 0 auto;
	max-width: 440px;
}

.ml-status-pill {
	display: inline-flex;
	align-items: center;
	gap: 6px;
	margin-top: 10px;
	padding: 6px 14px;
	border-radius: var(--radius-pill);
	background: var(--color-success-bg);
	color: var(--color-success-strong);
	font-family: var(--font-display);
	font-weight: var(--fw-bold);
	font-size: var(--text-xs);
}

.ml-territory-row {
	display: flex;
	flex-wrap: wrap;
	gap: 12px;
	justify-content: center;
	margin-bottom: 40px;
}

.ml-territory {
	display: inline-flex;
	align-items: center;
	gap: 8px;
	padding: 8px 16px;
	border-radius: var(--radius-pill);
	background: var(--color-surface);
	border: 1px solid var(--color-border);
	color: var(--color-text-muted);
}

.ml-territory-name { font-size: var(--text-sm); font-weight: var(--fw-semibold); }
.ml-territory-soon { font-size: var(--text-xs); font-weight: var(--fw-bold); color: var(--color-warning-strong); }

.ml-local-card {
	padding: 32px 24px;
	background: var(--color-surface);
	border-radius: var(--radius-xl);
	box-shadow: var(--shadow-md);
	max-width: 320px;
	margin: 0 auto;
}

.ml-story .ml-local-name {
	font-family: var(--font-display);
	font-weight: var(--fw-black);
	font-size: var(--text-2xl);
	color: var(--color-text);
	letter-spacing: normal;
}

.ml-cta-label {
	font-family: var(--font-display);
	font-weight: var(--fw-bold);
	font-size: var(--text-xs);
	letter-spacing: 1.5px;
	color: var(--slate-400);
	text-transform: uppercase;
}

.ml-scroll-hint {
	display: flex;
	align-items: center;
	gap: 8px;
	margin-top: 56px;
	justify-content: center;
	color: rgba(255, 255, 255, 0.75);
	font-size: var(--text-sm);
	font-weight: var(--fw-semibold);
	animation: medilocalScrollHint 2.2s ease-in-out infinite;
}

@keyframes medilocalScrollHint {
	0%, 100% { transform: translateY(0); opacity: 0.55; }
	50% { transform: translateY(7px); opacity: 1; }
}

/* ────────────────────────────────────────────────────────────────────────────────────
   6. Comment ça marche — colonnes
   ──────────────────────────────────────────────────────────────────────────────────── */

.ml-how-row {
	display: flex;
	flex-direction: row;
	gap: 48px;
	align-items: center;
	justify-content: center;
	width: 100%;
	max-width: var(--container-max);
}

.ml-how-steps-col { width: 400px; height: 170px; }

/* ── Mise à l'échelle du châssis ─────────────────────────────────────────────────────
   Le panneau fait 100 dvh et centre son contenu. Celui de `how` est le plus haut des
   quatre séquences et il est FIXE : gouttières 48 + en-tête 108 + marge 56 + châssis 694
   ≈ 906 px. Passé sous cette hauteur de fenêtre, le débordement se répartit de part et
   d'autre du centre et le surtitre puis le titre sortent par le haut — invisibles, alors
   que ce sont eux qui nomment la section.

   Le châssis est donc mis à l'échelle, pas redimensionné : sa mise en page interne reste
   calculée sur 320×694. C'est ce qui permet de ne rien compacter ni masquer — les cinq
   résultats, la carte, l'heure et les icônes de la barre d'état restent entiers, alors
   qu'un châssis réellement réduit les tronquait (cotes en dur : île de 126 px, barre
   d'état de 252 px). Procédé de la maquette statique, qui fait déjà
   `transform: scale(0.82)` (index.html:74).

   L'échelle est en paliers parce qu'elle est INCALCULABLE en CSS : il faudrait diviser une
   longueur (100dvh) par une longueur pour obtenir un nombre sans unité, ce que `calc()`
   interdit. L'autre voie serait un listener JS, mais ce plugin ne lit jamais le layout et
   n'écoute ni `scroll` ni `resize` — on ne casse pas ce contrat pour un facteur d'échelle. */
.ml-how-phone-col {
	--ml-stage-scale: 1;

	width: calc(320px * var(--ml-stage-scale));
	height: calc(694px * var(--ml-stage-scale));
	display: block;
}

.ml-how-phone-col .ml-phone-stage {
	transform: scale(var(--ml-stage-scale));
	transform-origin: top left;
}

/* Paliers desktop. Le contenu fixe hors châssis mesure 190 px : gouttières du panneau 48
   + en-tête 86 + marge 56 — mesuré dans le navigateur à 1440×900, pas déduit, l'en-tête
   dépendant du `clamp()` du titre. Sur toute la plage desktop le titre tient sur une ligne
   (647 px de large au plus), l'en-tête y garde donc sa hauteur.

   Chaque palier est calé sur le PIRE cas de son intervalle, pas sur sa borne haute : le
   palier `max-height: X` reste en vigueur jusqu'à X − 39, d'où `s = (X - 39 - 190) / 694`.
   Au-delà de 900 px de haut, l'échelle 1 tient d'elle-même (190 + 694 = 884). */
@media (min-width: 860px) and (max-height: 900px) {
	.ml-how-phone-col { --ml-stage-scale: 0.96; } /* au pire 861 px de haut → 666 px rendus pour 671 dispo */
}

@media (min-width: 860px) and (max-height: 860px) {
	.ml-how-phone-col { --ml-stage-scale: 0.90; } /* au pire 821 px de haut → 625 px rendus pour 631 dispo */
}

@media (min-width: 860px) and (max-height: 820px) {
	.ml-how-phone-col { --ml-stage-scale: 0.85; } /* au pire 781 px de haut → 590 px rendus pour 591 dispo */
}

@media (min-width: 860px) and (max-height: 780px) {
	.ml-how-phone-col { --ml-stage-scale: 0.79; } /* au pire 741 px de haut → 548 px rendus pour 551 dispo */
}

@media (min-width: 860px) and (max-height: 740px) {
	.ml-how-phone-col { --ml-stage-scale: 0.73; } /* au pire 701 px de haut → 507 px rendus pour 511 dispo */
}

@media (min-width: 860px) and (max-height: 700px) {
	.ml-how-phone-col { --ml-stage-scale: 0.67; } /* au pire 661 px de haut → 465 px rendus pour 471 dispo */
}

@media (min-width: 860px) and (max-height: 660px) {
	.ml-how-phone-col { --ml-stage-scale: 0.62; } /* au pire 621 px de haut → 430 px rendus pour 431 dispo */
}

@media (min-width: 860px) and (max-height: 620px) {
	.ml-how-phone-col { --ml-stage-scale: 0.56; } /* au pire 581 px de haut → 389 px rendus pour 391 dispo */
}

/* Garde-fou : si une hauteur tombe malgré tout entre deux paliers, `safe` fait dégénérer
   le centrage en `flex-start` au lieu de déborder des deux côtés. C'est alors le bas du
   châssis qui est rogné, jamais le titre. La déclaration simple reste pour les moteurs qui
   ignorent `safe`. */
.ml-group[data-ml-group="how"] .ml-pane {
	justify-content: center;
	justify-content: safe center;
}

/* ── Mobile : faire tenir la séquence sous la barre haute ────────────────────────────
   Le panneau fait 100 dvh avec son contenu centré, et la barre haute vient se poser
   par-dessus ses 76 premiers pixels. `how` est le seul groupe qui en souffre : son
   contenu mesure 876 px FIXES (en-tête 108 + marge 32 + téléphone 498 + gouttière 48 +
   colonne d'étapes 190), pour 684 px disponibles sur un 360×800. Le surtitre finissait
   38 px au-dessus du bord haut et le titre passait sous le logo.
   `intro`, `benefits` et `local` sont mesurés à 188 px et plus du haut : ils gardent leur
   cadrage, réserver la barre chez eux ne ferait que descendre inutilement un rendu validé.

   Réserver seule ne suffit pas — elle aggraverait le débordement en bas. On retaille donc
   aussi les trois blocs fixes, puis on met le châssis à l'échelle. */
@media (max-width: 859px) {
	.ml-how-row { flex-direction: column; gap: 20px; }
	.ml-how-steps-col { width: 100%; height: 168px; }

	.ml-group[data-ml-group="how"] .ml-pane {
		padding-top: calc(clamp(20px, 4vw, 24px) + var(--ml-topbar-h));
	}

	.ml-group[data-ml-group="how"] .ml-pane-head { margin-bottom: 20px; }

	/* Paliers mobiles, calés sur `(hauteur - 76 - 356) / 694`, où 356 = gouttières du
	   panneau 40 + en-tête 108 + marge 20 + gouttière de rangée 20 + étapes 168. La
	   mécanique d'échelle elle-même est déclarée plus haut, commune aux deux mises en page. */
	.ml-how-phone-col {
		--ml-stage-scale: 0.72; /* ≥ 900 px de haut → 500 px rendus */

		margin: 0 auto; /* la rangée est passée en colonne : centrage horizontal */
	}
}

@media (max-width: 859px) and (max-height: 900px) {
	.ml-how-phone-col { --ml-stage-scale: 0.60; } /* 852 px de haut → 416 pour 420 dispo */
}

@media (max-width: 859px) and (max-height: 820px) {
	.ml-how-phone-col { --ml-stage-scale: 0.53; } /* 800 px de haut → 368 pour 368 dispo */
}

@media (max-width: 859px) and (max-height: 760px) {
	.ml-how-phone-col { --ml-stage-scale: 0.41; } /* 720 px de haut → 285 pour 288 dispo */
}

.ml-step-row { display: flex; align-items: center; gap: 16px; margin-bottom: 12px; }

.ml-step-badge {
	width: 36px;
	height: 36px;
	border-radius: 50%;
	display: flex;
	align-items: center;
	justify-content: center;
	font-family: var(--font-display);
	font-weight: var(--fw-extrabold);
	font-size: var(--text-base);
	flex-shrink: 0;
	background: var(--color-primary);
	color: #fff;
}

/* Les 3 étapes se relaient au même emplacement en fondu : une seule pastille est visible à la
   fois, le dégradé bleu → vert demandé est donc temporel. Une seule rampe déclarée, étirée à
   300 % et échantillonnée par tiers, pour que la couleur reste continue de 1 à 3 (bleu →
   bleu-vert → vert) plutôt que trois teintes choisies à la main. */
.ml-how-steps-col .ml-beat .ml-step-badge {
	background-image: linear-gradient(135deg, var(--blue-500) 0%, var(--teal-500) 100%);
	background-size: 300% 100%;
}

.ml-how-steps-col .ml-beat:nth-child(1) .ml-step-badge { background-position: 0% 0; }
.ml-how-steps-col .ml-beat:nth-child(2) .ml-step-badge { background-position: 50% 0; }
.ml-how-steps-col .ml-beat:nth-child(3) .ml-step-badge { background-position: 100% 0; }

.ml-story .ml-step-title {
	font-family: var(--font-display);
	font-weight: var(--fw-extrabold);
	font-size: var(--text-xl);
	margin: 0;
	color: var(--color-text);
	letter-spacing: normal;
}

.ml-story .ml-step-desc {
	font-size: var(--text-base);
	color: var(--color-text-muted);
	line-height: var(--lh-relaxed);
	margin: 0;
	max-width: 420px;
}

/* ────────────────────────────────────────────────────────────────────────────────────
   7. Composants du design system
   ──────────────────────────────────────────────────────────────────────────────────── */

.ml-btn {
	font-family: var(--font-display);
	font-weight: var(--fw-bold);
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: 8px;
	text-decoration: none;
	cursor: pointer;
	transition:
		background var(--duration-base) var(--ease-standard),
		transform var(--duration-fast) var(--ease-standard),
		box-shadow var(--duration-base) var(--ease-standard);
}

.ml-btn--sm { padding: 8px 16px; font-size: var(--text-sm); border-radius: var(--radius-md); }
.ml-btn--md { padding: 12px 22px; font-size: var(--text-base); border-radius: var(--radius-md); }
.ml-btn--lg { padding: 16px 28px; font-size: var(--text-lg); border-radius: var(--radius-lg); }
.ml-btn--full { width: 100%; }

.ml-btn--primary {
	background: var(--color-primary);
	color: var(--color-text-on-color);
	border: 2px solid var(--color-primary);
}

.ml-btn--secondary {
	background: var(--color-surface);
	color: var(--color-secondary-active);
	border: 2px solid var(--color-secondary);
}

.ml-btn--cta {
	background: var(--color-cta);
	color: var(--color-text-on-color);
	border: 2px solid var(--color-cta);
}

.ml-btn--primary:hover { background: var(--color-primary-hover); box-shadow: var(--shadow-sm); }
.ml-btn--secondary:hover { background: var(--color-secondary-tint); box-shadow: var(--shadow-sm); }
.ml-btn--cta:hover { background: var(--color-cta-hover); box-shadow: var(--shadow-sm); }
.ml-btn:active { transform: scale(0.97); }

/* La maquette utilise :focus ; :focus-visible évite l'anneau au clic à la souris. */
.ml-btn:focus-visible { box-shadow: var(--shadow-focus); outline: none; }

.ml-badge {
	display: inline-flex;
	align-items: center;
	gap: 6px;
	border-radius: var(--radius-pill);
	font-family: var(--font-display);
	font-weight: var(--fw-bold);
	line-height: 1;
	white-space: nowrap;
}

.ml-badge--sm { padding: 4px 10px; font-size: var(--text-xs); }
.ml-badge--md { padding: 6px 14px; font-size: var(--text-sm); }
.ml-badge--in-stock { background: var(--color-success-bg); color: var(--color-success-strong); }
.ml-badge--out-of-stock { background: var(--color-error-bg); color: var(--color-error-strong); }
.ml-badge--on-order { background: var(--color-warning-bg); color: var(--color-warning-strong); }

/* ────────────────────────────────────────────────────────────────────────────────────
   8. Châssis iPhone (ios-frame.jsx)
   ──────────────────────────────────────────────────────────────────────────────────── */

.ml-ios {
	width: 100%;
	height: 100%;
	border-radius: 48px;
	overflow: hidden;
	position: relative;
	background: #F2F2F7;
	box-shadow: 0 40px 80px rgba(0, 0, 0, 0.18), 0 0 0 1px rgba(0, 0, 0, 0.12);
	font-family: -apple-system, system-ui, sans-serif;
	-webkit-font-smoothing: antialiased;
}

.ml-ios-island {
	position: absolute;
	top: 11px;
	left: 50%;
	transform: translateX(-50%);
	width: 126px;
	height: 37px;
	border-radius: 24px;
	background: #000;
	z-index: 50;
}

.ml-ios-sb {
	position: absolute;
	top: 0;
	left: 0;
	right: 0;
	z-index: 10;
	display: flex;
	gap: 154px;
	align-items: center;
	justify-content: center;
	padding: 21px 24px 19px;
	box-sizing: border-box;
	width: 100%;
	color: #000;
}

/* Le `gap: 154px` ci-dessus n'est valable qu'à 320 px de large : 48 (heure) + 126 (île) + 78
   (icônes) = 252 px de contenu incompressible. C'est la raison pour laquelle le châssis n'est
   plus réduit à 230 px sur mobile mais mis à l'échelle — voir `.ml-how-phone-col`. */

.ml-ios-sb-time,
.ml-ios-sb-icons {
	flex: 1;
	height: 22px;
	display: flex;
	align-items: center;
	justify-content: center;
}

.ml-ios-sb-time {
	font-family: -apple-system, "SF Pro", system-ui;
	font-weight: 590;
	font-size: 17px;
	line-height: 22px;
	padding-top: 1.5px;
}

.ml-ios-sb-icons { gap: 7px; padding-top: 1px; padding-right: 1px; }

.ml-ios-stack { height: 100%; display: flex; flex-direction: column; }

.ml-ios-nav {
	display: flex;
	flex-direction: column;
	gap: 10px;
	padding-top: 62px;
	padding-bottom: 10px;
	position: relative;
	z-index: 5;
}

.ml-ios-nav-row {
	display: flex;
	align-items: center;
	justify-content: space-between;
	padding: 0 16px;
}

.ml-ios-pill {
	height: 44px;
	min-width: 44px;
	border-radius: 9999px;
	position: relative;
	overflow: hidden;
	display: flex;
	align-items: center;
	justify-content: center;
	box-shadow: 0 1px 3px rgba(0, 0, 0, 0.07), 0 3px 10px rgba(0, 0, 0, 0.06);
}

.ml-ios-pill-glass {
	position: absolute;
	inset: 0;
	border-radius: 9999px;
	-webkit-backdrop-filter: blur(12px) saturate(180%);
	backdrop-filter: blur(12px) saturate(180%);
	background: rgba(255, 255, 255, 0.5);
}

.ml-ios-pill-shine {
	position: absolute;
	inset: 0;
	border-radius: 9999px;
	box-shadow:
		inset 1.5px 1.5px 1px rgba(255, 255, 255, 0.7),
		inset -1px -1px 1px rgba(255, 255, 255, 0.4);
	border: 0.5px solid rgba(0, 0, 0, 0.06);
}

.ml-ios-pill-body {
	position: relative;
	z-index: 1;
	display: flex;
	align-items: center;
	justify-content: center;
	padding: 0 4px;
	width: 36px;
	height: 36px;
}

.ml-ios-title {
	padding: 0 16px;
	font-family: -apple-system, system-ui;
	font-size: 34px;
	font-weight: 700;
	line-height: 41px;
	color: #000;
	letter-spacing: 0.4px;
}

.ml-ios-body { flex: 1; overflow: auto; }

.ml-ios-home {
	position: absolute;
	bottom: 0;
	left: 0;
	right: 0;
	z-index: 60;
	height: 34px;
	display: flex;
	justify-content: center;
	align-items: flex-end;
	padding-bottom: 8px;
	pointer-events: none;
}

.ml-ios-home > span {
	width: 139px;
	height: 5px;
	border-radius: 100px;
	background: rgba(0, 0, 0, 0.25);
}

/* ────────────────────────────────────────────────────────────────────────────────────
   8bis. Écrans de l'app (aperçus de `apercus/`)
   ──────────────────────────────────────────────────────────────────────────────────── */

/* Les trois écrans sont dessinés en 390 px de large, la largeur des aperçus ; le châssis
   en fait 320. Plutôt que de recalculer une à une les cotes des aperçus — un travail à
   refaire à chaque nouvelle livraison de maquette — le calque est mis à l'échelle :
   320/390 = 0,8205, et les hauteurs suivent (694/0,8205 = 845,8 px, soit les 844 px de
   l'aperçu à 2 px près, absorbés par les zones `flex`).
   Même procédé que la mise à l'échelle du châssis en mobile (§ 6), et que le
   `transform: scale(0.82)` de la maquette statique (index.html:74).

   Écart avec le § 8 : les écrans ne prennent PAS la police système du châssis, ils
   gardent Montserrat / Nunito Sans comme les aperçus. C'est l'app Médilocal qui est
   montrée, pas une app iOS générique. */
.ml-app {
	--ml-app-scale: 0.8205;

	position: absolute;
	top: 0;
	left: 0;
	width: calc(320px / var(--ml-app-scale));
	height: calc(694px / var(--ml-app-scale));
	transform: scale(var(--ml-app-scale));
	transform-origin: top left;
	box-sizing: border-box;
	display: flex;
	flex-direction: column;
	background: var(--color-bg);
	font-family: var(--font-body);
	color: var(--color-text);

	/* Réserves du châssis, exprimées dans le repère 390 : la barre d'état occupe 62 px en
	   repère 320 (62/0,8205 ≈ 76), l'indicateur d'accueil 34 px (≈ 41). L'en-tête des
	   aperçus apporte ses propres 18 px de gouttière haute, d'où 76 − 18 = 58. */
	padding-top: 58px;
	padding-bottom: 20px;
}

/* L'écran d'itinéraire est une carte plein cadre : ses trois calques (carte, en-tête
   flottant, feuille) se superposent au lieu de s'empiler. La carte passe SOUS la barre
   d'état, comme dans l'aperçu — la réserve haute ne vaut plus que pour l'en-tête. */
.ml-app--map { padding-top: 0; padding-bottom: 0; }
.ml-app--map .ml-app-head { padding-top: 76px; }

/* ── En-tête : retour, options, et pour l'itinéraire une pilule de titre ────────────── */
.ml-app-head {
	flex-shrink: 0;
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 10px;
	padding: 18px 18px 6px;
	background: var(--color-bg);
	z-index: 5;
}

.ml-app-head--float {
	position: absolute;
	top: 0;
	left: 0;
	right: 0;
	padding: 18px;
	background: none;
}

.ml-app-round {
	width: 40px;
	height: 40px;
	border-radius: 50%;
	background: var(--color-bg-subtle);
	color: var(--color-text);
	display: flex;
	align-items: center;
	justify-content: center;
	flex-shrink: 0;
}

.ml-app-round--surface { background: var(--color-surface); box-shadow: var(--shadow-sm); }

/* La pastille de retour est une chevron-right retournée : le bundle des aperçus n'expose
   pas de ChevronLeft, il fait exactement la même rotation. */
.ml-app-round--back svg { transform: rotate(180deg); }

.ml-app-titlepill {
	flex: 1;
	min-width: 0;
	height: 40px;
	background: var(--color-surface);
	border-radius: var(--radius-pill);
	box-shadow: var(--shadow-sm);
	display: flex;
	align-items: center;
	justify-content: center;
	padding: 0 16px;
	font-family: var(--font-display);
	font-weight: var(--fw-extrabold);
	font-size: var(--text-base);
	color: var(--color-text);
	white-space: nowrap;
	overflow: hidden;
	text-overflow: ellipsis;
}

/* ── Corps ──────────────────────────────────────────────────────────────────────────── */
.ml-app-body {
	flex: 1;
	min-height: 0;
	padding: 8px 20px 16px;
	display: flex;
	flex-direction: column;
	gap: 16px;
	overflow: hidden;
}

.ml-app-searchrow { display: flex; align-items: center; gap: 10px; flex-shrink: 0; }

/* Le logo est servi par la médiathèque (taille `medium`) et non par le PNG des aperçus,
   qui pèse 883 Ko pour un rendu de 26 px de haut.
   Sélecteur en deux classes : `.elementor img { height: auto }` du Kit fait 0,1,1 et
   gagnerait sinon, le logo écrasant alors la barre de recherche. */
.ml-story .ml-app-logo {
	height: 26px;
	width: auto;
	max-width: none;
	flex-shrink: 0;
}

.ml-app-field {
	display: flex;
	align-items: center;
	gap: 6px;
	flex: 1;
	min-width: 0;
	height: 44px;
	box-sizing: border-box;
	background: var(--color-surface);
	border: 2px solid var(--color-border);
	border-radius: var(--radius-pill);
	padding: 0 6px 0 18px;
	box-shadow: var(--shadow-sm);
}

.ml-app-field-value {
	flex: 1;
	min-width: 0;
	font-size: var(--text-base);
	font-weight: var(--fw-semibold);
	color: var(--color-text);
	white-space: nowrap;
	overflow: hidden;
	text-overflow: ellipsis;
}

.ml-app-field-icon,
.ml-app-field-clear {
	display: flex;
	flex-shrink: 0;
	color: var(--color-text-muted);
}

.ml-app-field-clear { padding: 6px; }
.ml-app-field-icon { padding-right: 2px; }

.ml-app-field-go {
	flex-shrink: 0;
	width: 36px;
	height: 36px;
	border-radius: 50%;
	background: var(--color-primary);
	color: var(--color-text-on-color);
	display: flex;
	align-items: center;
	justify-content: center;
}

.ml-app-field-edit {
	flex-shrink: 0;
	width: 32px;
	height: 32px;
	border-radius: 50%;
	background: var(--color-bg-subtle);
	color: var(--color-primary);
	display: flex;
	align-items: center;
	justify-content: center;
}

/* ── Filtres ────────────────────────────────────────────────────────────────────────── */
/* L'aperçu défile horizontalement (`overflow-x: auto`), ce qui y laisse une barre de
   défilement visible sous les chips. Dans un mockup inerte elle n'a pas de sens : les
   chips sont coupés net au bord de l'écran, comme à l'ouverture de l'aperçu. */
.ml-app-chips {
	display: flex;
	gap: 8px;
	flex-shrink: 0;
	margin-top: -8px;
	overflow: hidden;
}

.ml-chip {
	display: inline-flex;
	align-items: center;
	gap: 6px;
	padding: 8px 16px;
	border-radius: var(--radius-pill);
	border: 2px solid var(--color-border);
	background: var(--color-surface);
	color: var(--color-text);
	font-weight: var(--fw-bold);
	font-size: var(--text-sm);
	white-space: nowrap;
}

.ml-chip--active {
	border-color: var(--color-primary);
	background: var(--color-primary-tint);
	color: var(--color-primary-active);
}

.ml-app-geo {
	display: flex;
	align-items: center;
	gap: 8px;
	flex-shrink: 0;
	margin-top: -8px;
	font-size: var(--text-sm);
	font-weight: var(--fw-bold);
	color: var(--color-text-muted);
}

.ml-app-geo svg { color: var(--color-secondary); flex-shrink: 0; }

/* ── Carte ──────────────────────────────────────────────────────────────────────────── */
.ml-app-mapblock {
	margin-top: 4px;
	flex: 1;
	min-height: 220px;
	display: flex;
	flex-direction: column;
}

.ml-app-maplabel {
	flex-shrink: 0;
	font-family: var(--font-display);
	font-weight: var(--fw-extrabold);
	font-size: var(--text-sm);
	color: var(--color-text-muted);
	text-transform: uppercase;
	letter-spacing: 0.03em;
	margin-bottom: 10px;
}

.ml-app-map {
	position: relative;
	flex: 1;
	min-height: 0;
	border-radius: var(--radius-lg);
	overflow: hidden;
	border: 1px solid var(--color-border);
	background: linear-gradient(135deg, var(--color-bg-tinted) 0%, var(--color-secondary-tint) 100%);
}

/* Plein cadre sous la barre d'état pour l'écran d'itinéraire : ni bord, ni arrondi. */
.ml-app-map--full {
	position: absolute;
	inset: 0;
	flex: none;
	border: 0;
	border-radius: 0;
}

/* Les rues : deux trames croisées, pas une tuile ni une image — donc aucun appel réseau,
   et un rendu net à n'importe quelle échelle. */
.ml-app-map-grid {
	position: absolute;
	inset: 0;
	background-image:
		repeating-linear-gradient(58deg, transparent 0 46px, rgba(255, 255, 255, 0.55) 46px 49px),
		repeating-linear-gradient(-32deg, transparent 0 70px, rgba(255, 255, 255, 0.4) 70px 72px);
}

.ml-app-pin,
.ml-app-marker,
.ml-app-me,
.ml-app-marker-pulse {
	position: absolute;
	transform: translate(-50%, -50%);
}

.ml-app-pin {
	width: 34px;
	height: 34px;
	border-radius: 50%;
	background: var(--color-primary);
	color: var(--color-text-on-color);
	display: flex;
	align-items: center;
	justify-content: center;
	box-shadow: var(--shadow-md);
}

.ml-app-pin--secondary { background: var(--color-secondary); }

.ml-app-me {
	width: 16px;
	height: 16px;
	border-radius: 50%;
	background: var(--color-cta);
	border: 3px solid var(--color-bg);
	box-shadow: 0 0 0 6px rgba(255, 84, 51, 0.22);
}

.ml-app-marker {
	width: 56px;
	height: 56px;
	border-radius: 50%;
	background: var(--color-primary);
	color: var(--color-text-on-color);
	display: flex;
	align-items: center;
	justify-content: center;
	border: 3px solid var(--color-bg);
	box-shadow: var(--shadow-lg);
	transform: translate(-50%, -100%);
}

.ml-app-marker-pulse {
	width: 16px;
	height: 16px;
	border-radius: 50%;
	background: var(--color-primary);
	animation: ml-app-pulse 2.2s ease-out infinite;
}

/* `medilocal-pulse` des aperçus, renommée au préfixe du plugin. Le translate est répété
   dans les deux images-clés : une animation de `transform` écrase le translate de
   positionnement. */
@keyframes ml-app-pulse {
	0% { transform: translate(-50%, -50%) scale(0.6); opacity: 0.55; }
	100% { transform: translate(-50%, -50%) scale(2.6); opacity: 0; }
}

.ml-app-zoom {
	position: absolute;
	right: 14px;
	top: 120px;
	display: flex;
	flex-direction: column;
	border-radius: var(--radius-md);
	overflow: hidden;
	box-shadow: var(--shadow-sm);
}

.ml-app-zoom-btn {
	width: 40px;
	height: 40px;
	background: var(--color-surface);
	color: var(--color-text);
	display: flex;
	align-items: center;
	justify-content: center;
}

.ml-app-zoom-btn:first-child { border-bottom: 1px solid var(--color-border); }

.ml-app-locate {
	position: absolute;
	right: 14px;
	bottom: 14px;
	width: 40px;
	height: 40px;
	border-radius: 50%;
	background: var(--color-surface);
	color: var(--color-primary);
	display: flex;
	align-items: center;
	justify-content: center;
	box-shadow: var(--shadow-sm);
}

/* Sur l'itinéraire, la pastille remonte au-dessus de la feuille basse. */
.ml-app--map .ml-app-locate { bottom: 264px; }

/* ── Résultats ──────────────────────────────────────────────────────────────────────── */
.ml-app-results-head {
	display: flex;
	flex-direction: column;
	gap: 4px;
	flex-shrink: 0;
}

.ml-app-eyebrow {
	font-family: var(--font-display);
	font-weight: var(--fw-extrabold);
	font-size: var(--text-xs);
	color: var(--color-text-muted);
	text-transform: uppercase;
	letter-spacing: 0.06em;
}

.ml-app-results-row {
	display: flex;
	align-items: baseline;
	justify-content: space-between;
	gap: 8px;
}

.ml-app-results-title {
	font-family: var(--font-display);
	font-weight: var(--fw-extrabold);
	font-size: var(--text-lg);
	color: var(--color-text);
}

.ml-app-count {
	flex-shrink: 0;
	font-size: var(--text-sm);
	font-weight: var(--fw-bold);
	color: var(--color-text-muted);
}

.ml-app-cards { display: flex; flex-direction: column; gap: 10px; }

.ml-app-card {
	display: flex;
	align-items: center;
	gap: 12px;
	padding: 14px;
	background: var(--color-surface);
	border: 1px solid var(--color-border);
	border-radius: var(--radius-lg);
	box-shadow: var(--shadow-sm);
	flex-shrink: 0;
}

.ml-app-card-icon {
	flex-shrink: 0;
	width: 40px;
	height: 40px;
	border-radius: var(--radius-md);
	background: var(--color-bg-tinted);
	color: var(--color-secondary);
	display: flex;
	align-items: center;
	justify-content: center;
}

.ml-app-card-main {
	flex: 1;
	min-width: 0;
	display: flex;
	flex-direction: column;
	gap: 3px;
}

.ml-app-card-name {
	font-family: var(--font-display);
	font-weight: var(--fw-bold);
	font-size: var(--text-base);
	color: var(--color-text);
	line-height: 1.2;
}

.ml-app-card-meta {
	font-size: var(--text-sm);
	color: var(--color-text-muted);
	white-space: nowrap;
	overflow: hidden;
	text-overflow: ellipsis;
}

/* Les deux variantes hautes : le badge passe en haut à droite du nom, la ligne
   « distance · adresse » gagne une épingle. */
.ml-app-card--featured,
.ml-app-card--sheet {
	align-items: flex-start;
	gap: 14px;
	padding: 16px;
}

.ml-app-card--featured .ml-app-card-icon,
.ml-app-card--sheet .ml-app-card-icon {
	background: var(--color-primary-tint);
	color: var(--color-primary);
}

.ml-app-card--featured .ml-app-card-icon { width: 64px; height: 64px; }
.ml-app-card--sheet .ml-app-card-icon { width: 52px; height: 52px; }

.ml-app-card--featured .ml-app-card-main,
.ml-app-card--sheet .ml-app-card-main { gap: 6px; }

.ml-app-card--featured .ml-app-card-name,
.ml-app-card--sheet .ml-app-card-name {
	font-weight: var(--fw-extrabold);
	font-size: var(--text-lg);
	line-height: 1.15;
}

.ml-app-card-top {
	display: flex;
	align-items: flex-start;
	justify-content: space-between;
	gap: 10px;
}

.ml-app-card--featured .ml-app-card-meta,
.ml-app-card--sheet .ml-app-card-meta {
	display: flex;
	align-items: center;
	gap: 6px;
	white-space: normal;
}

.ml-app-card--featured .ml-app-card-meta svg,
.ml-app-card--sheet .ml-app-card-meta svg { flex-shrink: 0; }

.ml-app-card--featured .ml-app-card-meta span,
.ml-app-card--sheet .ml-app-card-meta span {
	white-space: nowrap;
	overflow: hidden;
	text-overflow: ellipsis;
}

/* ── Feuille basse de l'itinéraire ──────────────────────────────────────────────────── */
.ml-app-sheet {
	position: absolute;
	left: 0;
	right: 0;
	bottom: 0;
	background: var(--color-surface);
	border-radius: 24px 24px 0 0;
	box-shadow: var(--shadow-lg);

	/* 22 px de l'aperçu + les 41 px d'indicateur d'accueil du châssis (34/0,8205). */
	padding: 12px 20px 63px;
	display: flex;
	flex-direction: column;
	gap: 16px;
	z-index: 5;
}

.ml-app-sheet-grip {
	width: 40px;
	height: 4px;
	border-radius: var(--radius-pill);
	background: var(--color-border);
	align-self: center;
}

/* La carte de la feuille n'a ni cadre, ni ombre, ni gouttière : la feuille les porte. */
.ml-app-sheet .ml-app-card {
	background: none;
	border: 0;
	box-shadow: none;
	padding: 0;
}


/* ────────────────────────────────────────────────────────────────────────────────────
   9. Sections natives Elementor
   ──────────────────────────────────────────────────────────────────────────────────── */

/* Les deux sections non épinglées sont des containers/widgets Elementor natifs, donc
   éditables visuellement. Seul ce qui n'est pas exprimable dans ses contrôles vit ici :
   les `clamp()`, le point de rupture à 860 px, et la grille.
   Le sélecteur doublé `.e-con.…` bat le `display:flex` / `padding` de `.e-con` sans
   recourir à !important. Les classes `.ml-e-*` ciblent les widgets Titre, dont le texte
   est rendu dans un `.elementor-heading-title` — même convention que le Kit du site
   (`.ml-h1 .elementor-heading-title`). */

.e-con.ml-section-pad,
.e-con.ml-faq-section {
	padding: clamp(76px, 10vw, 128px) clamp(20px, 4vw, 24px);
}

.e-con.ml-section-inner {
	max-width: var(--container-max);
	margin: 0 auto;
	width: 100%;
}

/* Clôture resserrée sur retour client. Le `min-height` réservait 80 vh alors que la section
   ne contenait que logo + promesse + 2 boutons ; elle porte désormais deux formulaires, donc
   sa hauteur vient du contenu et non d'une réserve. */
.e-con.ml-closing-section {
	padding: clamp(52px, 6vw, 80px) clamp(20px, 4vw, 24px);
	min-height: 52vh;
}

@media (max-width: 859px) {
	.e-con.ml-closing-section { min-height: 0; }
}

/* La section montre désormais le back-office à droite des bénéfices : la grille passe à
   trois colonnes, les deux premières pour les 4 cartes — resserrées et calées à gauche —
   la troisième pour le châssis. Rien ici n'est exprimable dans les contrôles du container :
   ni le `minmax()`, ni le placement du châssis, ni les `clamp()`.
   Le châssis est placé explicitement plutôt que laissé au flux : les items positionnés le
   sont avant les items automatiques, donc les 4 cartes remplissent bien les colonnes 1-2
   au lieu de voir la troisième sauter en colonne 3. */
.e-con.ml-pharma-grid {
	display: grid;
	grid-template-columns: repeat(2, minmax(0, 1fr)) minmax(300px, 1.35fr);
	grid-template-rows: min-content min-content 1fr;
	gap: 20px 22px;
}

/* Le bouton a rejoint la grille pour que la colonne de gauche — 4 cartes + appel à l'action —
   fasse exactement la hauteur du châssis. Les deux rangées de cartes sont en `min-content`,
   donc serrées : un item qui couvre une piste flexible n'agrandit pas les pistes
   intrinsèques qu'il traverse, tout le surplus imposé par le châssis tombe dans la troisième
   rangée. `align-self: end` y cale le bouton sur le bas du châssis. */
.e-con.ml-pharma-cta {
	grid-column: 1 / 3;
	grid-row: 3;
	align-self: end;
}

/* Châssis de navigateur — aperçu desktop du back-office pharmacien. Aucune hauteur n'est
   imposée : le châssis épouse la proportion de la capture, et ce sont les deux rangées de
   cartes qui s'alignent sur lui. Si un jour les cartes le dépassent, il s'étire (il couvre
   les deux rangées) et c'est le `cover` de l'image qui rogne, par le bas. */
.e-con.ml-bo-frame {
	grid-column: 3;
	grid-row: 1 / -1;
	background: var(--slate-0);
	border-radius: 14px;
	overflow: hidden;
	box-shadow: 0 18px 40px rgba(6, 84, 80, 0.32);
}

/* Barre haute inerte : trois pastilles, pas de barre d'adresse. Le HTML porte la classe
   lui-même plutôt que de passer par les classes du widget, pour ne pas dépendre du wrapper
   `.elementor-widget-container` — même convention que les icônes des cartes. */
.ml-story .ml-bo-chrome {
	display: flex;
	align-items: center;
	gap: 7px;
	height: 32px;
	padding: 0 14px;
	background: var(--slate-50);
	border-bottom: 1px solid var(--color-border);
	flex-shrink: 0;
}

.ml-story .ml-bo-chrome span {
	width: 10px;
	height: 10px;
	border-radius: 50%;
	background: var(--slate-300);
}

/* La capture occupe toute la hauteur restante du châssis. Elementor empile
   `.elementor-widget-container > a > img` : les trois maillons doivent transmettre la
   hauteur, sinon l'image retombe sur sa hauteur intrinsèque et crève le cadre. */
.ml-story .ml-bo-shot {
	flex: 1 1 auto;
	min-height: 0;
}

.ml-story .ml-bo-shot .elementor-widget-container,
.ml-story .ml-bo-shot a {
	display: block;
	height: 100%;
}

.ml-story .ml-bo-shot img {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
	object-position: top center;
	cursor: zoom-in;
}

/* Sous 1100 px, une troisième colonne à 300 px écraserait les cartes : le châssis passe
   sous elles, centré, avant même le point de rupture général à 860 px. Toujours aucune
   proportion imposée : lui coller un ratio plus étroit que celui de la capture la ferait
   rogner sur les côtés — donc amputer la barre latérale du back-office, la partie la plus
   reconnaissable. */
@media (max-width: 1099px) {
	.e-con.ml-pharma-grid {
		grid-template-columns: repeat(2, minmax(0, 1fr));
		grid-template-rows: none;
	}

	.e-con.ml-bo-frame {
		grid-column: 1 / -1;
		grid-row: auto;
		width: 100%;
		max-width: 460px;
		margin-inline: auto;
	}

	.e-con.ml-pharma-cta {
		grid-column: 1 / -1;
		grid-row: auto;
		align-self: auto;
		margin-top: 12px;
	}
}

@media (max-width: 859px) {
	.e-con.ml-pharma-grid { grid-template-columns: 1fr; }
}

.e-con.ml-closing-ctas {
	display: flex;
	flex-direction: row;
	gap: clamp(20px, 4vw, 32px);
	flex-wrap: wrap;
	justify-content: center;
	align-items: flex-start;
}

/* Les colonnes portaient un bouton à largeur intrinsèque ; elles portent maintenant un
   formulaire, qui a besoin d'une largeur pour que son champ ne s'écrase pas. */
.e-con.ml-cta-col {
	display: flex;
	flex-direction: column;
	align-items: stretch;
	gap: 10px;
	width: min(340px, 100%);
}

/* Champs des deux formulaires d'inscription. Ils sont posés sur le dégradé bleu → vert de la
   clôture : fond opaque obligatoire, sinon le texte saisi devient illisible. Ces règles
   closent ce qui n'est pas exprimable proprement dans les contrôles du widget (le `radius`
   pill sur `input` ET `textarea`, et la couleur du placeholder). */
.ml-closing-ctas .elementor-field-textual {
	background: var(--slate-0);
	border: 2px solid transparent;
	border-radius: var(--radius-pill);
	padding: 0 20px;
	height: 52px;
	font-family: var(--font-body);
	font-weight: var(--fw-semibold);
	font-size: var(--text-base);
	color: var(--color-text);
	letter-spacing: normal;
}

.ml-closing-ctas .elementor-field-textual::placeholder {
	color: var(--slate-400);
	opacity: 1;
}

.ml-closing-ctas .elementor-field-textual:focus {
	border-color: var(--slate-0);
	box-shadow: 0 0 0 3px rgba(255, 255, 255, 0.35);
	outline: none;
}

.ml-closing-ctas .elementor-message {
	font-family: var(--font-body);
	font-weight: var(--fw-bold);
	font-size: var(--text-sm);
	color: var(--slate-0);
	letter-spacing: normal;
}

.ml-story .ml-e-eyebrow .elementor-heading-title {
	font-family: var(--font-display);
	font-weight: var(--fw-extrabold);
	font-size: var(--text-sm);
	letter-spacing: 2px;
	text-transform: uppercase;
	color: var(--teal-50);
}

.ml-story .ml-e-h2 .elementor-heading-title {
	font-family: var(--font-display);
	font-weight: var(--fw-black);
	font-size: clamp(1.75rem, 4vw, 2.25rem);
	line-height: var(--lh-tight);
	max-width: 780px;
	color: #fff;
	overflow-wrap: anywhere;
	min-width: 0;
	letter-spacing: normal;
}

.ml-story .ml-e-card-title .elementor-heading-title {
	font-family: var(--font-display);
	font-weight: var(--fw-extrabold);
	font-size: var(--text-lg);
	color: #fff;
	margin-bottom: 6px;
	letter-spacing: normal;
}

.ml-story .ml-e-card-desc .elementor-heading-title {
	font-family: var(--font-body);
	font-weight: var(--fw-regular, 400);
	font-size: var(--text-sm);
	color: var(--teal-100);
	line-height: var(--lh-relaxed);
	letter-spacing: normal;
}

.ml-story .ml-e-claim .elementor-heading-title {
	font-family: var(--font-display);
	font-weight: var(--fw-bold);
	font-size: clamp(1.125rem, 2.5vw, 1.375rem);
	color: var(--blue-50);
	letter-spacing: normal;
}

/* `--slate-400` ne donnait que 2,2:1 sur le dégradé #0B5FCB → #00A79A de la clôture : les deux
   libellés étaient illisibles. `--blue-50` monte à ~6:1, conforme AA pour ce 12 px en gras. */
.ml-story .ml-e-cta-label .elementor-heading-title {
	font-family: var(--font-display);
	font-weight: var(--fw-bold);
	font-size: var(--text-xs);
	letter-spacing: 1.5px;
	color: var(--blue-50);
	text-transform: uppercase;
}

.ml-closing-logo,
.ml-closing-logo img {
	width: min(200px, 40vw);
	height: auto;
	display: block;
	margin: 0 auto;
}

/* FAQ — accordéon Elementor natif, posé après « Ancrage local ». La typographie et les
   couleurs viennent de ses propres contrôles (donc éditables) ; ne vit ici que ce qu'ils
   n'expriment pas : la largeur de colonne, la suppression de la boîte au profit de filets, et
   le chevron. */

.e-con.ml-faq-inner {
	max-width: 760px;
	margin: 0 auto;
	width: 100%;
}

.ml-story .ml-e-h2-dark .elementor-heading-title {
	font-family: var(--font-display);
	font-weight: var(--fw-black);
	font-size: clamp(1.75rem, 4vw, 2.25rem);
	line-height: var(--lh-tight);
	color: var(--color-text);
	letter-spacing: normal;
}

/* Le widget dessine une boîte complète (`border: 1px solid #d5d8dc` sur l'item, 2 classes) ;
   la maquette n'a que des filets de séparation. Nos 3 classes la battent. */
.ml-story .ml-e-faq .elementor-accordion-item {
	border: 0;
	border-bottom: 1px solid var(--color-border);
}

.ml-story .ml-e-faq .elementor-tab-title {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 16px;
	padding: 20px 0;
	line-height: var(--lh-snug);
	letter-spacing: normal;
}

.ml-story .ml-e-faq .elementor-accordion-title {
	flex: 1 1 auto;
	min-width: 0;
}

/* Chevron tracé en CSS plutôt que confié au contrôle d'icône : la page n'embarque pas Font
   Awesome (le plugin n'utilise que des SVG inline) et il aurait fallu l'y charger pour un
   décor. Il pivote au lieu d'être remplacé par un second glyphe. */
.ml-story .ml-e-faq .elementor-tab-title::after {
	content: "";
	width: 10px;
	height: 10px;
	flex-shrink: 0;
	border-right: 2px solid currentColor;
	border-bottom: 2px solid currentColor;
	transform: translateY(-3px) rotate(45deg);
	transition: transform var(--duration-base) var(--ease-standard);
}

.ml-story .ml-e-faq .elementor-tab-title.elementor-active::after {
	transform: translateY(3px) rotate(-135deg);
}

.ml-story .ml-e-faq .elementor-tab-content {
	border: 0;
	padding: 0 0 24px;
	letter-spacing: normal;
}

/* ────────────────────────────────────────────────────────────────────────────────────
   10. Mouvement réduit
   ──────────────────────────────────────────────────────────────────────────────────── */

@media (prefers-reduced-motion: reduce) {
	.ml-story {
		--ml-beat-shift: 0px;
		--ml-beat-scale: 1;
		--ml-beat-dur: 150ms;
	}

	.ml-beat[data-ml-state="before"],
	.ml-beat[data-ml-state="after"] { filter: none; }

	.ml-bg,
	.ml-phone,
	.ml-topbar,
	.ml-reveal { transition-duration: 150ms; }

	.ml-phone[data-ml-state="before"],
	.ml-phone[data-ml-state="after"] { transform: none; }

	.ml-scroll-hint { animation: none; }
}

/* ────────────────────────────────────────────────────────────────────────────────────
   11. Rendu dans l'éditeur Elementor
   ──────────────────────────────────────────────────────────────────────────────────── */

/* Sans cet aplatissement, l'éditeur affiche 1400 vh de canevas dont tout le contenu est
   à opacity:0 : le widget devient inutilisable. Ces règles closent le fichier pour
   gagner par l'ordre de cascade, sans !important. */

.ml-group--editor { height: auto; }

.ml-group--editor .ml-pane,
.ml-group--editor .ml-bgs {
	position: static;
	height: auto;
	margin-bottom: 0;
	overflow: visible;
	padding: 24px;
}

.ml-group--editor .ml-beats,
.ml-group--editor .ml-beats--fill,
.ml-group--editor .ml-phone-stage,
.ml-group--editor .ml-how-steps-col {
	position: static;
	inset: auto;
	height: auto;
	width: auto;
	max-width: none;
}

.ml-group--editor .ml-how-row { flex-direction: column; }

/* La colonne du téléphone est dimensionnée sur UN châssis à l'échelle (§ 6) ; aplatie, elle
   en empile trois, et l'échelle n'a plus de sens puisque le canevas de l'éditeur défile. */
.ml-group--editor .ml-how-phone-col {
	width: auto;
	height: auto;
}

.ml-group--editor .ml-how-phone-col .ml-phone-stage { transform: none; }

.ml-group--editor .ml-beat[data-ml-state],
.ml-group--editor .ml-phone[data-ml-state],
.ml-group--editor .ml-bg[data-ml-state] {
	position: relative;
	inset: auto;
	opacity: 1;
	visibility: visible;
	transform: none;
	filter: none;
	pointer-events: auto;
	transition: none;
}

.ml-group--editor .ml-beat[data-ml-state] {
	min-height: 160px;
	padding: 20px;
	border: 1px dashed var(--slate-300);
	border-radius: 12px;
	margin-bottom: 12px;
}

.ml-group--editor .ml-beat[data-ml-state]::before {
	content: attr(data-screen-label);
	display: block;
	font: 700 11px/1.4 system-ui, sans-serif;
	letter-spacing: 1px;
	text-transform: uppercase;
	color: var(--slate-400);
	margin-bottom: 12px;
	align-self: flex-start;
}

.ml-group--editor .ml-phone[data-ml-state] {
	width: 320px;
	height: 694px;
	margin: 0 auto 16px;
}

/* Les 4 dégradés sont réduits à des échantillons, sinon ils recouvriraient le contenu. */
.ml-group--editor .ml-bg[data-ml-state] { height: 48px; border-radius: 8px; margin-bottom: 8px; }
.ml-group--editor .ml-bgs { display: flex; flex-direction: column; }

/* Le flou reste désactivé dans l'éditeur même au-dessus de 1024 px. */
@media (min-width: 1024px) {
	.ml-group--editor .ml-beat[data-ml-state="before"],
	.ml-group--editor .ml-beat[data-ml-state="after"] { filter: none; }
}
