/* ===========================================================================
   ORIENT DC — Design system
   ---------------------------------------------------------------------------
   Sommaire
     01. Jetons (couleurs, typo, espacements, ombres)
     02. Réinitialisation et base
     03. Utilitaires de mise en page
     04. Typographie de section
     05. Boutons
     06. Décors (halos, grille, grain, orbes)
     07. En-tête et navigation
     08. Hero
     09. Repères chiffrés
     10. À propos
     11. Services
     12. La clinique en images
     13. Technologie
     14. Prévention
     15. Contact et localisation
     16. Bandeau d'appel
     17. Pied de page
     18. Pages intérieures
     18b. Questions fréquentes
     18c. Pages de soins
     19. Animations d'apparition
     20. Univers 3D — objets rendus (icônes et illustrations)
     21. Décors avancés (aurore, hexagones, orbes, rayons, particules)
     22. Effets premium (inclinaison, aimantation, dérive, balayage)
     23. Accessibilité et impression
   =========================================================================== */

/* == 01. Jetons ============================================================ */

:root {
	/* Bleu de la marque, relevé du logo (« O » cobalt). */
	--blue-50:  #eef5ff;
	--blue-100: #d9e8ff;
	--blue-200: #b6d2ff;
	--blue-300: #85b4fb;
	--blue-400: #4f90f3;
	--blue-500: #2570e0;
	--blue-600: #0f52ba;
	--blue-700: #0b3f92;
	--blue-800: #0a3272;
	--blue-900: #0a2757;

	/* Encres profondes : la base sombre du site. */
	--ink-900: #04070f;
	--ink-850: #060b16;
	--ink-800: #080f1f;
	--ink-700: #0c1830;
	--ink-600: #122343;
	--ink-500: #1b3157;

	--white: #ffffff;
	--surface-1: #ffffff;
	--surface-2: #f4f7fc;
	--surface-3: #e8f0fa;

	--text-strong: #071026;
	--text-body:   #40506b;
	/* 4,17:1 sur blanc auparavant (#6d7d97) : sous le seuil AA de 4,5:1.
	   #5a6a85 donne 5,48:1 sur blanc et 4,77:1 sur la plus claire des
	   surfaces teintées, tout en restant nettement plus clair que
	   --text-body : la hiérarchie visuelle est préservée. */
	--text-muted:  #5a6a85;
	--text-invert: #ffffff;
	--text-invert-soft: rgba(233, 240, 250, .72);

	--line: rgba(9, 30, 66, .09);
	--line-strong: rgba(9, 30, 66, .16);
	--line-invert: rgba(255, 255, 255, .12);

	/* Typographie */
	--font-body: 'Inter var', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
	--font-display: 'Sora var', var(--font-body);

	--fs-eyebrow: .75rem;
	--fs-small:   clamp(.82rem, .8rem + .1vw, .89rem);
	--fs-body:    clamp(.97rem, .94rem + .18vw, 1.06rem);
	--fs-lead:    clamp(1.03rem, 1rem + .3vw, 1.19rem);
	--fs-h4:      clamp(1.08rem, 1.02rem + .3vw, 1.28rem);
	--fs-h3:      clamp(1.3rem, 1.15rem + .7vw, 1.85rem);
	--fs-h2:      clamp(1.85rem, 1.4rem + 2.1vw, 3.35rem);
	--fs-h1:      clamp(2.35rem, 1.6rem + 3.6vw, 4.9rem);
	--fs-display: clamp(2.8rem, 1.8rem + 5vw, 6.5rem);

	/* Rythme vertical */
	--gutter: clamp(1.15rem, .7rem + 2.2vw, 2.5rem);
	--wrap: 1240px;
	--wrap-narrow: 880px;
	--section-y: clamp(4.5rem, 3rem + 6vw, 9rem);

	/* Formes */
	--r-xs: 8px;
	--r-sm: 12px;
	--r-md: 18px;
	--r-lg: 26px;
	--r-xl: 34px;
	--r-pill: 999px;

	/* Ombres en couches : jamais une seule ombre plate. */
	--sh-sm: 0 1px 2px rgba(7, 16, 38, .05), 0 2px 6px rgba(7, 16, 38, .04);
	--sh-md: 0 2px 4px rgba(7, 16, 38, .04), 0 10px 24px -6px rgba(7, 16, 38, .10);
	--sh-lg: 0 4px 8px rgba(7, 16, 38, .04), 0 24px 48px -12px rgba(7, 16, 38, .16);
	--sh-xl: 0 8px 16px rgba(7, 16, 38, .05), 0 44px 80px -20px rgba(10, 39, 87, .28);
	--sh-blue: 0 10px 30px -8px rgba(15, 82, 186, .45), 0 2px 6px rgba(15, 82, 186, .2);

	/* Mouvement */
	--ease: cubic-bezier(.22, 1, .36, 1);
	--ease-out: cubic-bezier(.16, 1, .3, 1);
	--ease-spring: cubic-bezier(.34, 1.56, .64, 1);
	--dur-fast: .22s;
	--dur: .42s;
	--dur-slow: .8s;

	--header-h: 86px;
}

/* Grain fin, appliqué en surcouche pour casser les dégradés trop lisses. */
:root {
	--noise: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.82' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)' opacity='.42'/%3E%3C/svg%3E");
}

/* == 02. Réinitialisation et base ========================================== */

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

html {
	-webkit-text-size-adjust: 100%;
	scroll-behavior: smooth;
	scroll-padding-top: calc(var(--header-h) + 16px);
}

body.odc {
	margin: 0;
	font-family: var(--font-body);
	font-size: var(--fs-body);
	font-weight: 400;
	line-height: 1.65;
	color: var(--text-body);
	background: var(--surface-1);
	-webkit-font-smoothing: antialiased;
	-moz-osx-font-smoothing: grayscale;
	font-feature-settings: 'cv11', 'ss01';
	/*
	 * `clip` et non `hidden`, et sur les DEUX éléments racine.
	 *
	 * Le panneau de navigation mobile est rangé hors cadre par une translation
	 * de 100 %. En français il part vers la droite, où `overflow-x: hidden`
	 * posé sur <body> le masquait. En arabe il part vers la gauche — c'est-à-dire
	 * du côté où le défilement RTL s'étend : les 360 px du panneau devenaient
	 * une zone défilable réelle, la page entière se décalait et le titre du hero
	 * sortait du cadre.
	 *
	 * `overflow-x: clip` ne crée aucun conteneur de défilement : le débord est
	 * découpé sans jamais devenir atteignable, dans un sens comme dans l'autre.
	 * C'est aussi ce qui le distingue de `hidden`, qui aurait cassé le
	 * `position: sticky` de l'illustration de la section Prévention.
	 */
	overflow-x: clip;
}

html { overflow-x: clip; }

img, picture, svg, video { display: block; max-width: 100%; }
img { height: auto; }

h1, h2, h3, h4 {
	margin: 0;
	font-family: var(--font-display);
	font-weight: 600;
	line-height: 1.08;
	letter-spacing: -.022em;
	color: var(--text-strong);
	text-wrap: balance;
}

p { margin: 0; text-wrap: pretty; }
ul, ol { margin: 0; padding: 0; list-style: none; }

a { color: var(--blue-600); text-decoration: none; transition: color var(--dur-fast) var(--ease); }
/* Le survol assombrit au lieu d'éclaircir : --blue-500 ne tenait que
   4,37:1 sur les sections teintées, --blue-700 en donne 8,7 partout. */
a:hover { color: var(--blue-700); }

button { font: inherit; color: inherit; background: none; border: 0; cursor: pointer; }

::selection { background: var(--blue-600); color: #fff; }

:focus-visible {
	outline: 2px solid var(--blue-500);
	outline-offset: 3px;
	border-radius: 4px;
}

/* Barre de progression de lecture. */
.odc-progress {
	position: fixed;
	inset: 0 auto auto 0;
	z-index: 120;
	width: 100%;
	height: 2px;
	background: linear-gradient(90deg, var(--blue-600), var(--blue-300));
	transform: scaleX(var(--p, 0));
	transform-origin: 0 50%;
	will-change: transform;
	pointer-events: none;
}

.odc-skip {
	position: absolute;
	top: -100px;
	inset-inline-start: 16px;
	z-index: 200;
	padding: .7rem 1.1rem;
	color: #fff;
	background: var(--ink-800);
	border-radius: var(--r-xs);
	transition: top var(--dur-fast) var(--ease);
}
.odc-skip:focus { top: 12px; color: #fff; }

/* == 03. Utilitaires de mise en page ======================================= */

.odc-wrap {
	width: 100%;
	max-width: var(--wrap);
	margin-inline: auto;
	padding-inline: var(--gutter);
}
.odc-wrap--narrow { max-width: var(--wrap-narrow); }

.odc-section { position: relative; padding-block: var(--section-y); }
.odc-section--flush-top { padding-top: 0; }
.odc-section--dark { color: var(--text-invert-soft); background: var(--ink-900); }
.odc-section--dark h2, .odc-section--dark h3, .odc-section--dark h4 { color: #fff; }
.odc-section--tint { background: var(--surface-2); }

.odc-sr {
	position: absolute !important;
	width: 1px; height: 1px;
	margin: -1px; padding: 0;
	overflow: hidden;
	clip-path: inset(50%);
	white-space: nowrap;
	border: 0;
}

/* == 04. Typographie de section ============================================ */

.odc-head { max-width: 46rem; margin-bottom: clamp(2.2rem, 1.6rem + 2vw, 3.8rem); }
.odc-head--center { margin-inline: auto; text-align: center; }
.odc-head--start { margin-inline: 0; }

.odc-eyebrow {
	display: inline-flex;
	align-items: center;
	gap: .6rem;
	margin-bottom: 1.1rem;
	font-family: var(--font-body);
	font-size: var(--fs-eyebrow);
	font-weight: 600;
	letter-spacing: .16em;
	text-transform: uppercase;
	color: var(--blue-600);
}
.odc-head--dark .odc-eyebrow { color: var(--blue-300); }

.odc-eyebrow__dot {
	position: relative;
	width: 6px; height: 6px;
	border-radius: 50%;
	background: currentColor;
}
.odc-eyebrow__dot::after {
	content: '';
	position: absolute;
	inset: -5px;
	border: 1px solid currentColor;
	border-radius: 50%;
	opacity: .35;
	animation: odc-ping 2.6s var(--ease) infinite;
}
@keyframes odc-ping {
	0%   { transform: scale(.6); opacity: .6; }
	70%  { transform: scale(1.5); opacity: 0; }
	100% { transform: scale(1.5); opacity: 0; }
}

.odc-h2 { font-size: var(--fs-h2); }
.odc-h2 em {
	font-style: normal;
	background: linear-gradient(100deg, var(--blue-500), var(--blue-300) 60%, var(--blue-400));
	-webkit-background-clip: text;
	background-clip: text;
	color: transparent;
}
.odc-section--dark .odc-h2 em {
	background: linear-gradient(100deg, var(--blue-200), #fff 55%, var(--blue-300));
	-webkit-background-clip: text;
	background-clip: text;
	color: transparent;
}

.odc-lead {
	margin-top: 1.15rem;
	font-size: var(--fs-lead);
	line-height: 1.62;
	color: var(--text-muted);
}
.odc-section--dark .odc-lead { color: var(--text-invert-soft); }

/* == 05. Boutons =========================================================== */

.odc-btn {
	--btn-bg: var(--blue-600);
	--btn-fg: #fff;
	position: relative;
	display: inline-flex;
	align-items: center;
	gap: .7rem;
	padding: .95rem 1.5rem;
	font-family: var(--font-body);
	font-size: var(--fs-small);
	font-weight: 600;
	letter-spacing: -.005em;
	color: var(--btn-fg);
	background: var(--btn-bg);
	border-radius: var(--r-pill);
	isolation: isolate;
	overflow: hidden;
	white-space: nowrap;
	transition: transform var(--dur) var(--ease), box-shadow var(--dur) var(--ease), color var(--dur-fast) var(--ease);
}

/* Voile lumineux qui balaie le bouton au survol. */
.odc-btn::before {
	content: '';
	position: absolute;
	inset: 0;
	z-index: -1;
	background: linear-gradient(115deg, var(--blue-500), var(--blue-400) 45%, var(--blue-600));
	opacity: 0;
	transition: opacity var(--dur) var(--ease);
}
.odc-btn::after {
	content: '';
	position: absolute;
	top: 0; left: -120%;
	z-index: -1;
	width: 55%; height: 100%;
	background: linear-gradient(100deg, transparent, rgba(255, 255, 255, .38), transparent);
	transform: skewX(-18deg);
	transition: left .75s var(--ease);
}
.odc-btn:hover { color: #fff; transform: translateY(-2px); box-shadow: var(--sh-blue); }
.odc-btn:hover::before { opacity: 1; }
.odc-btn:hover::after { left: 130%; }
.odc-btn:active { transform: translateY(0) scale(.985); }

.odc-btn__icon {
	display: grid;
	place-items: center;
	transition: transform var(--dur) var(--ease-spring);
}
.odc-btn:hover .odc-btn__icon { transform: translateX(4px); }

.odc-btn--ghost {
	--btn-bg: transparent;
	--btn-fg: var(--text-strong);
	box-shadow: inset 0 0 0 1px var(--line-strong);
}
.odc-btn--ghost::before { background: var(--ink-800); }
.odc-btn--ghost:hover { box-shadow: var(--sh-lg); }

.odc-btn--glass {
	--btn-bg: rgba(255, 255, 255, .08);
	--btn-fg: #fff;
	box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .2);
	-webkit-backdrop-filter: blur(14px);
	backdrop-filter: blur(14px);
}
.odc-btn--glass::before { background: rgba(255, 255, 255, .16); }
.odc-btn--glass:hover { box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .38), 0 16px 34px -12px rgba(0, 0, 0, .5); }

.odc-btn--light { --btn-bg: #fff; --btn-fg: var(--blue-700); }
.odc-btn--light::before { background: var(--blue-50); }
.odc-btn--light:hover { color: var(--blue-700); }

.odc-btn--lg { padding: 1.1rem 1.85rem; font-size: 1rem; }
.odc-btn--block { width: 100%; justify-content: center; }

/* Bouton circulaire (flèches de carte, carrousels). */
.odc-round {
	display: grid;
	place-items: center;
	width: 42px; height: 42px;
	color: var(--blue-600);
	background: var(--white);
	border-radius: 50%;
	box-shadow: var(--sh-sm), inset 0 0 0 1px var(--line);
	transition: transform var(--dur) var(--ease-spring), background var(--dur) var(--ease), color var(--dur) var(--ease), box-shadow var(--dur) var(--ease);
}
.odc-round:hover {
	color: #fff;
	background: var(--blue-600);
	transform: scale(1.1);
	box-shadow: var(--sh-blue);
}

/* == 06. Décors ============================================================ */

.odc-glow {
	position: absolute;
	border-radius: 50%;
	filter: blur(90px);
	opacity: .5;
	pointer-events: none;
	/*
	 * PAS de `will-change: transform` ici.
	 *
	 * Le halo n'est jamais transformé : la dérive à la souris porte sur
	 * `[data-drift]` (l. 2700), qui déclare son propre indice. L'indication
	 * réservait donc une couche GPU permanente — pour un disque flouté à 90 px
	 * sur 40vw, et il y en a jusqu'à neuf par page. C'est de la mémoire vidéo
	 * immobilisée sans qu'aucune animation ne la justifie.
	 */
}
.odc-glow--blue { background: radial-gradient(circle, rgba(37, 112, 224, .85), transparent 68%); }
.odc-glow--deep { background: radial-gradient(circle, rgba(15, 82, 186, .7), transparent 70%); }
.odc-glow--cyan { background: radial-gradient(circle, rgba(133, 180, 251, .55), transparent 70%); }

/* Grille technique discrète, en fondu vers les bords. */
.odc-grid-bg {
	position: absolute;
	inset: 0;
	background-image:
		linear-gradient(rgba(255, 255, 255, .045) 1px, transparent 1px),
		linear-gradient(90deg, rgba(255, 255, 255, .045) 1px, transparent 1px);
	background-size: 68px 68px;
	-webkit-mask-image: radial-gradient(ellipse 90% 70% at 50% 35%, #000 20%, transparent 78%);
	mask-image: radial-gradient(ellipse 90% 70% at 50% 35%, #000 20%, transparent 78%);
	pointer-events: none;
}

.odc-noise {
	position: absolute;
	inset: 0;
	background-image: var(--noise);
	opacity: .05;
	mix-blend-mode: overlay;
	pointer-events: none;
}

/* Motif de points, comme dans la référence, en décor de section clair. */
.odc-dots {
	position: absolute;
	width: 190px; height: 190px;
	background-image: radial-gradient(var(--blue-300) 1.4px, transparent 1.4px);
	background-size: 15px 15px;
	opacity: .4;
	pointer-events: none;
}

/* == 07. En-tête et navigation ============================================= */

.odc-header {
	position: fixed;
	inset: 0 0 auto 0;
	z-index: 100;
	transition: background var(--dur) var(--ease), box-shadow var(--dur) var(--ease), border-color var(--dur) var(--ease);
	border-bottom: 1px solid transparent;
}
.odc-header__inner {
	display: flex;
	align-items: center;
	gap: clamp(1rem, .5rem + 2vw, 2.5rem);
	min-height: var(--header-h);
}

/* Au repos sur le hero sombre : totalement transparent. */
.odc-header.is-stuck {
	background: rgba(6, 11, 22, .72);
	border-bottom-color: var(--line-invert);
	-webkit-backdrop-filter: blur(20px) saturate(160%);
	backdrop-filter: blur(20px) saturate(160%);
}
body.odc-page .odc-header {
	background: rgba(6, 11, 22, .88);
	-webkit-backdrop-filter: blur(20px);
	backdrop-filter: blur(20px);
}

/* -- Logo -- */
.odc-logo, .odc-logo-img { flex: 0 0 auto; }

/*
 * Logo client : seule la hauteur est imposée, la largeur suit le rapport réel
 * de l'image. Le fichier est détouré et son liseré blanc porte le contraste sur
 * fond sombre — aucune variante claire n'est nécessaire.
 */
.odc-logo-img {
	width: auto;
	height: 62px;
	transition: transform var(--dur) var(--ease-spring), filter var(--dur) var(--ease);
}
.odc-logo-link:hover .odc-logo-img { transform: translateY(-2px) scale(1.03); }
.odc-footer .odc-logo-img { height: 74px; }
.odc-mobile__top .odc-logo-img { height: 46px; }
@media (max-width: 1023px) {
	.odc-logo-img { height: 50px; }
}
.odc-logo {
	display: inline-flex;
	align-items: center;
	gap: .6rem;
	color: #fff;
}
.odc-logo__mark {
	width: 34px; height: 38px;
	color: var(--blue-400);
	transition: transform var(--dur) var(--ease-spring), color var(--dur) var(--ease);
}
.odc-logo:hover .odc-logo__mark { transform: translateY(-2px) rotate(-4deg); color: var(--blue-300); }
.odc-logo__tooth {
	stroke-dasharray: 160;
	stroke-dashoffset: 0;
}
.odc-logo__type { display: flex; flex-direction: column; line-height: 1; }
.odc-logo__name {
	font-family: var(--font-display);
	font-size: 1.16rem;
	font-weight: 700;
	letter-spacing: -.03em;
	color: #fff;
}
.odc-logo__name b { color: var(--blue-400); font-weight: 800; }
.odc-logo__name em { font-style: normal; margin-inline-start: .18em; opacity: .92; }
.odc-logo__sub {
	margin-top: .3rem;
	font-size: .55rem;
	font-weight: 600;
	letter-spacing: .22em;
	color: rgba(255, 255, 255, .5);
}

/* -- Navigation -- */
.odc-nav { margin-inline: auto; }
.odc-nav__list { display: flex; align-items: center; gap: .15rem; }
.odc-nav__link {
	position: relative;
	display: block;
	padding: .55rem .85rem;
	font-size: var(--fs-small);
	font-weight: 500;
	color: rgba(255, 255, 255, .74);
	white-space: nowrap;
	border-radius: var(--r-pill);
	transition: color var(--dur-fast) var(--ease), background var(--dur-fast) var(--ease);
}
.odc-nav__link:hover { color: #fff; background: rgba(255, 255, 255, .08); }
.odc-nav__link[aria-current='true'],
.odc-nav__link.is-active { color: #fff; background: rgba(37, 112, 224, .22); }
.odc-nav__link.is-active::after {
	content: '';
	position: absolute;
	left: 50%; bottom: 3px;
	width: 14px; height: 2px;
	background: var(--blue-400);
	border-radius: 2px;
	transform: translateX(-50%);
}

/*
 * Entre le seuil du menu burger (1024 px) et 1220 px, sept entrées ne passent
 * qu'en resserrant les gouttières : sans cela le libellé le plus long chasse le
 * bouton d'appel hors de l'en-tête. Au-delà, la respiration d'origine revient.
 */
@media (min-width: 1024px) and (max-width: 1219px) {
	.odc-nav__link { padding-inline: .5rem; }
}

/* -- Sous-menu des pôles de soins --------------------------------------------
 * Ouvert au survol ET au focus clavier, sans JavaScript. `:focus-within` suffit :
 * l'utilisateur qui tabule dans le panneau le fait apparaître, et le quitter le
 * referme. Le délai de fermeture évite qu'un curseur qui coupe l'angle entre le
 * lien et le panneau ne le fasse disparaître sous la souris.
 * -------------------------------------------------------------------------- */

/*
 * Le panneau se positionne sur la BARRE, pas sur le lien.
 *
 * Ancré au lien, un panneau de 832 px partait hors écran dès que son lien
 * s'éloignait du bord — et en arabe, où la barre se lit de droite à gauche,
 * neuf liens sortaient à 1024 px. Rattaché à la barre, son bord de début
 * coïncide avec celui de la navigation : il ne peut plus la déborder, dans
 * un sens comme dans l'autre. `top: 100%` reste juste sous la barre, les
 * deux ayant la même hauteur.
 */
.odc-nav { position: relative; }
.odc-nav__item { position: static; }
.odc-nav__link { display: flex; align-items: center; gap: .3rem; }
.odc-nav__caret { display: inline-flex; transition: transform var(--dur-fast) var(--ease); }
.odc-nav__item--has-menu:hover .odc-nav__caret,
.odc-nav__item--has-menu:focus-within .odc-nav__caret { transform: rotate(180deg); }

.odc-nav__panel {
	position: absolute;
	top: calc(100% + 10px);
	/*
	 * Ancré sur le BORD DE DÉBUT du lien, pas centré dessus.
	 *
	 * Le panneau passe sur deux colonnes et double de largeur ; centré sur
	 * « Nos soins », qui siège à 256 px du bord, il commencerait à −112 px —
	 * hors écran. `inset-inline-start` se retourne seul en arabe.
	 */
	inset-inline-start: 0;
	z-index: 60;
	width: min(94vw, 52rem);
	padding: .5rem;
	background: rgba(8, 15, 31, .92);
	backdrop-filter: blur(18px) saturate(150%);
	-webkit-backdrop-filter: blur(18px) saturate(150%);
	border-radius: var(--r-lg);
	box-shadow: var(--sh-xl), inset 0 0 0 1px var(--line-invert);
	opacity: 0;
	visibility: hidden;
	transform: translateY(-8px);
	transition: opacity var(--dur-fast) var(--ease), transform var(--dur-fast) var(--ease), visibility 0s linear var(--dur-fast);
}
/* Pont invisible entre le lien et le panneau : sans lui, les 10 px d'écart
   referment le menu dès que la souris quitte le lien. */
.odc-nav__panel::before { content: ''; position: absolute; inset: -12px 0 auto 0; height: 12px; }

.odc-nav__item--has-menu:hover .odc-nav__panel,
.odc-nav__item--has-menu:focus-within .odc-nav__panel {
	opacity: 1;
	visibility: visible;
	transform: translateY(0);
	transition-delay: 0s;
}

/*
 * DEUX COLONNES : toute la branche des soins visible d'un coup.
 *
 * Sur une colonne, les dix-sept liens dépassaient la hauteur utile : le panneau
 * défilait, et « Urgence dentaire » — le lien qu'on cherche quand on est
 * pressé — n'était jamais visible sans molette. Le multi-colonnes convient
 * mieux qu'une grille : les groupes n'ont pas la même hauteur, et
 * `break-inside` garde chaque pôle soudé à ses sous-services.
 */
.odc-nav__panel > ul {
	display: block;
	column-count: 2;
	column-gap: .35rem;
}
.odc-nav__panel > ul > li {
	break-inside: avoid;
	page-break-inside: avoid;
}
.odc-nav__panel ul ul { display: grid; gap: 1px; }
.odc-nav__panel a {
	display: grid;
	grid-template-columns: auto minmax(0, 1fr);
	align-items: center;
	gap: .7rem;
	padding: .6rem .7rem;
	color: rgba(255, 255, 255, .8);
	border-radius: var(--r-sm);
	transition: background var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease);
}
.odc-nav__panel a:hover,
.odc-nav__panel a:focus-visible { color: #fff; background: rgba(255, 255, 255, .09); }
.odc-nav__panel strong {
	display: block;
	font-family: var(--font-display);
	font-size: .88rem;
	font-weight: 600;
	color: #fff;
}
.odc-nav__panel strong + span {
	display: block;
	margin-top: .12rem;
	font-size: .74rem;
	line-height: 1.45;
	color: rgba(226, 235, 248, .62);
}
.odc-nav__panel-ico {
	display: grid;
	place-items: center;
	width: 32px; height: 32px;
	color: var(--blue-300);
	background: rgba(79, 144, 243, .16);
	border-radius: var(--r-xs);
}
.odc-nav__panel a.is-alert .odc-nav__panel-ico { color: #ffb08a; background: rgba(255, 140, 90, .16); }

@media (prefers-reduced-motion: reduce) {
	.odc-nav__panel { transition: none; }
}

.odc-header__cta { display: flex; align-items: center; gap: .6rem; }

.odc-burger {
	display: none;
	place-items: center;
	width: 44px; height: 44px;
	color: #fff;
	border-radius: var(--r-sm);
	box-shadow: inset 0 0 0 1px var(--line-invert);
}
.odc-burger:hover { background: rgba(255, 255, 255, .08); }

/* -- Panneau mobile -- */
.odc-mobile {
	position: fixed;
	inset: 0;
	z-index: 110;
	display: grid;
	grid-template-rows: auto 1fr auto;
	padding: var(--gutter);
	/* La barre d'accueil de l'iPhone recouvrait le bouton « Prendre
	   rendez-vous », dernier élément du pied de panneau. */
	padding-bottom: max(var(--gutter), env(safe-area-inset-bottom, 0px));
	background: rgba(4, 7, 15, .97);
	-webkit-backdrop-filter: blur(24px);
	backdrop-filter: blur(24px);
	visibility: hidden;
	opacity: 0;
	transition: opacity var(--dur) var(--ease), visibility var(--dur);
}
.odc-mobile.is-open { visibility: visible; opacity: 1; }
.odc-mobile__top { display: flex; align-items: center; justify-content: space-between; min-height: var(--header-h); }
/*
 * La liste du panneau mobile doit DÉFILER.
 *
 * Trois défauts se cumulaient dans la règle d'origine, et ils ne se sont vus
 * qu'en ajoutant « Nos réalisations » : le panneau est passé de 7 à 8 entrées,
 * plus les 7 pôles déroulés sous « Nos soins ». Quinze liens, et sur un
 * téléphone :
 *
 *   1. aucun `overflow-y` — le débord était purement et simplement coupé ;
 *   2. aucun `min-height: 0` — un élément de grille refuse par défaut de
 *      descendre sous la hauteur de son contenu, donc la rangée `1fr`
 *      gonflait et poussait `.odc-mobile__foot` hors de l'écran, emportant
 *      avec lui le sélecteur de langue et les deux boutons d'action ;
 *   3. `justify-content: center` — même le défilement rétabli, un contenu
 *      centré qui déborde déborde des DEUX côtés, et le haut de la liste
 *      devient inatteignable. `safe center` centre tant que ça tient et
 *      bascule en alignement haut dès que ça ne tient plus.
 *
 * Résultat avant correction : « Prévention », « Contact », le choix de la
 * langue et le bouton d'appel étaient invisibles et inaccessibles sur mobile.
 */
.odc-mobile__list {
	display: flex;
	flex-direction: column;
	justify-content: safe center;
	gap: .3rem;
	min-height: 0;
	overflow-y: auto;
	/* Le défilement ne se propage pas à la page derrière le panneau. */
	overscroll-behavior: contain;
	-webkit-overflow-scrolling: touch;
	scrollbar-width: thin;
	scrollbar-color: rgba(255, 255, 255, .22) transparent;
}
.odc-mobile__list::-webkit-scrollbar { width: 4px; }
.odc-mobile__list::-webkit-scrollbar-thumb {
	background: rgba(255, 255, 255, .22);
	border-radius: var(--r-pill);
}
.odc-mobile__link {
	display: flex;
	align-items: baseline;
	gap: 1rem;
	padding: .55rem 0;
	font-family: var(--font-display);
	/*
	 * Échelle calibrée sur le NOMBRE d'entrées, pas seulement sur la largeur.
	 *
	 * `clamp(1.6rem, 1.2rem + 3vw, 2.4rem)` donnait 38 px sur une tablette de
	 * 768 px. C'était juste tant que le panneau portait 7 liens ; il en porte
	 * 15 depuis que « Nos soins » déroule ses pôles et que « Nos réalisations »
	 * s'est ajouté. Quatre entrées sur huit tenaient à l'écran, et le menu se
	 * parcourait au doigt sur deux hauteurs d'écran. Un menu se balaie du
	 * regard : il doit tenir, ou presque.
	 */
	font-size: clamp(1.3rem, 1.05rem + 1.5vw, 1.85rem);
	font-weight: 600;
	letter-spacing: -.03em;
	color: #fff;
	border-bottom: 1px solid var(--line-invert);
	opacity: 0;
	transform: translateY(18px);
}
.odc-mobile.is-open .odc-mobile__link {
	animation: odc-rise .55s var(--ease-out) forwards;
	animation-delay: calc(var(--i, 0) * 55ms + 90ms);
}

/* Pôles de soins, déroulés sous leur parent dans le panneau mobile. */
.odc-mobile__sub {
	display: grid;
	gap: 1px;
	padding: .5rem 0 .8rem;
	border-bottom: 1px solid var(--line-invert);
	opacity: 0;
	transform: translateY(18px);
}
.odc-mobile.is-open .odc-mobile__sub {
	animation: odc-rise .55s var(--ease-out) forwards;
	animation-delay: calc(var(--i, 0) * 55ms + 130ms);
}
.odc-mobile__sub a {
	display: flex;
	align-items: center;
	gap: .6rem;
	/*
	 * 44 px : la cible tactile minimale. Le panneau mobile ne se parcourt
	 * qu'au doigt, et il était mesuré à 40 px.
	 */
	min-height: 44px;
	padding: .2rem .1rem;
	font-size: .95rem;
	color: rgba(255, 255, 255, .74);
}
.odc-mobile__sub a:hover { color: #fff; }
.odc-mobile__sub svg { flex: 0 0 auto; color: var(--blue-300); }
.odc-mobile__sub a.is-alert svg { color: #ffb08a; }

@media (prefers-reduced-motion: reduce) {
	.odc-mobile__link, .odc-mobile__sub { opacity: 1; transform: none; animation: none !important; }
}
.odc-mobile__link span {
	font-family: var(--font-body);
	font-size: .7rem;
	font-weight: 600;
	color: var(--blue-400);
}
.odc-mobile__foot { display: grid; gap: .7rem; padding-top: 1.4rem; }

@keyframes odc-rise {
	to { opacity: 1; transform: none; }
}

@media (max-width: 1023px) {
	.odc-nav, .odc-header__cta .odc-btn { display: none; }
	.odc-burger { display: grid; }
	.odc-logo__sub { display: none; }
}

/* == 08. Hero ============================================================== */

.odc-hero {
	position: relative;
	display: flex;
	align-items: flex-end;
	min-height: min(100svh, 900px);
	padding-top: calc(var(--header-h) + clamp(2.5rem, 1rem + 6vw, 6rem));
	padding-bottom: clamp(7rem, 4rem + 9vw, 12rem);
	overflow: hidden;
	color: #fff;
	background: var(--ink-900);
	isolation: isolate;
}

.odc-hero__media { position: absolute; inset: 0; z-index: -3; will-change: transform; }

/*
 * Fond défilant : les vues sont empilées et se fondent l'une dans l'autre.
 * Un fondu, pas un glissement — la couche porte déjà la parallaxe, deux
 * translations concurrentes se combattraient.
 */
.odc-hero__slide {
	position: absolute;
	inset: 0;
	z-index: 0;
	opacity: 0;
	transition: opacity 1.5s var(--ease-out);
}
/*
 * La vue sortante reste opaque SOUS la vue entrante pendant tout le fondu.
 * Les faire passer toutes deux par 50 % au même instant laissait transparaître
 * le fond de section et n'appliquait qu'à moitié le `dim` de chacune : la
 * transition éclaircissait au lieu de fondre (luminance mesurée à 55,7 en
 * milieu de fondu, contre 41,5 et 54,1 pour les deux vues stabilisées).
 */
.odc-hero__slide.is-leaving { opacity: 1; z-index: 0; }
.odc-hero__slide.is-active  { opacity: 1; z-index: 1; }

.odc-hero__slide img, .odc-hero__slide picture {
	width: 100%; height: 100%;
	object-fit: cover;
	object-position: var(--pos, 32% 40%);
}

/* Voile propre à la vue : cf. le champ `dim` de odc_hero_slides(). */
.odc-hero__slide::after {
	content: '';
	position: absolute;
	inset: 0;
	background: rgba(4, 7, 15, var(--dim, 0));
}
/* Voile en deux couches : lisibilité du texte à gauche, respiration à droite. */
.odc-hero__scrim {
	position: absolute;
	inset: 0;
	z-index: -2;
	background:
		linear-gradient(100deg, rgba(4, 7, 15, .96) 0%, rgba(4, 7, 15, .84) 34%, rgba(6, 12, 26, .52) 62%, rgba(8, 18, 40, .58) 100%),
		linear-gradient(to top, var(--ink-900) 2%, transparent 42%);
}
.odc-hero .odc-grid-bg, .odc-hero .odc-noise { z-index: -1; }
.odc-hero__canvas {
	position: absolute;
	inset: 0;
	z-index: -1;
	opacity: .55;
	pointer-events: none;
}
.odc-hero .odc-glow--a { top: -12%; left: -8%; width: 42vw; height: 42vw; opacity: .35; }
.odc-hero .odc-glow--b { right: -10%; bottom: -18%; width: 38vw; height: 38vw; opacity: .3; }

.odc-hero__grid {
	display: grid;
	grid-template-columns: minmax(0, 1fr) auto;
	gap: clamp(2rem, 1rem + 4vw, 4.5rem);
	align-items: end;
	width: 100%;
}

.odc-hero__badge {
	display: inline-flex;
	align-items: center;
	gap: .6rem;
	padding: .5rem 1rem .5rem .7rem;
	margin-bottom: 1.6rem;
	font-size: .72rem;
	font-weight: 600;
	letter-spacing: .13em;
	text-transform: uppercase;
	color: var(--blue-200);
	background: rgba(37, 112, 224, .14);
	border-radius: var(--r-pill);
	box-shadow: inset 0 0 0 1px rgba(133, 180, 251, .28);
}
.odc-hero__badge svg { color: var(--blue-300); }

.odc-hero__title {
	max-width: 17ch;
	font-size: var(--fs-h1);
	font-weight: 600;
	line-height: 1.02;
	letter-spacing: -.035em;
	color: #fff;
}
.odc-hero__title em {
	display: block;
	font-style: normal;
	background: linear-gradient(96deg, #fff 8%, var(--blue-200) 52%, var(--blue-400));
	-webkit-background-clip: text;
	background-clip: text;
	color: transparent;
}

.odc-hero__text {
	max-width: 44ch;
	margin-top: 1.5rem;
	font-size: var(--fs-lead);
	color: rgba(226, 235, 248, .78);
}

.odc-hero__actions { display: flex; flex-wrap: wrap; gap: .8rem; margin-top: 2.2rem; }

.odc-hero__chips {
	display: flex;
	flex-wrap: wrap;
	gap: .4rem 1.6rem;
	margin-top: 2.4rem;
	padding-top: 1.6rem;
	border-top: 1px solid var(--line-invert);
}
.odc-hero__chip {
	display: inline-flex;
	align-items: center;
	gap: .5rem;
	font-size: var(--fs-small);
	color: rgba(226, 235, 248, .8);
}
.odc-hero__chip svg { color: var(--blue-400); }

/* -- Cartes flottantes en verre -- */
.odc-hero__cards { display: grid; gap: .7rem; width: min(290px, 34vw); }
.odc-glass {
	position: relative;
	display: flex;
	align-items: center;
	gap: .9rem;
	padding: .95rem 1.1rem;
	background: rgba(255, 255, 255, .07);
	border-radius: var(--r-md);
	box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .14), 0 18px 40px -18px rgba(0, 0, 0, .7);
	-webkit-backdrop-filter: blur(18px) saturate(150%);
	backdrop-filter: blur(18px) saturate(150%);
	transition: transform var(--dur) var(--ease), background var(--dur) var(--ease), box-shadow var(--dur) var(--ease);
}
.odc-glass:hover {
	background: rgba(255, 255, 255, .12);
	transform: translateX(-6px);
	box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .26), 0 24px 50px -18px rgba(0, 0, 0, .8);
}
.odc-glass__icon {
	display: grid;
	place-items: center;
	flex: 0 0 auto;
	width: 40px; height: 40px;
	color: var(--blue-200);
	background: rgba(37, 112, 224, .24);
	border-radius: var(--r-sm);
	box-shadow: inset 0 0 0 1px rgba(133, 180, 251, .3);
}
.odc-glass__title { display: block; font-size: .92rem; font-weight: 600; color: #fff; line-height: 1.3; }
.odc-glass__sub { display: block; margin-top: .15rem; font-size: .76rem; line-height: 1.4; color: rgba(226, 235, 248, .62); }

@keyframes odc-bob {
	0%, 100% { transform: translate(-50%, -50%); }
	50%      { transform: translate(-50%, calc(-50% + 7px)); }
}

/* Objet 3D signature du hero.
   Positionné en `inset-inline-end` et non en `right` : le thème est trilingue et
   passe en `dir="rtl"` en arabe (cf. inc/i18n.php). Une propriété logique se
   retourne seule, là où un `right` figé collerait l'objet du mauvais côté et le
   ferait chevaucher la colonne de titre. */
.odc-hero__object {
	position: absolute;
	z-index: 2;
	inset-block-start: 46%;
	inset-inline-end: clamp(300px, 27vw, 430px);
	width: 260px;
	pointer-events: none;
}
.odc-hero__object .odc-i3d { filter: drop-shadow(0 24px 44px rgba(4, 12, 30, .6)) drop-shadow(0 0 34px rgba(79, 144, 243, .3)); }

/* Sous 1240 px, l'espace entre le titre et les cartes se referme : l'objet
   viendrait passer sur le texte. Il disparaît plutôt que d'être réduit — à
   120 px il ne se lisait plus comme un objet, seulement comme une salissure. */
@media (max-width: 1239px) {
	.odc-hero__object { display: none; }
}

@media (max-width: 899px) {
	.odc-hero__grid { grid-template-columns: 1fr; }
	.odc-hero__cards { flex-direction: row; width: 100%; grid-template-columns: 1fr 1fr; }
	.odc-hero__cards .odc-glass:last-child { grid-column: span 2; }
	/*
	 * Recadrage mobile réglé pour la PREMIÈRE vue seule : son sujet est décentré
	 * vers la gauche, un cadrage centré le couperait. Les vues suivantes sont des
	 * recadrages 16/9 déjà composés pour le site et gardent leur `--pos`.
	 * Écrit sur `.odc-hero__slide:first-child` et non sur `.odc-hero__media img` :
	 * à spécificité égale, l'ancien sélecteur passait après la règle de base et
	 * imposait ce cadrage à toutes les vues.
	 */
	.odc-hero__slide:first-child img { object-position: 42% 35%; }
}
@media (max-width: 560px) {
	.odc-hero__cards { grid-template-columns: 1fr; }
	.odc-hero__cards .odc-glass:last-child { grid-column: auto; }
}

/* == 09. Repères chiffrés ================================================== */

.odc-facts { position: relative; z-index: 5; margin-top: clamp(-6.5rem, -5vw, -4rem); }

/* Chevauche volontairement le bord haut de la carte, comme dans la référence. */
.odc-facts__cue {
	position: absolute;
	left: 50%; top: 0;
	z-index: 7;
	display: grid;
	place-items: center;
	width: 46px; height: 46px;
	color: #fff;
	background: var(--blue-600);
	border-radius: 50%;
	transform: translate(-50%, -50%);
	box-shadow: var(--sh-blue);
	animation: odc-bob 2.8s var(--ease) infinite;
}
.odc-facts__cue:hover { color: #fff; }
.odc-facts__card {
	display: grid;
	grid-template-columns: repeat(4, 1fr);
	background: var(--white);
	border-radius: var(--r-lg);
	box-shadow: var(--sh-xl);
	overflow: hidden;
}
.odc-fact {
	position: relative;
	padding: clamp(1.5rem, 1rem + 1.6vw, 2.4rem) clamp(1rem, .6rem + 1.2vw, 1.9rem);
	text-align: center;
}
.odc-fact + .odc-fact::before {
	content: '';
	position: absolute;
	inset-inline-start: 0; top: 22%;
	width: 1px; height: 56%;
	background: linear-gradient(to bottom, transparent, var(--line-strong), transparent);
}
.odc-fact__icon {
	display: inline-grid;
	place-items: center;
	width: 44px; height: 44px;
	margin-bottom: .8rem;
	color: var(--blue-600);
	background: var(--blue-50);
	border-radius: var(--r-sm);
	transition: transform var(--dur) var(--ease-spring), background var(--dur) var(--ease), color var(--dur) var(--ease);
}
.odc-fact:hover .odc-fact__icon { color: #fff; background: var(--blue-600); transform: translateY(-3px) scale(1.06); }
.odc-fact__value {
	font-family: var(--font-display);
	font-size: clamp(1.85rem, 1.3rem + 1.9vw, 2.8rem);
	font-weight: 700;
	line-height: 1;
	letter-spacing: -.04em;
	background: linear-gradient(160deg, var(--blue-600), var(--blue-400));
	-webkit-background-clip: text;
	background-clip: text;
	color: transparent;
	font-variant-numeric: tabular-nums;
}
.odc-fact__label {
	margin-top: .5rem;
	font-size: .74rem;
	font-weight: 700;
	letter-spacing: .1em;
	text-transform: uppercase;
	color: var(--text-strong);
}
.odc-fact__sub { margin-top: .25rem; font-size: .8rem; color: var(--text-muted); }

@media (max-width: 767px) {
	.odc-facts__card { grid-template-columns: 1fr 1fr; }
	.odc-fact:nth-child(3)::before, .odc-fact:nth-child(2n + 1)::before { display: none; }
	.odc-fact:nth-child(n + 3) { border-top: 1px solid var(--line); }
}

/* == 10. À propos ========================================================== */

.odc-about__grid {
	display: grid;
	grid-template-columns: minmax(0, 1.02fr) minmax(0, 1fr);
	gap: clamp(2rem, 1rem + 4vw, 4.5rem);
	align-items: center;
}

.odc-about__media { position: relative; }
.odc-about__frame {
	position: relative;
	border-radius: var(--r-lg);
	overflow: hidden;
	box-shadow: var(--sh-xl);
	transform: perspective(1400px) rotateY(3deg) rotateX(1.2deg);
	transition: transform var(--dur-slow) var(--ease);
}
.odc-about__media:hover .odc-about__frame { transform: perspective(1400px) rotateY(0) rotateX(0) translateY(-6px); }
.odc-about__frame img { aspect-ratio: 4 / 3.1; object-fit: cover; transition: transform 1.1s var(--ease); }
.odc-about__media:hover .odc-about__frame img { transform: scale(1.05); }
.odc-about__frame::after {
	content: '';
	position: absolute;
	inset: 0;
	background: linear-gradient(to top, rgba(4, 7, 15, .55), transparent 55%);
}
.odc-about .odc-dots { inset-inline-end: -32px; bottom: -32px; z-index: -1; }

/* Étiquette flottante sur l'image. */
.odc-about__tag {
	position: absolute;
	inset-inline-start: clamp(1rem, 3%, 1.6rem);
	bottom: clamp(1rem, 3%, 1.6rem);
	z-index: 2;
	display: flex;
	align-items: center;
	gap: .8rem;
	padding: .7rem 1.1rem .7rem .75rem;
	color: #fff;
	background: rgba(4, 7, 15, .5);
	border-radius: var(--r-pill);
	box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .18);
	-webkit-backdrop-filter: blur(16px);
	backdrop-filter: blur(16px);
}
.odc-about__tag strong { display: block; font-size: .88rem; font-weight: 600; }
.odc-about__tag span { font-size: .74rem; color: rgba(226, 235, 248, .68); }
.odc-about__tag i {
	display: grid;
	place-items: center;
	width: 34px; height: 34px;
	color: #fff;
	background: var(--blue-600);
	border-radius: 50%;
}

.odc-about__actions { display: flex; flex-wrap: wrap; gap: .7rem; margin-top: 2rem; }

.odc-reasons { display: grid; grid-template-columns: 1fr 1fr; gap: .7rem; margin-top: 2rem; }
.odc-reason {
	display: flex;
	align-items: flex-start;
	gap: .75rem;
	padding: .95rem 1rem;
	background: var(--surface-2);
	border-radius: var(--r-sm);
	box-shadow: inset 0 0 0 1px transparent;
	transition: background var(--dur) var(--ease), box-shadow var(--dur) var(--ease), transform var(--dur) var(--ease);
}
.odc-reason:hover {
	background: var(--white);
	transform: translateY(-2px);
	box-shadow: var(--sh-md), inset 0 0 0 1px var(--blue-100);
}
.odc-reason svg { flex: 0 0 auto; margin-top: .12rem; color: var(--blue-600); }
.odc-reason strong { display: block; font-size: .89rem; font-weight: 600; color: var(--text-strong); line-height: 1.35; }
.odc-reason p { margin-top: .2rem; font-size: .82rem; color: var(--text-muted); line-height: 1.5; }

@media (max-width: 899px) {
	.odc-about__grid { grid-template-columns: 1fr; }
	.odc-about__frame { transform: none; }
	.odc-reasons { grid-template-columns: 1fr; }
}

/* == 11. Services ========================================================== */

.odc-services__grid {
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(min(100%, 320px), 1fr));
	gap: clamp(1rem, .6rem + 1.2vw, 1.6rem);
}

.odc-card {
	--spot-x: 50%;
	--spot-y: 0%;
	position: relative;
	display: flex;
	flex-direction: column;
	background: var(--white);
	border-radius: var(--r-lg);
	box-shadow: var(--sh-sm), inset 0 0 0 1px var(--line);
	overflow: hidden;
	isolation: isolate;
	transition: transform var(--dur) var(--ease), box-shadow var(--dur) var(--ease);
}
/* Halo qui suit le curseur : la carte réagit à la position exacte de la souris. */
.odc-card::before {
	content: '';
	position: absolute;
	inset: 0;
	z-index: 3;
	background: radial-gradient(340px circle at var(--spot-x) var(--spot-y), rgba(37, 112, 224, .1), transparent 62%);
	opacity: 0;
	transition: opacity var(--dur) var(--ease);
	pointer-events: none;
}
.odc-card:hover { transform: translateY(-6px); box-shadow: var(--sh-lg), inset 0 0 0 1px var(--blue-200); }
.odc-card:hover::before { opacity: 1; }

.odc-card__media { position: relative; overflow: hidden; }
.odc-card__media img {
	aspect-ratio: 16 / 10.5;
	width: 100%;
	object-fit: cover;
	transition: transform 1s var(--ease), filter var(--dur) var(--ease);
}
.odc-card:hover .odc-card__media img { transform: scale(1.07); }
.odc-card__media::after {
	content: '';
	position: absolute;
	inset: 0;
	background: linear-gradient(to top, rgba(4, 7, 15, .72), rgba(4, 7, 15, .1) 55%, transparent);
}

.odc-card__num {
	position: absolute;
	top: 1rem; inset-inline-end: 1.1rem;
	z-index: 2;
	font-family: var(--font-display);
	font-size: .82rem;
	font-weight: 700;
	letter-spacing: .04em;
	color: rgba(255, 255, 255, .55);
}
.odc-card__badge {
	position: absolute;
	top: 1rem; inset-inline-start: 1.1rem;
	z-index: 2;
	padding: .3rem .7rem;
	font-size: .64rem;
	font-weight: 700;
	letter-spacing: .1em;
	text-transform: uppercase;
	color: var(--blue-100);
	background: rgba(15, 82, 186, .55);
	border-radius: var(--r-pill);
	box-shadow: inset 0 0 0 1px rgba(133, 180, 251, .35);
	-webkit-backdrop-filter: blur(10px);
	backdrop-filter: blur(10px);
}

/* La pastille chevauche le bas du média. Elle est rendue dans `__body` et non
   dans `__media` : ce dernier porte `overflow: hidden` — indispensable au zoom
   de l'image au survol — et rognait donc net la moitié qui déborde. Le débord
   était dans l'intention du départ, il n'a jamais été visible ; l'icône SVG de
   22 px, centrée, tenait par chance juste au-dessus du trait de coupe, et
   l'objet 3D, qui occupe toute la pastille, l'a révélé. */
.odc-card__icon {
	position: absolute;
	inset-inline-start: 1.25rem; top: -26px;
	z-index: 2;
	display: grid;
	place-items: center;
	width: 56px; height: 56px;
	color: var(--blue-600);
	background: var(--white);
	border-radius: 16px;
	box-shadow: var(--sh-md);
	transition: transform var(--dur) var(--ease-spring), background var(--dur) var(--ease), color var(--dur) var(--ease);
}
/* L'objet 3D garde sa marge dans la pastille : à ras bord, ses reflets touchent
   l'arrondi et la pastille cesse de se lire comme un support. */
.odc-card__icon .odc-i3d { width: 44px; }
.odc-card:hover .odc-card__icon {
	color: #fff;
	background: linear-gradient(150deg, var(--blue-500), var(--blue-700));
	transform: rotate(-6deg) scale(1.08);
}

/* `position: relative` sert d'ancre à `.odc-card__icon`, qui remonte de 26 px
   au-dessus du corps pour chevaucher le média. */
.odc-card__body { position: relative; display: flex; flex-direction: column; flex: 1; padding: 2.2rem 1.35rem 1.35rem; }
.odc-card__title {
	font-size: var(--fs-h4);
	font-weight: 600;
	letter-spacing: -.02em;
	color: var(--blue-700);
	transition: color var(--dur-fast) var(--ease);
}
.odc-card:hover .odc-card__title { color: var(--blue-500); }
.odc-card__lead { margin-top: .55rem; font-size: .87rem; line-height: 1.6; color: var(--text-muted); }

.odc-card__items { margin-top: 1rem; display: grid; gap: .38rem; }
.odc-card__items li {
	display: flex;
	align-items: flex-start;
	gap: .5rem;
	font-size: .83rem;
	line-height: 1.45;
	color: var(--text-body);
}
.odc-card__items svg { flex: 0 0 auto; margin-top: .18rem; color: var(--blue-400); }

.odc-card__foot {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 1rem;
	margin-top: auto;
	padding-top: 1.2rem;
}
.odc-card__cta {
	display: inline-flex;
	align-items: center;
	gap: .45rem;
	font-size: .8rem;
	font-weight: 600;
	color: var(--blue-600);
}
.odc-card__arrow {
	display: grid;
	place-items: center;
	width: 38px; height: 38px;
	color: var(--blue-600);
	background: var(--blue-50);
	border-radius: 50%;
	transition: transform var(--dur) var(--ease-spring), background var(--dur) var(--ease), color var(--dur) var(--ease);
}
.odc-card:hover .odc-card__arrow { color: #fff; background: var(--blue-600); transform: translateX(3px) scale(1.06); }

/*
 * Toute la carte est cliquable, mais un seul lien la couvre : un `::after`
 * étendu au conteneur. Deux liens superposés — l'un sur le titre, l'autre sur
 * la flèche — donneraient deux entrées identiques dans la liste des liens d'un
 * lecteur d'écran, et deux tabulations pour la même destination.
 */
.odc-card__link {
	display: flex;
	flex: 1;
	align-items: center;
	justify-content: space-between;
	gap: 1rem;
	color: inherit;
}
.odc-card__link::after {
	content: '';
	position: absolute;
	inset: 0;
	z-index: 3;
	border-radius: inherit;
}
.odc-card:focus-within { box-shadow: var(--sh-lg), inset 0 0 0 2px var(--blue-500); }
.odc-card__link:focus-visible { outline: 0; }

.odc-services__more {
	display: flex;
	flex-wrap: wrap;
	gap: .7rem;
	justify-content: center;
	margin-top: clamp(1.8rem, 1.2rem + 2vw, 2.8rem);
}

/* Formulaire de recherche (page de résultats, 404). */
.odc-search { display: flex; flex-wrap: wrap; gap: .6rem; align-items: flex-start; }
.odc-search .odc-field { flex: 1 1 14rem; }

/* == 12. La clinique en images ============================================= */

/* Les seules photos réelles du site, et les plus petites : 382 px de large.
   Toute la mise en page les maintient sous ~260 px d'affichage, où cette
   définition reste nette. Ne pas les agrandir sans fichiers d'origine. */

.odc-gallery { overflow: hidden; }
.odc-gallery__dots { top: -30px; inset-inline-end: -46px; }

.odc-gallery__grid {
	display: grid;
	grid-template-columns: repeat(5, minmax(0, 1fr));
	gap: clamp(.6rem, .35rem + .8vw, 1.15rem);
}

/* Cinq portraits alignés au cordeau font planche-contact : le décalage d'une
   vignette sur deux leur rend un rythme. */
.odc-gallery__item:nth-child(even) { margin-top: clamp(1rem, .4rem + 1.8vw, 2.6rem); }

.odc-gallery__card {
	position: relative;
	margin: 0;
	overflow: hidden;
	isolation: isolate;
	border-radius: var(--r-lg);
	box-shadow: var(--sh-md), inset 0 0 0 1px var(--line);
	transition: transform var(--dur) var(--ease), box-shadow var(--dur) var(--ease);
}
.odc-gallery__card:hover { transform: translateY(-6px); box-shadow: var(--sh-lg), inset 0 0 0 1px var(--blue-200); }

.odc-gallery__card img {
	width: 100%;
	aspect-ratio: 3 / 4;
	object-fit: cover;
	transition: transform 1.1s var(--ease);
}
.odc-gallery__card:hover img { transform: scale(1.06); }

/* Voile permanent et non au survol : la légende doit rester lisible au tactile. */
.odc-gallery__card::after {
	content: '';
	position: absolute;
	inset: 0;
	z-index: 1;
	background: linear-gradient(to top, rgba(4, 7, 15, .84), rgba(4, 7, 15, .2) 44%, transparent 70%);
	pointer-events: none;
}

.odc-gallery__cap {
	position: absolute;
	inset: auto 0 0 0;
	z-index: 2;
	padding: 1rem .95rem .95rem;
	color: #fff;
}
.odc-gallery__label {
	display: block;
	font-family: var(--font-display);
	font-size: .93rem;
	font-weight: 600;
	line-height: 1.2;
	letter-spacing: -.015em;
}
.odc-gallery__text {
	display: block;
	margin-top: .28rem;
	font-size: .74rem;
	line-height: 1.45;
	color: rgba(226, 235, 248, .78);
}

/*
 * Sous 1024 px, cinq colonnes deviendraient illisibles et un repli en grille
 * laisserait une rangée orpheline (3+2, puis 2+2+1). Rail à défilement horizontal :
 * il déborde jusqu'aux bords de l'écran pour que la vignette coupée signale
 * elle-même qu'il y a une suite.
 */
@media (max-width: 1023px) {
	.odc-gallery__grid {
		display: flex;
		gap: .8rem;
		margin-inline: calc(var(--gutter) * -1);
		padding: .4rem var(--gutter) 1rem;
		overflow-x: auto;
		overscroll-behavior-x: contain;
		scroll-snap-type: x mandatory;
		scroll-padding-inline: var(--gutter);
		scrollbar-width: thin;
	}
	.odc-gallery__item {
		flex: 0 0 clamp(198px, 54vw, 262px);
		margin-top: 0;
		scroll-snap-align: center;
	}
	.odc-gallery__item:nth-child(even) { margin-top: 0; }
}

/* == 13. Technologie ======================================================= */

.odc-tech { position: relative; overflow: hidden; }
.odc-tech .odc-glow--a { top: -20%; right: -12%; width: 46vw; height: 46vw; opacity: .28; }
.odc-tech .odc-glow--b { left: -14%; bottom: -22%; width: 40vw; height: 40vw; opacity: .22; }

.odc-tech__grid {
	position: relative;
	display: grid;
	grid-template-columns: minmax(0, 1fr) minmax(0, 1.06fr);
	gap: clamp(2rem, 1rem + 4vw, 4.5rem);
	align-items: center;
}

.odc-steps { display: grid; gap: .1rem; margin-top: 2rem; }
.odc-step {
	position: relative;
	display: flex;
	gap: 1.1rem;
	padding: 1.05rem 0;
}
/* Fil conducteur reliant les étapes du flux numérique. */
.odc-step::before {
	content: '';
	position: absolute;
	inset-inline-start: 21px; top: 46px; bottom: -8px;
	width: 1px;
	background: linear-gradient(to bottom, rgba(133, 180, 251, .4), transparent);
}
.odc-step:last-child::before { display: none; }
.odc-step__icon {
	position: relative;
	display: grid;
	place-items: center;
	flex: 0 0 auto;
	width: 43px; height: 43px;
	color: var(--blue-200);
	background: rgba(37, 112, 224, .16);
	border-radius: 13px;
	box-shadow: inset 0 0 0 1px rgba(133, 180, 251, .26);
	transition: transform var(--dur) var(--ease-spring), background var(--dur) var(--ease), color var(--dur) var(--ease);
}
.odc-step:hover .odc-step__icon {
	color: #fff;
	background: var(--blue-600);
	transform: scale(1.08);
	box-shadow: var(--sh-blue);
}
.odc-step strong { display: block; font-size: 1rem; font-weight: 600; color: #fff; }
.odc-step p { margin-top: .3rem; font-size: .87rem; line-height: 1.6; color: var(--text-invert-soft); }

.odc-tech__media { position: relative; }
.odc-tech__frame {
	position: relative;
	border-radius: var(--r-lg);
	overflow: hidden;
	box-shadow: 0 40px 90px -30px rgba(0, 0, 0, .8), inset 0 0 0 1px var(--line-invert);
}
.odc-tech__frame img { aspect-ratio: 16 / 11; object-fit: cover; }
.odc-tech__frame::after {
	content: '';
	position: absolute;
	inset: 0;
	background: linear-gradient(200deg, rgba(37, 112, 224, .16), transparent 55%);
}
/* Ligne de balayage, clin d'œil au scanner. */
.odc-tech__scan {
	position: absolute;
	left: 0; right: 0; top: 0;
	height: 2px;
	background: linear-gradient(90deg, transparent, var(--blue-300), transparent);
	box-shadow: 0 0 24px 4px rgba(133, 180, 251, .5);
	animation: odc-scan 5.5s var(--ease) infinite;
}
@keyframes odc-scan {
	0%, 100% { transform: translateY(0); opacity: 0; }
	10%      { opacity: 1; }
	90%      { opacity: 1; }
	100%     { transform: translateY(100%); }
}

@media (max-width: 899px) {
	.odc-tech__grid { grid-template-columns: 1fr; }
}

/* == 14. Prévention ======================================================== */

.odc-prev__grid {
	display: grid;
	grid-template-columns: minmax(0, .85fr) minmax(0, 1.15fr);
	gap: clamp(2rem, 1rem + 3vw, 3.5rem);
	align-items: start;
}
.odc-prev__list { display: grid; gap: .7rem; }
.odc-prev__item {
	display: flex;
	gap: 1rem;
	padding: 1.15rem 1.25rem;
	background: var(--white);
	border-radius: var(--r-md);
	box-shadow: var(--sh-sm), inset 0 0 0 1px var(--line);
	transition: transform var(--dur) var(--ease), box-shadow var(--dur) var(--ease);
}
.odc-prev__item:hover { transform: translateX(5px); box-shadow: var(--sh-md), inset 0 0 0 1px var(--blue-200); }
.odc-prev__item > svg {
	flex: 0 0 auto;
	width: 40px; height: 40px;
	padding: 8px;
	color: var(--blue-600);
	background: var(--blue-50);
	border-radius: 12px;
	box-sizing: content-box;
}
.odc-prev__item strong { display: block; font-size: .96rem; font-weight: 600; color: var(--text-strong); }
.odc-prev__item p { margin-top: .3rem; font-size: .86rem; line-height: 1.6; color: var(--text-muted); }

.odc-prev__media { position: sticky; top: calc(var(--header-h) + 2rem); }
.odc-prev__media .odc-about__frame img { aspect-ratio: 4 / 3.4; }

@media (max-width: 899px) {
	.odc-prev__grid { grid-template-columns: 1fr; }
	.odc-prev__media { position: static; order: -1; }
}

/* == 15. Contact et localisation =========================================== */

.odc-contact__grid {
	display: grid;
	grid-template-columns: minmax(0, .92fr) minmax(0, 1.08fr);
	gap: clamp(1.2rem, .6rem + 2vw, 2rem);
	align-items: stretch;
}

.odc-info {
	position: relative;
	display: flex;
	flex-direction: column;
	padding: clamp(1.6rem, 1rem + 2vw, 2.6rem);
	overflow: hidden;
	color: var(--text-invert-soft);
	background: linear-gradient(155deg, var(--ink-700), var(--ink-900) 60%);
	border-radius: var(--r-lg);
	box-shadow: var(--sh-xl);
	isolation: isolate;
}
.odc-info .odc-glow--a { top: -30%; right: -25%; width: 60%; height: 60%; opacity: .3; z-index: -1; }
.odc-info h3 { font-size: var(--fs-h3); color: #fff; }
.odc-info__lead { margin-top: .7rem; font-size: .92rem; color: var(--text-invert-soft); }

.odc-info__list { display: grid; gap: .2rem; margin-top: 1.8rem; }
.odc-info__row {
	display: flex;
	align-items: flex-start;
	gap: .9rem;
	padding: .8rem 0;
	border-bottom: 1px solid var(--line-invert);
}
.odc-info__row:last-child { border-bottom: 0; }
.odc-info__row > svg { flex: 0 0 auto; margin-top: .15rem; color: var(--blue-300); }
.odc-info__row > dl { min-width: 0; }
.odc-info__row--wide > dl { flex: 1; }
.odc-info__row dt {
	font-size: .68rem;
	font-weight: 700;
	letter-spacing: .12em;
	text-transform: uppercase;
	color: rgba(226, 235, 248, .62);
}
.odc-info__row dd { margin: .2rem 0 0; font-size: .95rem; color: #fff; }
.odc-info__row dd a { color: #fff; }
.odc-info__row dd a:hover { color: var(--blue-300); }

/* Cible tactile de 24 px minimum, WCAG 2.2 · 2.5.8. */
.odc-info__tel {
	display: inline-flex;
	align-items: center;
	min-height: 24px;
	padding-block: 2px;
}

.odc-hours { display: grid; gap: .3rem; }
.odc-hours div { display: flex; justify-content: space-between; gap: 1rem; font-size: .89rem; }
.odc-hours dt { font-size: .89rem !important; font-weight: 500 !important; letter-spacing: 0 !important; text-transform: none !important; color: rgba(226, 235, 248, .72) !important; }
.odc-hours dd { margin: 0 !important; font-variant-numeric: tabular-nums; }
.odc-hours .is-closed dd { color: rgba(226, 235, 248, .6) !important; }

.odc-info__actions { display: grid; gap: .6rem; margin-top: 1.8rem; }

/* -- Formulaire -- */
.odc-form {
	display: flex;
	flex-direction: column;
	padding: clamp(1.6rem, 1rem + 2vw, 2.6rem);
	background: var(--white);
	border-radius: var(--r-lg);
	box-shadow: var(--sh-lg), inset 0 0 0 1px var(--line);
}
.odc-form h3 { font-size: var(--fs-h3); }
.odc-form__lead { margin-top: .6rem; font-size: .9rem; color: var(--text-muted); }
.odc-form__grid { display: grid; grid-template-columns: 1fr 1fr; gap: .9rem; margin-top: 1.6rem; }
.odc-field { position: relative; display: flex; flex-direction: column; }
.odc-field--full { grid-column: 1 / -1; }
.odc-field label {
	margin-bottom: .4rem;
	font-size: .76rem;
	font-weight: 600;
	letter-spacing: .04em;
	color: var(--text-strong);
}
.odc-field label span { color: var(--blue-600); }
.odc-field input, .odc-field select, .odc-field textarea {
	width: 100%;
	padding: .8rem .95rem;
	font: inherit;
	font-size: .92rem;
	color: var(--text-strong);
	background: var(--surface-2);
	border: 1px solid transparent;
	border-radius: var(--r-sm);
	transition: border-color var(--dur-fast) var(--ease), background var(--dur-fast) var(--ease), box-shadow var(--dur-fast) var(--ease);
	appearance: none;
}
.odc-field textarea { min-height: 108px; resize: vertical; }
.odc-field select {
	background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='20' height='20' viewBox='0 0 24 24' fill='none' stroke='%236d7d97' stroke-width='1.6' stroke-linecap='round'%3E%3Cpath d='m6 9.5 6 6 6-6'/%3E%3C/svg%3E");
	background-repeat: no-repeat;
	background-position: right .8rem center;
	padding-inline-end: 2.4rem;
}
.odc-field input:focus, .odc-field select:focus, .odc-field textarea:focus {
	outline: 0;
	background: var(--white);
	border-color: var(--blue-400);
	box-shadow: 0 0 0 4px rgba(37, 112, 224, .12);
}
.odc-field.has-error input, .odc-field.has-error textarea { border-color: #d94a4a; background: #fdf3f3; }
.odc-field__error { margin-top: .3rem; font-size: .76rem; color: #c33b3b; }

.odc-field--consent { margin-top: 1.1rem; }
.odc-field--consent.has-error .odc-form__consent { color: #c33b3b; }
.odc-field--consent.has-error input[type='checkbox'] { outline: 2px solid #d94a4a; outline-offset: 2px; }
.odc-form__consent { display: flex; gap: .6rem; font-size: .78rem; line-height: 1.5; color: var(--text-muted); cursor: pointer; }
.odc-form__consent a { text-decoration: underline; text-underline-offset: 2px; }
.odc-form__consent input { flex: 0 0 auto; width: 17px; height: 17px; margin-top: .1rem; accent-color: var(--blue-600); }
.odc-form__submit { margin-top: 1.3rem; }
.odc-form__note { margin-top: .9rem; font-size: .76rem; color: var(--text-muted); }

.odc-form__msg {
	display: none;
	gap: .6rem;
	margin-top: 1.1rem;
	padding: .9rem 1.05rem;
	font-size: .87rem;
	border-radius: var(--r-sm);
}
.odc-form__msg.is-ok { display: flex; color: #0d6b46; background: #e8f8f0; box-shadow: inset 0 0 0 1px #b6e6cd; }
.odc-form__msg.is-ko { display: flex; color: #a4302e; background: #fdeeee; box-shadow: inset 0 0 0 1px #f4c9c8; }

/*
 * Champ leurre anti-robot.
 *
 * Masqué par découpe, PAS par un déport hors écran.
 *
 * `left: -9999px` fonctionnait tant que le site n'existait qu'en français : le
 * navigateur ne défile pas au-delà de l'origine, donc le débord restait
 * invisible. Passé en propriété logique, il devient `right: -9999px` en arabe —
 * soit 9999 px de débord DANS le sens du défilement. La page entière se
 * décalait, le titre du hero sortait du cadre et une barre de défilement
 * horizontale apparaissait sur toutes les pages arabes.
 *
 * La découpe n'a pas de sens de lecture : elle masque à l'identique dans les
 * trois langues, sans rien ajouter à la surface du document. Le leurre reste
 * dans le DOM et rempli par un robot, ce qui est tout son objet.
 */
.odc-hp {
	position: absolute;
	width: 1px; height: 1px;
	margin: -1px; padding: 0;
	overflow: hidden;
	clip-path: inset(50%);
	white-space: nowrap;
	opacity: 0;
	pointer-events: none;
}

/* -- Carte -- */
.odc-map {
	position: relative;
	margin-top: clamp(1.2rem, .6rem + 2vw, 2rem);
	aspect-ratio: 21 / 8;
	border-radius: var(--r-lg);
	overflow: hidden;
	box-shadow: var(--sh-lg), inset 0 0 0 1px var(--line);
	background: var(--surface-3);
}
.odc-map iframe { width: 100%; height: 100%; border: 0; filter: saturate(.85) contrast(1.03); }

/* Façade affichée tant que le visiteur n'a pas demandé la carte Google. */
.odc-map__facade {
	position: relative;
	display: grid;
	place-items: center;
	height: 100%;
	padding: var(--gutter);
	overflow: hidden;
	color: var(--text-invert-soft);
	background: linear-gradient(155deg, var(--ink-700), var(--ink-900) 70%);
}
.odc-map__grid {
	position: absolute;
	inset: 0;
	background-image:
		linear-gradient(var(--line-invert) 1px, transparent 1px),
		linear-gradient(90deg, var(--line-invert) 1px, transparent 1px);
	background-size: 46px 46px;
	mask-image: radial-gradient(ellipse at 50% 50%, #000 20%, transparent 76%);
	-webkit-mask-image: radial-gradient(ellipse at 50% 50%, #000 20%, transparent 76%);
}
.odc-map__body { position: relative; display: grid; justify-items: center; gap: .9rem; text-align: center; }
.odc-map__pin {
	display: grid;
	place-items: center;
	width: 54px; height: 54px;
	color: var(--blue-300);
	background: rgba(79, 144, 243, .14);
	border-radius: 50%;
	box-shadow: inset 0 0 0 1px rgba(133, 180, 251, .3);
}
.odc-map__addr { font-size: var(--fs-small); line-height: 1.55; }
.odc-map__addr strong {
	display: block;
	margin-bottom: .2rem;
	font-family: var(--font-display);
	font-size: var(--fs-body);
	color: #fff;
}
.odc-map__actions { display: flex; flex-wrap: wrap; gap: .6rem; justify-content: center; }
/* .62 plutôt que .5 : à .5 le rapport tient de justesse (4,63:1) pour une
   mention de 11,5 px lue en diagonale. .62 le porte à 6,5:1. */
.odc-map__note { max-width: 40ch; font-size: .72rem; color: rgba(226, 235, 248, .62); }

@media (max-width: 899px) {
	.odc-contact__grid { grid-template-columns: 1fr; }
	.odc-map { aspect-ratio: 4 / 3; }
}
@media (max-width: 560px) {
	.odc-form__grid { grid-template-columns: 1fr; }
}

/* == 16. Bandeau d'appel =================================================== */

.odc-cta { position: relative; overflow: hidden; background: var(--ink-900); }
.odc-cta__inner {
	position: relative;
	display: grid;
	grid-template-columns: auto minmax(0, 1fr) auto;
	gap: clamp(1.5rem, 1rem + 3vw, 3.5rem);
	align-items: center;
	padding: clamp(2.2rem, 1.5rem + 3vw, 3.6rem) clamp(1.5rem, 1rem + 3vw, 3.5rem);
	background: linear-gradient(115deg, var(--blue-700), var(--blue-600) 42%, var(--blue-800));
	border-radius: var(--r-xl);
	box-shadow: 0 40px 90px -34px rgba(15, 82, 186, .7);
	isolation: isolate;
	overflow: hidden;
}
.odc-cta__inner .odc-noise { opacity: .07; }
.odc-cta__glow {
	position: absolute;
	inset: -40% -10% auto auto;
	z-index: -1;
	width: 60%; aspect-ratio: 1;
	background: radial-gradient(circle, rgba(255, 255, 255, .3), transparent 62%);
	filter: blur(40px);
}
.odc-cta__art { position: relative; width: clamp(96px, 12vw, 168px); }
.odc-cta__art img {
	border-radius: var(--r-lg);
	mix-blend-mode: screen;
	animation: odc-float 7s var(--ease) infinite;
}
@keyframes odc-float {
	0%, 100% { transform: translateY(0) rotate(0); }
	50%      { transform: translateY(-12px) rotate(2deg); }
}
.odc-cta h2 { font-size: clamp(1.5rem, 1.15rem + 1.5vw, 2.35rem); color: #fff; }
.odc-cta p { margin-top: .7rem; font-size: var(--fs-body); color: rgba(255, 255, 255, .8); max-width: 52ch; }
.odc-cta__actions { display: grid; gap: .6rem; }

@media (max-width: 899px) {
	.odc-cta__inner { grid-template-columns: 1fr; text-align: left; }
	.odc-cta__art { display: none; }
}

/* == 17. Pied de page ====================================================== */

.odc-footer {
	position: relative;
	padding-top: clamp(3rem, 2rem + 4vw, 5rem);
	color: var(--text-invert-soft);
	background: var(--ink-900);
	overflow: hidden;
}
.odc-footer .odc-grid-bg { opacity: .5; }
.odc-footer__grid {
	position: relative;
	display: grid;
	grid-template-columns: 1.5fr 1fr 1fr 1.3fr;
	gap: clamp(1.6rem, 1rem + 2.5vw, 3.2rem);
	padding-bottom: clamp(2.2rem, 1.5rem + 2vw, 3.4rem);
}
.odc-footer__about { max-width: 32ch; margin-top: 1.2rem; font-size: .87rem; line-height: 1.65; }
.odc-footer h3 {
	margin-bottom: 1.1rem;
	font-family: var(--font-body);
	font-size: .72rem;
	font-weight: 700;
	letter-spacing: .14em;
	text-transform: uppercase;
	color: rgba(255, 255, 255, .55);
}
.odc-footer__list { display: grid; gap: .55rem; }
.odc-footer__list a, .odc-footer__list li {
	font-size: .88rem;
	color: var(--text-invert-soft);
	transition: color var(--dur-fast) var(--ease), transform var(--dur-fast) var(--ease);
}
.odc-footer__list a { display: inline-flex; align-items: center; gap: .45rem; }
.odc-footer__list a:hover { color: #fff; transform: translateX(3px); }
.odc-footer__contact li { display: flex; align-items: flex-start; gap: .65rem; }
.odc-footer__contact svg { flex: 0 0 auto; margin-top: .2rem; color: var(--blue-400); }
/* Cible tactile de 24 px minimum, WCAG 2.2 · 2.5.8. */
.odc-footer__tel { display: flex; align-items: center; min-height: 24px; }

.odc-social { display: flex; gap: .5rem; margin-top: 1.5rem; }
.odc-social a {
	display: grid;
	place-items: center;
	width: 40px; height: 40px;
	color: rgba(255, 255, 255, .78);
	border-radius: 50%;
	box-shadow: inset 0 0 0 1px var(--line-invert);
	transition: color var(--dur) var(--ease), background var(--dur) var(--ease), transform var(--dur) var(--ease-spring);
}
.odc-social a:hover { color: #fff; background: var(--blue-600); transform: translateY(-3px); box-shadow: var(--sh-blue); }

.odc-footer__bar {
	position: relative;
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: space-between;
	gap: .8rem;
	padding-block: 1.4rem;
	font-size: .8rem;
	border-top: 1px solid var(--line-invert);
}
.odc-footer__bar p { color: rgba(226, 235, 248, .55); }
.odc-footer__legal { display: flex; gap: 1.2rem; }
.odc-footer__legal a { color: rgba(226, 235, 248, .55); }
.odc-footer__legal a:hover { color: #fff; }

@media (max-width: 899px) {
	.odc-footer__grid { grid-template-columns: 1fr 1fr; }
}
@media (max-width: 560px) {
	.odc-footer__grid { grid-template-columns: 1fr; }
}

/* -- Rail de contact flottant : appeler / WhatsApp / rendez-vous ------------
   À mi-hauteur du bord droit plutôt qu'en barre basse : les trois actions
   restent visibles dès le premier écran, sur toutes les tailles, et le bas de
   l'écran reste libre pour le bouton « retour en haut ». */
.odc-fab {
	position: fixed;
	top: 50%;
	inset-inline-end: clamp(.6rem, 1.4vw, 1.5rem);
	z-index: 95;
	display: flex;
	flex-direction: column;
	gap: clamp(.6rem, 1vw, .95rem);
	transform: translateY(-50%);
}

.odc-fab__item {
	--fab-size: 52px;
	position: relative;
	display: grid;
	place-items: center;
	width: var(--fab-size); height: var(--fab-size);
	color: #fff;
	background: var(--fab-bg);
	border-radius: 50%;
	/* Anneau translucide de la teinte du bouton : sur les sections claires du
	   site, une ombre seule ne détacherait pas assez la pastille. */
	box-shadow: 0 0 0 6px var(--fab-ring), 0 8px 20px -8px rgba(7, 16, 38, .5);
	transition: transform var(--dur) var(--ease-spring), box-shadow var(--dur) var(--ease);
}
.odc-fab__item:hover,
.odc-fab__item:focus-visible {
	color: #fff;
	transform: scale(1.08);
	box-shadow: 0 0 0 9px var(--fab-ring), 0 12px 26px -8px rgba(7, 16, 38, .55);
}

/* Le rouge et le vert ne viennent pas de la palette de marque : ce sont les
   codes attendus pour « appeler » et « WhatsApp ». Le bleu, lui, est celui du
   logo — le rendez-vous est l'action de la clinique. */
.odc-fab__item--phone    { --fab-bg: #d9463f;         --fab-ring: rgba(217, 70, 63, .18); }
.odc-fab__item--whatsapp { --fab-bg: #25d366;         --fab-ring: rgba(37, 211, 102, .2); }
.odc-fab__item--rdv      { --fab-bg: var(--blue-600); --fab-ring: rgba(15, 82, 186, .18); }

/* Libellé au survol. L'intitulé accessible reste porté par aria-label sur le
   lien : cette étiquette est purement visuelle. */
.odc-fab__tip {
	position: absolute;
	inset-inline-end: calc(100% + .7rem);
	padding: .3rem .62rem;
	font-size: .78rem;
	font-weight: 600;
	color: #fff;
	white-space: nowrap;
	background: rgba(6, 11, 22, .92);
	border-radius: var(--r-xs);
	opacity: 0;
	transform: translateX(6px);
	pointer-events: none;
	transition: opacity var(--dur-fast) var(--ease), transform var(--dur-fast) var(--ease);
}
@media (hover: hover) {
	.odc-fab__item:hover .odc-fab__tip { opacity: 1; transform: none; }
}
.odc-fab__item:focus-visible .odc-fab__tip { opacity: 1; transform: none; }

@media (max-width: 767px) {
	.odc-fab__item { --fab-size: 46px; }
	.odc-fab__tip { display: none; }
}

/* -- Retour en haut -- */
.odc-top {
	position: fixed;
	inset-inline-end: clamp(1rem, 2vw, 1.8rem);
	bottom: clamp(1rem, 2vw, 1.8rem);
	z-index: 96;
	display: grid;
	place-items: center;
	width: 46px; height: 46px;
	color: #fff;
	background: var(--blue-600);
	border-radius: 50%;
	box-shadow: var(--sh-blue);
	opacity: 0;
	visibility: hidden;
	transform: translateY(12px);
	transition: opacity var(--dur) var(--ease), transform var(--dur) var(--ease), visibility var(--dur);
}
.odc-top.is-on { opacity: 1; visibility: visible; transform: none; }
.odc-top:hover { color: #fff; transform: translateY(-3px); }

/* == 18. Pages intérieures ================================================= */

.odc-page-hero {
	position: relative;
	padding-top: calc(var(--header-h) + clamp(3rem, 2rem + 4vw, 6rem));
	padding-bottom: clamp(2.5rem, 2rem + 3vw, 4.5rem);
	color: #fff;
	background: linear-gradient(150deg, var(--ink-700), var(--ink-900));
	overflow: hidden;
}
.odc-page-hero h1 { font-size: clamp(1.9rem, 1.4rem + 2.2vw, 3.2rem); color: #fff; }
.odc-crumbs { display: flex; flex-wrap: wrap; gap: .5rem; margin-bottom: 1rem; font-size: .8rem; color: rgba(226, 235, 248, .6); }
.odc-crumbs a { color: var(--blue-300); }
.odc-crumbs a:hover { color: #fff; }

.odc-prose { max-width: 68ch; }
.odc-prose > * + * { margin-top: 1.15rem; }
.odc-prose h2 { margin-top: 2.4rem; font-size: var(--fs-h3); }
.odc-prose h3 { margin-top: 1.9rem; font-size: var(--fs-h4); }
.odc-prose ul, .odc-prose ol { padding-inline-start: 1.3rem; list-style: disc; }
.odc-prose ol { list-style: decimal; }
.odc-prose li { margin-top: .4rem; }
.odc-prose a { text-decoration: underline; text-underline-offset: 3px; }
.odc-prose blockquote {
	padding: 1rem 1.3rem;
	border-inline-start: 3px solid var(--blue-400);
	background: var(--surface-2);
	border-radius: 0 var(--r-sm) var(--r-sm) 0;
}
.odc-prose img { border-radius: var(--r-md); }

.odc-404 { display: grid; place-items: center; min-height: 62svh; text-align: center; }
.odc-404__code {
	font-family: var(--font-display);
	font-size: clamp(4.5rem, 3rem + 10vw, 10rem);
	font-weight: 700;
	line-height: 1;
	letter-spacing: -.05em;
	background: linear-gradient(160deg, var(--blue-600), var(--blue-300));
	-webkit-background-clip: text;
	background-clip: text;
	color: transparent;
}

.odc-img-missing {
	display: block;
	width: 100%;
	aspect-ratio: 16 / 10;
	background:
		linear-gradient(135deg, var(--surface-3), var(--surface-2)),
		var(--noise);
}

/* == 18b. Questions fréquentes ============================================= */

/*
 * `<details>` natif : le contenu replié reste dans le DOM, donc lisible par un
 * robot qui n'exécute pas de JavaScript. C'est la condition pour qu'un moteur
 * génératif reprenne une réponse — un accordéon qui injecte son texte au clic
 * n'est jamais lu.
 */

.odc-faq__list {
	display: grid;
	gap: .6rem;
	max-width: 46rem;
	margin-inline: auto;
}
.odc-faq--page .odc-faq__list,
.odc-head--start ~ .odc-faq__list { margin-inline: 0; }

.odc-faq__item {
	overflow: hidden;
	background: var(--surface-1);
	border-radius: var(--r-md);
	box-shadow: var(--sh-sm), inset 0 0 0 1px var(--line);
	transition: box-shadow var(--dur) var(--ease);
}
.odc-faq__item:hover { box-shadow: var(--sh-md), inset 0 0 0 1px var(--line-strong); }
.odc-faq__item[open] { box-shadow: var(--sh-md), inset 0 0 0 1px var(--blue-200); }

.odc-faq__q {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 1rem;
	padding: 1.05rem 1.25rem;
	font-family: var(--font-display);
	font-size: var(--fs-body);
	font-weight: 600;
	line-height: 1.35;
	color: var(--text-strong);
	cursor: pointer;
	list-style: none;
}
/* Safari garde son triangle sans ce sélecteur préfixé. */
.odc-faq__q::-webkit-details-marker { display: none; }
.odc-faq__q::marker { content: ''; }

.odc-faq__chevron {
	flex: 0 0 auto;
	display: grid;
	place-items: center;
	width: 28px; height: 28px;
	color: var(--blue-600);
	background: var(--blue-50);
	border-radius: 50%;
	transition: transform var(--dur) var(--ease), background var(--dur) var(--ease);
}
.odc-faq__item[open] .odc-faq__chevron { transform: rotate(180deg); background: var(--blue-100); }

.odc-faq__a {
	padding: 0 1.25rem 1.15rem;
	font-size: var(--fs-small);
	line-height: 1.68;
	color: var(--text-body);
}
.odc-faq__a p { max-width: 62ch; }

.odc-faq__foot { margin-top: 1.6rem; font-size: var(--fs-small); color: var(--text-muted); text-align: center; }
.odc-faq__title { margin-bottom: 1.3rem; font-size: var(--fs-h3); }

/* == 18c. Pages de soins =================================================== */

.odc-page-hero__lead {
	max-width: 52ch;
	margin-top: 1.1rem;
	font-size: var(--fs-lead);
	color: rgba(226, 235, 248, .74);
}
.odc-eyebrow--invert { color: var(--blue-300); }

/*
 * Bloc de réponse directe : la seule zone de la page volontairement typographiée
 * comme une citation. C'est ce que reprennent les moteurs génératifs, et ce que
 * lit un visiteur pressé qui ne descendra pas plus bas.
 */
.odc-answer {
	position: relative;
	padding: clamp(1.3rem, 1rem + 1.4vw, 2rem) clamp(1.2rem, .9rem + 1.4vw, 2rem);
	margin-bottom: clamp(2rem, 1.4rem + 2vw, 3.2rem);
	background: linear-gradient(155deg, var(--blue-50), var(--surface-1) 70%);
	border-radius: var(--r-lg);
	box-shadow: var(--sh-sm), inset 0 0 0 1px var(--blue-100);
}
.odc-answer::before {
	content: '';
	position: absolute;
	inset: 1rem auto 1rem 0;
	width: 3px;
	background: linear-gradient(var(--blue-500), var(--blue-300));
	border-radius: 0 3px 3px 0;
}
.odc-answer__label {
	display: inline-flex;
	align-items: center;
	gap: .45rem;
	margin-bottom: .7rem;
	font-size: var(--fs-eyebrow);
	font-weight: 600;
	letter-spacing: .13em;
	text-transform: uppercase;
	color: var(--blue-600);
}
.odc-answer__text {
	font-size: var(--fs-lead);
	line-height: 1.6;
	color: var(--text-strong);
}

.odc-soin__media { margin: 0 0 clamp(1.6rem, 1rem + 2vw, 2.6rem); }
.odc-soin__media img { border-radius: var(--r-lg); box-shadow: var(--sh-lg); }

.odc-soin__chips {
	display: flex;
	flex-wrap: wrap;
	gap: .5rem;
	margin-bottom: clamp(1.8rem, 1.2rem + 2vw, 2.8rem);
}
.odc-soin__chips li {
	display: inline-flex;
	align-items: center;
	gap: .45rem;
	padding: .5rem .85rem;
	font-size: .8rem;
	font-weight: 500;
	color: var(--text-strong);
	background: var(--surface-2);
	border-radius: var(--r-pill);
	box-shadow: inset 0 0 0 1px var(--line);
}
.odc-soin__chips svg { color: var(--blue-600); }

/*
 * Colonne d'article unique : encadré, image, texte, FAQ et cartes partagent la
 * même largeur. Le `max-width: 68ch` posé sur les seuls paragraphes laissait un
 * bord droit en dents de scie — le texte s'arrêtait 180 px avant les blocs qui
 * l'encadraient. La mesure de lecture est portée par le conteneur, une fois.
 */
.odc-soin .odc-wrap--narrow { max-width: 44rem; }
.odc-prose--wide { max-width: none; }
.odc-soin__block + .odc-soin__block { margin-top: clamp(2rem, 1.5rem + 1.6vw, 3rem); }
.odc-soin__block h2 { margin-top: 0; }
.odc-soin__block > * + * { margin-top: 1.1rem; }

.odc-faq--page { margin-top: clamp(2.4rem, 1.8rem + 2vw, 3.6rem); }

.odc-disclaimer {
	display: flex;
	gap: .7rem;
	margin-top: clamp(2rem, 1.4rem + 2vw, 3rem);
	padding: 1rem 1.15rem;
	font-size: .8rem;
	line-height: 1.6;
	color: var(--text-muted);
	background: var(--surface-2);
	border-radius: var(--r-md);
	box-shadow: inset 0 0 0 1px var(--line);
}
.odc-disclaimer svg { flex: 0 0 auto; margin-top: .15rem; color: var(--blue-600); }

/* -- Fiche du praticien -- */

.odc-cv__card {
	margin-top: clamp(1.4rem, 1rem + 1.2vw, 2rem);
	padding: clamp(1.2rem, .9rem + 1.2vw, 1.7rem);
	background: var(--surface-1);
	border-radius: var(--r-lg);
	box-shadow: var(--sh-sm), inset 0 0 0 1px var(--line);
}
.odc-cv__card--reg { background: linear-gradient(155deg, var(--blue-50), var(--surface-1) 70%); box-shadow: var(--sh-sm), inset 0 0 0 1px var(--blue-100); }

.odc-cv__titre {
	display: flex;
	align-items: center;
	gap: .7rem;
	margin-bottom: 1rem;
	font-size: var(--fs-h4);
}
.odc-cv__ico {
	display: grid;
	place-items: center;
	width: 34px; height: 34px;
	color: var(--blue-600);
	background: var(--blue-50);
	border-radius: var(--r-sm);
}
.odc-cv__card--reg .odc-cv__ico { background: var(--white); }

.odc-cv__liste { display: grid; gap: .55rem; }
.odc-cv__liste li { display: flex; gap: .6rem; font-size: var(--fs-small); line-height: 1.6; }
.odc-cv__liste svg { flex: 0 0 auto; margin-top: .28rem; color: var(--blue-500); }

.odc-cv__reg { display: grid; gap: .8rem; }
.odc-cv__reg div { display: flex; flex-wrap: wrap; justify-content: space-between; gap: .4rem 1.5rem; }
.odc-cv__reg dt { font-size: var(--fs-small); font-weight: 500; color: var(--text-muted); }
.odc-cv__reg dd { margin: 0; font-weight: 600; font-variant-numeric: tabular-nums; color: var(--text-strong); }

/* -- Soins associés -- */
.odc-related { margin-top: clamp(2.4rem, 1.8rem + 2vw, 3.6rem); }
.odc-related--index { margin-top: clamp(1.6rem, 1.2rem + 1.4vw, 2.4rem); }
.odc-related--index + .odc-prose { margin-top: clamp(2.4rem, 1.8rem + 2vw, 3.6rem); }
.odc-related__title { margin-bottom: 1.2rem; font-size: var(--fs-h3); }
.odc-related__grid { display: grid; gap: .7rem; }
.odc-related--index .odc-related__grid { gap: .8rem; }

.odc-related__card {
	display: grid;
	grid-template-columns: auto minmax(0, 1fr) auto;
	align-items: center;
	gap: 1rem;
	padding: 1.1rem 1.25rem;
	color: var(--text-body);
	background: var(--surface-1);
	border-radius: var(--r-md);
	box-shadow: var(--sh-sm), inset 0 0 0 1px var(--line);
	transition: transform var(--dur) var(--ease), box-shadow var(--dur) var(--ease);
}
.odc-related__card:hover {
	color: var(--text-body);
	transform: translateY(-3px);
	box-shadow: var(--sh-md), inset 0 0 0 1px var(--blue-200);
}
.odc-related__card strong {
	display: block;
	font-family: var(--font-display);
	font-size: var(--fs-body);
	font-weight: 600;
	color: var(--text-strong);
}
.odc-related__card strong + span { display: block; margin-top: .25rem; font-size: .82rem; line-height: 1.5; color: var(--text-muted); }
.odc-related__card > svg:last-child { color: var(--blue-600); transition: transform var(--dur) var(--ease); }
.odc-related__card:hover > svg:last-child { transform: translateX(4px); }

.odc-related__icon {
	display: grid;
	place-items: center;
	width: 42px; height: 42px;
	color: var(--blue-600);
	background: var(--blue-50);
	border-radius: var(--r-sm);
}
.odc-related__card--alert .odc-related__icon { color: #b4451f; background: #fdefe7; }
.odc-related__card--alert:hover { box-shadow: var(--sh-md), inset 0 0 0 1px #f3cdb9; }

@media (max-width: 560px) {
	.odc-related__card { grid-template-columns: auto minmax(0, 1fr); gap: .8rem; }
	.odc-related__card > svg:last-child { display: none; }
}

/* == 19. Animations d'apparition =========================================== */

[data-reveal] {
	opacity: 0;
	transform: translateY(26px);
	transition:
		opacity .85s var(--ease-out) var(--reveal-delay, 0ms),
		transform .85s var(--ease-out) var(--reveal-delay, 0ms),
		filter .85s var(--ease-out) var(--reveal-delay, 0ms);
	filter: blur(6px);
	will-change: opacity, transform;
}
[data-reveal].is-in { opacity: 1; transform: none; filter: none; }

[data-reveal='left']  { transform: translateX(-34px); }
[data-reveal='right'] { transform: translateX(34px); }
[data-reveal='scale'] { transform: scale(.94); }
[data-reveal='left'].is-in,
[data-reveal='right'].is-in,
[data-reveal='scale'].is-in { transform: none; }

/* Le JS ne fait qu'ajouter .is-in : sans JS, tout reste visible. */
.no-js [data-reveal] { opacity: 1; transform: none; filter: none; }

/* == 20. Univers 3D — objets rendus ========================================
   Les visuels produits par `_tools/icons-batch.sh` sont des PNG/WebP détourés
   avec leur propre ombre et leurs propres reflets. Tout ce qui suit ne fait que
   les mettre en mouvement : aucun filtre de couleur n'est appliqué dessus, ce
   qui les garderait cohérents entre eux mais coûterait un repaint par image.
   ========================================================================= */

.odc-i3d {
	display: block;
	width: 100%;
	height: auto;
	/* L'ombre est portée par le rendu 3D lui-même. Celle-ci n'ajoute qu'un
	   contact très doux, pour décoller l'objet des fonds clairs unis. */
	filter: drop-shadow(0 10px 18px rgba(10, 39, 87, .16));
	transform: translateZ(0);
}

.odc-section--dark .odc-i3d,
.odc-hero .odc-i3d,
.odc-footer .odc-i3d {
	/* Sur fond sombre, une ombre bleutée lit l'objet comme un halo plutôt que
	   comme une salissure — une ombre neutre y apparaît grise et sale. */
	filter: drop-shadow(0 12px 26px rgba(4, 12, 30, .55))
	        drop-shadow(0 0 22px rgba(79, 144, 243, .22));
}

/* --- Mouvements d'objet ---------------------------------------------------
   Chaque modificateur lit `--f-dur` et `--f-delay`, posés en style inline par
   le gabarit. Deux icônes voisines qui flottent en phase font mécanique ; c'est
   le décalage qui fait vivant, et il ne coûte rien. */

@keyframes odc-i3d-float {
	0%, 100% { transform: translate3d(0, 0, 0) rotate(0deg); }
	50%      { transform: translate3d(0, -9px, 0) rotate(-1.4deg); }
}

@keyframes odc-breathe {
	0%, 100% { transform: scale(1); }
	50%      { transform: scale(1.045); }
}

@keyframes odc-spin-y {
	0%   { transform: perspective(700px) rotateY(0deg); }
	100% { transform: perspective(700px) rotateY(360deg); }
}

@keyframes odc-tilt-sway {
	0%, 100% { transform: perspective(800px) rotateY(-7deg) rotateX(3deg); }
	50%      { transform: perspective(800px) rotateY(7deg) rotateX(-2deg); }
}

.odc-i3d--float   { animation: odc-i3d-float var(--f-dur, 6s) var(--ease) var(--f-delay, 0s) infinite; }
.odc-i3d--breathe { animation: odc-breathe var(--f-dur, 5s) var(--ease) var(--f-delay, 0s) infinite; }
.odc-i3d--sway    { animation: odc-tilt-sway var(--f-dur, 9s) var(--ease) var(--f-delay, 0s) infinite; }
.odc-i3d--spin    { animation: odc-spin-y var(--f-dur, 22s) linear var(--f-delay, 0s) infinite; }

/* --- Socle lumineux -------------------------------------------------------
   Le halo est un pseudo-élément séparé et non une `box-shadow` sur l'objet :
   une box-shadow animée repeint à chaque image, un pseudo-élément en
   `opacity`/`scale` reste sur le compositeur. */

.odc-i3d-halo {
	position: relative;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	isolation: isolate;
}
.odc-i3d-halo::before {
	content: '';
	position: absolute;
	z-index: -1;
	inset: -18%;
	border-radius: 50%;
	background: radial-gradient(circle, rgba(79, 144, 243, .38), rgba(79, 144, 243, 0) 68%);
	animation: odc-halo var(--f-dur, 5.5s) var(--ease) var(--f-delay, 0s) infinite;
	pointer-events: none;
}
.odc-i3d-halo--gold::before {
	background: radial-gradient(circle, rgba(217, 185, 137, .34), rgba(217, 185, 137, 0) 68%);
}

@keyframes odc-halo {
	0%, 100% { opacity: .55; transform: scale(.94); }
	50%      { opacity: 1;   transform: scale(1.06); }
}

/* --- Tuile de verre porteuse d'icône -------------------------------------- */

.odc-i3d-tile {
	position: relative;
	display: grid;
	place-items: center;
	padding: clamp(.9rem, .6rem + .8vw, 1.4rem);
	border: 1px solid var(--line);
	border-radius: var(--r-lg);
	background:
		linear-gradient(150deg, rgba(255, 255, 255, .9), rgba(244, 247, 252, .55)),
		radial-gradient(120% 90% at 15% 0%, rgba(133, 180, 251, .22), transparent 60%);
	box-shadow: var(--sh-sm);
	transition: transform var(--dur) var(--ease), box-shadow var(--dur) var(--ease);
}
.odc-i3d-tile:hover { transform: translateY(-6px); box-shadow: var(--sh-lg); }

.odc-section--dark .odc-i3d-tile,
.odc-hero .odc-i3d-tile {
	border-color: var(--line-invert);
	background:
		linear-gradient(150deg, rgba(255, 255, 255, .08), rgba(255, 255, 255, .02)),
		radial-gradient(120% 90% at 15% 0%, rgba(79, 144, 243, .18), transparent 60%);
	-webkit-backdrop-filter: blur(14px) saturate(140%);
	backdrop-filter: blur(14px) saturate(140%);
}

/* --- Grille de la bibliothèque d'icônes ----------------------------------- */

.odc-i3d-grid {
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(112px, 1fr));
	gap: clamp(.7rem, .4rem + .8vw, 1.15rem);
}
.odc-i3d-grid__item { display: grid; gap: .55rem; justify-items: center; text-align: center; }
.odc-i3d-grid__label {
	font-size: var(--fs-eyebrow);
	font-weight: 500;
	letter-spacing: .01em;
	color: var(--text-muted);
}
.odc-section--dark .odc-i3d-grid__label { color: var(--text-invert-soft); }

/* == 21. Décors avancés ====================================================
   Tous ces éléments sont purement décoratifs, portent `aria-hidden` et
   `pointer-events: none`, et n'animent que `transform`/`opacity`.
   ========================================================================= */

/* --- Aurore : dégradé de maille en mouvement lent -------------------------
   Trois taches radiales sur un seul élément, déplacées ensemble. Un vrai mesh
   gradient demanderait un canvas ou quatre calques empilés ; à cette échelle
   de flou, la différence ne se voit pas et le coût est nul. */

.odc-aurora {
	position: absolute;
	inset: -25%;
	pointer-events: none;
	opacity: .75;
	background:
		radial-gradient(38% 44% at 22% 28%, rgba(37, 112, 224, .55), transparent 62%),
		radial-gradient(34% 40% at 78% 22%, rgba(133, 180, 251, .42), transparent 60%),
		radial-gradient(46% 50% at 58% 82%, rgba(15, 82, 186, .48), transparent 64%);
	filter: blur(48px);
	animation: odc-aurora 26s var(--ease) infinite;
	will-change: transform;
}
.odc-aurora--soft { opacity: .4; filter: blur(70px); }

@keyframes odc-aurora {
	0%, 100% { transform: translate3d(0, 0, 0) scale(1) rotate(0deg); }
	33%      { transform: translate3d(3%, -2%, 0) scale(1.08) rotate(4deg); }
	66%      { transform: translate3d(-2%, 3%, 0) scale(1.04) rotate(-3deg); }
}

/* --- Trame hexagonale ------------------------------------------------------
   Nid d'abeille reprenant le motif moléculaire de la référence. Le pavé fait
   31,18 × 54 : c'est la maille exacte d'un hexagone pointe en haut de rayon 18
   (largeur √3·R, pas vertical 1,5·R). Une valeur approchée ferait dériver le
   motif d'un pavé à l'autre et le raccord se verrait en diagonale. */

.odc-hex {
	position: absolute;
	inset: 0;
	pointer-events: none;
	opacity: .5;
	background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='31.18' height='54' viewBox='0 0 31.18 54'%3E%3Cg fill='none' stroke='%234f90f3' stroke-width='.8'%3E%3Cpath d='M15.59 0 31.18 9v18l-15.59 9L0 27V9Z'/%3E%3Cpath d='M0 27l15.59 9v18L0 63l-15.59-9V36Z'/%3E%3Cpath d='M31.18 27l15.59 9v18l-15.59 9-15.59-9V36Z'/%3E%3C/g%3E%3C/svg%3E");
	background-size: 62px 108px;
	-webkit-mask-image: radial-gradient(ellipse 70% 60% at 50% 40%, #000, transparent 72%);
	mask-image: radial-gradient(ellipse 70% 60% at 50% 40%, #000, transparent 72%);
}
.odc-hex--dense { background-size: 38px 66px; opacity: .32; }
.odc-section--dark .odc-hex, .odc-hero .odc-hex { opacity: .16; }

/* --- Orbes flottantes (bokeh) -------------------------------------------- */

.odc-orb {
	position: absolute;
	border-radius: 50%;
	pointer-events: none;
	background: radial-gradient(circle at 32% 28%, rgba(255, 255, 255, .7), rgba(133, 180, 251, .32) 42%, rgba(37, 112, 224, .06) 70%);
	box-shadow: inset 0 0 22px rgba(255, 255, 255, .35);
	opacity: .55;
	animation: odc-drift var(--f-dur, 18s) var(--ease) var(--f-delay, 0s) infinite;
	will-change: transform;
}
.odc-orb--blur { filter: blur(6px); opacity: .4; }
.odc-orb--gold {
	background: radial-gradient(circle at 32% 28%, rgba(255, 255, 255, .65), rgba(240, 224, 196, .3) 44%, rgba(217, 185, 137, .05) 72%);
}

@keyframes odc-drift {
	0%, 100% { transform: translate3d(0, 0, 0) scale(1); }
	25%      { transform: translate3d(14px, -20px, 0) scale(1.06); }
	50%      { transform: translate3d(-8px, -34px, 0) scale(.96); }
	75%      { transform: translate3d(-18px, -14px, 0) scale(1.03); }
}

/* --- Rayons volumétriques -------------------------------------------------
   Le dégradé répété tient lieu de faisceaux ; le masque conique les fait
   converger vers un point haut, sinon on lit une trame de rayures. */

.odc-rays {
	position: absolute;
	inset: -40% -20% auto;
	height: 120%;
	pointer-events: none;
	opacity: .28;
	background: repeating-linear-gradient(
		100deg,
		transparent 0 34px,
		rgba(133, 180, 251, .5) 34px 36px,
		transparent 36px 78px
	);
	-webkit-mask-image: radial-gradient(ellipse 60% 90% at 50% 0%, #000, transparent 70%);
	mask-image: radial-gradient(ellipse 60% 90% at 50% 0%, #000, transparent 70%);
	transform-origin: 50% 0;
	animation: odc-rays 19s var(--ease) infinite;
}

@keyframes odc-rays {
	0%, 100% { transform: rotate(-2.5deg) translateY(0); opacity: .2; }
	50%      { transform: rotate(2.5deg) translateY(-18px); opacity: .36; }
}

/* --- Forme organique en morphing ----------------------------------------- */

.odc-blob {
	position: absolute;
	pointer-events: none;
	background: linear-gradient(140deg, rgba(37, 112, 224, .5), rgba(133, 180, 251, .22));
	filter: blur(14px);
	opacity: .5;
	border-radius: 62% 38% 44% 56% / 48% 56% 44% 52%;
	animation: odc-morph var(--f-dur, 16s) var(--ease) var(--f-delay, 0s) infinite;
	will-change: border-radius, transform;
}

@keyframes odc-morph {
	0%, 100% { border-radius: 62% 38% 44% 56% / 48% 56% 44% 52%; transform: rotate(0deg) scale(1); }
	33%      { border-radius: 42% 58% 62% 38% / 56% 42% 58% 44%; transform: rotate(6deg) scale(1.05); }
	66%      { border-radius: 55% 45% 36% 64% / 38% 62% 38% 62%; transform: rotate(-5deg) scale(.97); }
}

/* --- Ligne de balayage --------------------------------------------------- */

.odc-scanline {
	position: absolute;
	inset: 0;
	overflow: hidden;
	pointer-events: none;
	-webkit-mask-image: linear-gradient(90deg, transparent, #000 18%, #000 82%, transparent);
	mask-image: linear-gradient(90deg, transparent, #000 18%, #000 82%, transparent);
}
.odc-scanline::after {
	content: '';
	position: absolute;
	inset: -50% 0 auto;
	height: 42%;
	background: linear-gradient(180deg, transparent, rgba(133, 180, 251, .3), transparent);
	animation: odc-sweep 7s var(--ease) infinite;
}

@keyframes odc-sweep {
	0%   { transform: translateY(0); opacity: 0; }
	12%  { opacity: 1; }
	88%  { opacity: 1; }
	100% { transform: translateY(340%); opacity: 0; }
}

/* --- Particules flottantes en CSS ----------------------------------------
   Complète le canvas du hero, qui reste réservé aux liaisons entre points. Ici,
   quelques points isolés suffisent et ne coûtent aucun JavaScript. */

.odc-motes { position: absolute; inset: 0; overflow: hidden; pointer-events: none; }
.odc-motes span {
	position: absolute;
	width: var(--s, 4px);
	height: var(--s, 4px);
	border-radius: 50%;
	background: rgba(133, 180, 251, .8);
	box-shadow: 0 0 10px rgba(133, 180, 251, .7);
	animation: odc-mote-rise var(--f-dur, 16s) linear var(--f-delay, 0s) infinite;
	opacity: 0;
}

@keyframes odc-mote-rise {
	0%   { transform: translate3d(0, 0, 0); opacity: 0; }
	10%  { opacity: .9; }
	85%  { opacity: .5; }
	100% { transform: translate3d(24px, -260px, 0); opacity: 0; }
}

/* == 22. Effets premium ====================================================
   Ces trois modificateurs sont pilotés par main.js, qui n'écrit que des
   variables CSS. Aucun style n'est posé en JavaScript : la règle reste ici, et
   le comportement se coupe entièrement en supprimant l'attribut data-*.
   ========================================================================= */

/* --- Inclinaison 3D au survol -------------------------------------------- */

[data-tilt] {
	transform:
		perspective(var(--tilt-depth, 900px))
		rotateX(var(--tilt-x, 0deg))
		rotateY(var(--tilt-y, 0deg))
		translateZ(0);
	transform-style: preserve-3d;
	transition: transform var(--dur) var(--ease);
}
[data-tilt].is-tilting { transition: transform .08s linear; }
[data-tilt] > * { transform: translateZ(var(--tilt-lift, 0)); }

/* --- Dérive à la souris ---------------------------------------------------
   `main.js` n'écrit que ces deux variables ; la transformation est ici. Elle est
   posée sur l'ENVELOPPE de l'objet, jamais sur l'image : celle-ci porte déjà son
   animation de flottement, et deux `transform` sur un même élément s'écrasent —
   le dernier déclaré gagne et l'autre disparaît sans erreur. */

[data-drift] {
	transform: translate3d(var(--drift-x, 0), var(--drift-y, 0), 0);
	will-change: transform;
}

/* --- Bouton magnétique ---------------------------------------------------- */

[data-magnetic] {
	transform: translate3d(var(--mag-x, 0), var(--mag-y, 0), 0);
	transition: transform .35s var(--ease-spring);
}
[data-magnetic].is-pulling { transition: transform .12s linear; }

/* --- Balayage lumineux au survol ------------------------------------------ */

.odc-shine { position: relative; overflow: hidden; }
.odc-shine::after {
	content: '';
	position: absolute;
	inset: 0 auto 0 -60%;
	width: 45%;
	background: linear-gradient(100deg, transparent, rgba(255, 255, 255, .48), transparent);
	transform: translateX(0) skewX(-18deg);
	transition: transform .9s var(--ease-out);
	pointer-events: none;
}
.odc-shine:hover::after { transform: translateX(370%) skewX(-18deg); }

/* --- Lévitation au survol ------------------------------------------------- */

.odc-lift { transition: transform var(--dur) var(--ease), box-shadow var(--dur) var(--ease); }
.odc-lift:hover { transform: translateY(-8px) scale(1.012); box-shadow: var(--sh-xl); }

/* --- Bordure en dégradé animé --------------------------------------------
   `background-clip` sur deux fonds : le premier peint l'intérieur, le second la
   bordure. C'est la seule façon d'obtenir une bordure en dégradé sans doubler
   l'élément, et elle reste compatible avec un `border-radius`. */

.odc-ring {
	border: 1px solid transparent;
	background:
		linear-gradient(var(--ring-bg, #fff), var(--ring-bg, #fff)) padding-box,
		conic-gradient(from var(--ring-a, 0deg), var(--blue-300), var(--blue-600), var(--blue-200), var(--blue-300)) border-box;
	animation: odc-ring 8s linear infinite;
}
.odc-section--dark .odc-ring, .odc-hero .odc-ring { --ring-bg: rgba(8, 15, 31, .72); }

/* `@property` rend l'angle interpolable : sans lui, une variable d'angle est une
   chaîne, l'animation saute de 0 à 360 et la bordure clignote au lieu de tourner. */
@property --ring-a {
	syntax: '<angle>';
	inherits: false;
	initial-value: 0deg;
}
@keyframes odc-ring { to { --ring-a: 360deg; } }

/* == 23. Accessibilité et impression ======================================= */

@media (prefers-reduced-motion: reduce) {
	html { scroll-behavior: auto; }
	*, *::before, *::after {
		animation-duration: .01ms !important;
		animation-iteration-count: 1 !important;
		transition-duration: .01ms !important;
	}
	[data-reveal] { opacity: 1 !important; transform: none !important; filter: none !important; }
	.odc-hero__canvas, .odc-tech__scan { display: none; }
}

@media (prefers-contrast: more) {
	:root { --text-body: #1d2942; --text-muted: #3b4a66; --line: rgba(9, 30, 66, .28); }
	.odc-btn { box-shadow: inset 0 0 0 2px currentColor; }
}

@media print {
	.odc-header, .odc-fab, .odc-top, .odc-hero__cue, .odc-map, .odc-form, .odc-hero__canvas { display: none !important; }
	body.odc { color: #000; background: #fff; }
	.odc-section--dark, .odc-footer, .odc-hero { color: #000 !important; background: #fff !important; }
	.odc-section--dark h2, .odc-footer h3, .odc-hero__title { color: #000 !important; }
	/*
	 * Le `em` du H1 est peint en dégradé via background-clip, donc `color:
	 * transparent`. La règle ci-dessus cible le titre, pas son `em` : sans cette
	 * remise à plat, « Dr Adil AKIF, chirurgien-dentiste » s'imprimait en
	 * transparent — le nom du praticien disparaissait de la feuille, y compris
	 * quand les graphiques d'arrière-plan sont activés (le dégradé part de #fff).
	 */
	.odc-hero__title em {
		color: #000 !important;
		-webkit-text-fill-color: #000 !important;
		background: none !important;
	}
	[data-reveal] { opacity: 1 !important; transform: none !important; filter: none !important; }
}

/* == 21. Sélecteur de langue =============================================== */

/*
 * Trois liens, pas un menu déroulant.
 *
 * Un `<select>` ou un panneau au clic coûterait un geste de plus pour un choix
 * qui n'a que trois issues, et masquerait aux moteurs deux des trois URL. Ici
 * les trois adresses sont dans le document, cliquables sans JavaScript, et le
 * module `softNav` se contente d'en intercepter le clic pour éviter le
 * rechargement visible.
 */
.odc-langs {
	display: flex;
	align-items: center;
	gap: 2px;
	padding: 3px;
	border-radius: var(--r-pill);
	background: rgba(255, 255, 255, .06);
	box-shadow: inset 0 0 0 1px var(--line-invert);
}

.odc-langs__item {
	display: grid;
	place-items: center;
	min-width: 34px;
	min-height: 30px;
	padding: 0 .5rem;
	/*
	 * La zone tactile passe à 44x44 au doigt, sans grossir le bouton.
	 *
	 * Mesuré à 34x30 px : sous la norme WCAG 2.5.5, et c'est la commande que
	 * TOUS les visiteurs non francophones doivent atteindre — l'échec y coûte
	 * une langue entière. Un pseudo-élément étend la cible sans toucher à la
	 * mise en page ni à l'alignement des trois pastilles ; `@media (pointer:
	 * coarse)` réserve l'agrandissement au tactile, la souris n'en a pas besoin.
	 */
	position: relative;
	font-family: var(--font-display);
	font-size: .78rem;
	font-weight: 600;
	line-height: 1;
	color: var(--text-invert-soft);
	border-radius: var(--r-pill);
	transition: color var(--dur-fast) var(--ease), background var(--dur-fast) var(--ease);
}

@media (pointer: coarse) {
	.odc-langs__item::after {
		content: '';
		position: absolute;
		inset: 50% auto auto 50%;
		width: max(100%, 44px);
		height: 44px;
		transform: translate(-50%, -50%);
	}
}

.odc-langs__item:hover { color: #fff; background: rgba(255, 255, 255, .1); }

.odc-langs__item.is-active {
	color: #fff;
	background: var(--blue-600);
	box-shadow: var(--sh-blue);
}

/* Le libellé complet n'est là que pour les lecteurs d'écran : « FR » seul
   n'annonce pas une langue, il épelle deux lettres. */
.odc-langs__full {
	position: absolute;
	width: 1px; height: 1px;
	overflow: hidden;
	clip-path: inset(50%);
	white-space: nowrap;
}

/* L'arabe s'écrit « ع » : une seule lettre, plus haute que « FR » et « EN ».
   Sans cet ajustement, la pastille active paraissait décentrée. */
.odc-langs__item[lang='ar'] .odc-langs__short {
	font-family: var(--font-arabic, inherit);
	font-size: .95rem;
	line-height: 1;
	transform: translateY(-.02em);
}

/* Dans le panneau mobile, le sélecteur passe pleine largeur, au-dessus des
   deux boutons d'action : c'est le premier choix à faire, pas le dernier. */
.odc-langs--mobile {
	justify-content: stretch;
	margin-bottom: .3rem;
	border-radius: var(--r-sm);
}
.odc-langs--mobile .odc-langs__item {
	flex: 1;
	min-height: 40px;
	border-radius: calc(var(--r-sm) - 3px);
	font-size: .85rem;
}

/* Sur les pages intérieures, l'en-tête reste sombre : aucune variante claire
   n'est nécessaire. Le sélecteur ne sort jamais de ce fond. */

@media (max-width: 1219px) {
	/* La barre perd ses boutons à cette largeur (cf. § 07) mais garde le
	   sélecteur : changer de langue ne doit pas obliger à ouvrir le menu. */
	.odc-langs--bar { margin-inline-end: .1rem; }
}

@media (max-width: 420px) {
	.odc-langs--bar .odc-langs__item { min-width: 30px; padding: 0 .35rem; }
}

/* == 22. Navigation douce ================================================== */

/*
 * Le fondu entre deux pages est délégué à l'API des transitions de vue : le
 * navigateur capture l'ancienne page, applique la nouvelle, et interpole. Rien
 * à animer à la main, et rien à nettoyer si l'API est absente.
 */
@view-transition { navigation: auto; }

::view-transition-old(root),
::view-transition-new(root) {
	animation-duration: .28s;
	animation-timing-function: var(--ease-out);
}

/*
 * Repère d'attente.
 *
 * Sur un site local la réponse est immédiate ; sur un lien 3G elle ne l'est pas,
 * et un clic sans retour visible se lit comme un clic perdu — le visiteur
 * reclique. La barre de progression déjà présente en haut de page sert de
 * témoin : elle passe en indéterminé le temps de la requête.
 */
/* La barre EST l'indicateur : elle n'a pas de `::after`. On reprend donc son
   `transform`, que le module de défilement pilote le reste du temps. */
.is-navigating .odc-progress {
	animation: odc-nav-wait 1s var(--ease) infinite;
}

@keyframes odc-nav-wait {
	0%   { transform: scaleX(0); }
	50%  { transform: scaleX(1); }
	100% { transform: scaleX(0); }
}

/* Le curseur dit qu'il se passe quelque chose, même hors du champ de la barre. */
.is-navigating { cursor: progress; }

@media (prefers-reduced-motion: reduce) {
	::view-transition-old(root),
	::view-transition-new(root) { animation: none; }
	.is-navigating .odc-progress { animation: none; }
}

/* == 23. Réalisations — comparateur avant / après ========================== */

.odc-real__grid {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(min(420px, 100%), 1fr));
	gap: clamp(1.4rem, 1rem + 2vw, 2.6rem);
	margin-top: clamp(2.2rem, 1.5rem + 2vw, 3.4rem);
}

.odc-real__card {
	margin: 0;
	overflow: hidden;
	background: var(--surface-1);
	border-radius: var(--r-lg);
	box-shadow: var(--sh-md);
	transition: box-shadow var(--dur) var(--ease), transform var(--dur) var(--ease);
}
.odc-real__card:hover { box-shadow: var(--sh-lg); }

/*
 * Le comparateur.
 *
 * Les deux images sont superposées en grille — même cellule, donc même taille
 * intrinsèque — et c'est un `clip-path` qui découvre l'« avant ». Découper
 * plutôt que redimensionner est ce qui garde les deux vues parfaitement
 * alignées : une largeur animée aurait déformé l'image du dessus au fil du
 * glissement, et la comparaison n'aurait plus rien voulu dire.
 */
.odc-compare {
	position: relative;
	display: grid;
	isolation: isolate;
	aspect-ratio: 16 / 10;
	overflow: hidden;
	background: var(--surface-3);
	touch-action: pan-y;
}

.odc-compare__pane { grid-area: 1 / 1; min-width: 0; }
.odc-compare__pane img,
.odc-compare__pane .odc-pic { width: 100%; height: 100%; object-fit: cover; }

.odc-compare__pane--before {
	z-index: 2;
	clip-path: inset(0 calc(100% - var(--split, 50%)) 0 0);
}

/* Le trait de séparation, dessiné sur le volet « avant » : il suit donc la
   découpe sans qu'aucun script n'ait à le positionner. */
.odc-compare__pane--before::after {
	content: '';
	position: absolute;
	inset-block: 0;
	inset-inline-start: var(--split, 50%);
	width: 2px;
	margin-inline-start: -1px;
	background: rgba(255, 255, 255, .92);
	box-shadow: 0 0 12px rgba(4, 7, 15, .45);
	z-index: 3;
}

.odc-compare__tag {
	position: absolute;
	top: .8rem;
	z-index: 4;
	padding: .28rem .62rem;
	font-family: var(--font-display);
	font-size: .68rem;
	font-weight: 600;
	letter-spacing: .08em;
	text-transform: uppercase;
	color: #fff;
	background: rgba(4, 7, 15, .62);
	backdrop-filter: blur(6px);
	border-radius: var(--r-pill);
	pointer-events: none;
}
.odc-compare__tag--before { inset-inline-start: .8rem; }
.odc-compare__tag--after  { inset-inline-end: .8rem; }

/* La poignée est purement décorative : le curseur natif, invisible, est ce qui
   reçoit réellement le pointeur et le clavier. */
.odc-compare__handle {
	position: absolute;
	top: 50%;
	inset-inline-start: var(--split, 50%);
	z-index: 5;
	display: grid;
	grid-auto-flow: column;
	place-items: center;
	gap: 1px;
	width: 46px; height: 46px;
	margin-inline-start: -23px;
	margin-top: -23px;
	color: var(--blue-600);
	background: #fff;
	border-radius: 50%;
	box-shadow: 0 2px 6px rgba(7, 16, 38, .2), 0 8px 24px -6px rgba(7, 16, 38, .3);
	pointer-events: none;
	transition: transform var(--dur-fast) var(--ease);
}
.odc-compare__handle svg:first-child { transform: rotate(180deg); }

/*
 * Le curseur natif couvre toute l'image, sans être visible.
 *
 * `opacity: 0` plutôt que `appearance: none` sur chaque pseudo-élément : le
 * dessin natif diffère d'un navigateur à l'autre, et il aurait fallu le
 * neutraliser trois fois. Ici il reste entièrement fonctionnel — pointeur,
 * clavier, lecteur d'écran — mais invisible, la poignée ci-dessus tenant lieu
 * d'affordance.
 */
.odc-compare__range {
	position: absolute;
	inset: 0;
	z-index: 6;
	width: 100%; height: 100%;
	margin: 0;
	opacity: 0;
	cursor: ew-resize;
	appearance: none;
	background: transparent;
}
.odc-compare__range::-webkit-slider-thumb { appearance: none; width: 46px; height: 100%; }
.odc-compare__range::-moz-range-thumb { width: 46px; height: 100%; border: 0; }

.odc-compare__range:focus-visible { opacity: 1; outline: none; }
.odc-compare__range:focus-visible ~ .odc-compare__handle {
	transform: scale(1.12);
	box-shadow: 0 0 0 3px var(--blue-400), 0 8px 24px -6px rgba(7, 16, 38, .3);
}

.odc-real__cap {
	display: grid;
	gap: .35rem;
	padding: 1.25rem 1.35rem 1.45rem;
}
.odc-real__cap strong { font-family: var(--font-display); font-size: var(--fs-h4); color: var(--text-strong); }
.odc-real__cap > span { font-size: var(--fs-small); color: var(--text-muted); }

.odc-real__link {
	display: inline-flex;
	align-items: center;
	gap: .35rem;
	margin-top: .45rem;
	font-size: var(--fs-small);
	font-weight: 600;
	color: var(--blue-600);
}
.odc-real__link:hover svg { transform: translateX(3px); }
.odc-real__link svg { transition: transform var(--dur-fast) var(--ease); }

.odc-real__more { display: flex; justify-content: center; margin-top: 2.4rem; }
.odc-real__note { margin-top: 2.2rem; }

/* Sans JavaScript, la découpe reste à 50 % : les deux vues sont visibles, et le
   curseur natif fonctionne malgré tout. Rien à prévoir de plus. */

@media (max-width: 560px) {
	.odc-compare { aspect-ratio: 4 / 3; }
	.odc-compare__handle { width: 40px; height: 40px; margin-inline-start: -20px; margin-top: -20px; }
}

/*
 * Emplacement d'image en attente — dans un comparateur seulement.
 *
 * Le repli générique est un aplat discret, ce qui convient à une vignette
 * isolée. Dans un comparateur avant/après il devenait illisible : deux aplats
 * superposés, un curseur, et rien qui dise POURQUOI c'est vide. On affiche donc
 * le nom du fichier attendu, repris de `data-slug`.
 *
 * Ce n'est pas un décor : c'est le seul endroit qui dit à l'intégrateur quel
 * fichier déposer et où. Il disparaît de lui-même dès que l'image existe.
 */
.odc-compare .odc-img-missing {
	position: relative;
	height: 100%;
	aspect-ratio: auto;
	display: grid;
	place-items: center;
}
.odc-compare .odc-img-missing::after {
	content: attr(data-slug) '.jpg';
	padding: .4rem .7rem;
	font-family: ui-monospace, Menlo, monospace;
	font-size: .72rem;
	color: var(--text-muted);
	background: rgba(255, 255, 255, .82);
	border: 1px dashed var(--line-strong);
	border-radius: var(--r-xs);
}

/*
 * Écrans bas : le panneau mobile se resserre.
 *
 * `clamp(1.6rem, 1.2rem + 3vw, 2.4rem)` ne regarde que la LARGEUR. Sur une
 * tablette 768 × 1024 en paysage, ou sur un téléphone en mode paysage, les
 * entrées gardaient donc leur taille maximale sur une hauteur deux fois
 * moindre : la liste défilait sur trois écrans pour huit liens. On règle la
 * densité sur la hauteur disponible, seule dimension qui compte ici.
 */
@media (max-height: 780px) {
	.odc-mobile__link {
		padding: .45rem 0;
		font-size: clamp(1.2rem, 1rem + 1.6vw, 1.65rem);
	}
	.odc-mobile__sub { padding: .35rem 0 .55rem; }
	/*
	 * Planchers relevés de 34/30 à 40/38 px.
	 *
	 * Ces compressions dataient du jour où le pied de panneau — sélecteur de
	 * langue, appel, rendez-vous — était poussé hors écran par une liste qui
	 * refusait de rétrécir. Depuis que cette liste défile (`min-height: 0` +
	 * `overflow-y: auto`), la hauteur ne commande plus la visibilité du pied,
	 * et rien ne justifie plus de descendre à 30 px sous le doigt.
	 */
	.odc-mobile__sub a { min-height: 40px; font-size: .88rem; }
	.odc-mobile__foot { padding-top: .9rem; }
	.odc-mobile__top { min-height: 58px; }
}

@media (max-height: 560px) {
	.odc-mobile__link { font-size: 1.05rem; padding: .3rem 0; }
	.odc-mobile__link span { font-size: .62rem; }
	.odc-mobile__sub a { min-height: 38px; font-size: .82rem; }
}

/* == 24. Sous-services dans les menus ====================================== */

/*
 * Troisième niveau du panneau déroulant.
 *
 * Aucune icône ici, contrairement aux deux niveaux du dessus : le panneau porte
 * déjà quinze liens, et une troisième colonne de pictogrammes brouillerait la
 * hiérarchie au lieu de la marquer. Le retrait et le filet vertical suffisent.
 */
.odc-nav__subs {
	display: grid;
	gap: 1px;
	margin: .15rem 0 .5rem;
	padding-inline-start: calc(18px + .85rem);
	list-style: none;
}
.odc-nav__subs a {
	display: block;
	padding: .3rem .55rem;
	font-size: .82rem;
	color: var(--text-invert-soft);
	border-inline-start: 1px solid var(--line-invert);
	border-radius: 0 var(--r-xs) var(--r-xs) 0;
	transition: color var(--dur-fast) var(--ease), background var(--dur-fast) var(--ease);
}
.odc-nav__subs a:hover {
	color: #fff;
	background: rgba(255, 255, 255, .06);
	border-inline-start-color: var(--blue-400);
}

/*
 * Fenêtre courte : on resserre plutôt que de faire défiler.
 *
 * Sur un navigateur de 700 px de haut, le cadre laisse ~613 px de vue utile.
 * Le panneau dépassait alors de 32 px, et « Urgence dentaire » — le dernier
 * lien, celui qu'on cherche quand on est pressé — tombait trois pixels sous le
 * pli. Trois pixels suffisent à le rendre introuvable sans molette.
 */
@media (max-height: 760px) {
	.odc-nav__panel a { padding: .45rem .7rem; }
	.odc-nav__panel > ul > li { margin-bottom: 0; }
	.odc-nav__subs { margin: .1rem 0 .35rem; }
	.odc-nav__subs a { padding: .22rem .55rem; }
}

/*
 * Second palier, pour les portables à écran court (~573 px de vue utile).
 * On reste au-dessus de la cible minimale de 24 px du pointeur fin : ce
 * panneau ne s'ouvre qu'au survol, il n'est jamais parcouru au doigt.
 */
@media (max-height: 620px) {
	.odc-nav__panel { padding: .35rem; }
	.odc-nav__panel a { padding: .32rem .6rem; }
	.odc-nav__panel strong { font-size: .84rem; }
	.odc-nav__subs { margin: .05rem 0 .25rem; }
	.odc-nav__subs a { padding: .14rem .55rem; font-size: .78rem; }
}


/* Même principe dans le panneau mobile. */
.odc-mobile__sub2 {
	/*
	 * `flex` et non `block` : centre le texte verticalement dans les 44 px
	 * minimum imposés ci-dessous. Mesuré à 40 px de haut — quatre pixels sous
	 * la norme, sur un panneau qui ne se parcourt qu'au doigt.
	 */
	display: flex;
	align-items: center;
	padding: .1rem 0 .1rem 1.7rem;
	font-size: .84rem;
	color: rgba(255, 255, 255, .6);
}
.odc-mobile__sub2::before {
	content: '';
	display: inline-block;
	width: .7rem;
	margin-inline-start: -1rem;
	margin-inline-end: .3rem;
	border-top: 1px solid var(--line-invert);
	vertical-align: middle;
}
.odc-mobile__sub2:hover { color: #fff; }

/*
 * Le panneau déroulant gagne trois niveaux : il faut lui rendre la hauteur
 * défilable, faute de quoi les derniers pôles sortent sous le pli sur un écran
 * de portable — le même défaut que le menu mobile portait avant correction.
 */
.odc-nav__panel {
	max-height: min(86vh, 760px);
	overflow-y: auto;
	overscroll-behavior: contain;
	scrollbar-width: thin;
	scrollbar-color: rgba(255, 255, 255, .22) transparent;
}

/* == 25. Sous-services illustrés =========================================== */

/*
 * La grille des actes d'un pôle.
 *
 * Trois colonnes au-delà de 900 px, deux au-dessus de 640, une en dessous —
 * les mêmes seuils que l'attribut `sizes` des images, sinon le navigateur
 * télécharge un palier qui ne correspond pas à la place réellement occupée.
 */
/*
 * Marge SYMÉTRIQUE : le bloc porte son propre espacement.
 *
 * Il n'avait qu'une marge haute, ce qui suffisait tant qu'il terminait la page.
 * Remonté entre « L'essentiel » et l'illustration, il s'est retrouvé collé à
 * celle-ci — l'image n'ayant, symétriquement, qu'une marge basse : zéro pixel
 * entre les deux. Un composant qu'on déplace doit être autonome en espacement,
 * sinon chaque déplacement redemande un réglage.
 */
.odc-subs { margin: clamp(2.5rem, 5vw, 4rem) 0; }

.odc-subs__title {
	margin: 0 0 1.4rem;
	font-family: var(--font-display);
	font-size: clamp(1.35rem, 1.1rem + .9vw, 1.85rem);
	line-height: 1.25;
}

.odc-subs__grid {
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(min(100%, 15.5rem), 1fr));
	gap: clamp(.9rem, 2vw, 1.4rem);
}

.odc-subs__card {
	display: flex;
	flex-direction: column;
	overflow: hidden;
	background: var(--surface);
	border: 1px solid var(--line);
	border-radius: var(--r-lg);
	text-decoration: none;
	color: inherit;
	transition: transform var(--dur) var(--ease), box-shadow var(--dur) var(--ease),
	            border-color var(--dur) var(--ease);
}
.odc-subs__card:hover {
	transform: translateY(-3px);
	border-color: var(--blue-300);
	box-shadow: var(--shadow-md);
}

.odc-subs__media {
	position: relative;
	display: block;
	/* Rapport figé : les neuf photos sont recadrées en 16/10 à la source, mais
	   une image manquante ne doit pas faire s'effondrer la carte. */
	aspect-ratio: 16 / 10;
	overflow: hidden;
	background: var(--surface-2);
}
.odc-subs__img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	display: block;
	transition: transform var(--dur-slow) var(--ease);
}
.odc-subs__card:hover .odc-subs__img { transform: scale(1.04); }

/* Pastille d'icône posée sur la photo : elle relie la carte au pôle parent,
   dont le menu et la page-pilier portent la même icône. */
.odc-subs__ico {
	position: absolute;
	inset-block-end: .6rem;
	inset-inline-start: .6rem;
	display: grid;
	place-items: center;
	width: 2.1rem;
	height: 2.1rem;
	color: #fff;
	background: rgba(11, 22, 45, .62);
	backdrop-filter: blur(6px);
	border-radius: 50%;
}

.odc-subs__body {
	display: flex;
	flex-direction: column;
	gap: .35rem;
	padding: .9rem 1rem 1.05rem;
}
.odc-subs__name { font-size: 1.02rem; line-height: 1.3; }
.odc-subs__lead {
	font-size: .88rem;
	line-height: 1.5;
	color: var(--text-soft);
}
.odc-subs__more {
	display: inline-flex;
	align-items: center;
	gap: .35rem;
	margin-top: .25rem;
	font-size: .82rem;
	font-weight: 600;
	color: var(--blue-600);
}
.odc-subs__card:hover .odc-subs__more svg { transform: translateX(3px); }
.odc-subs__more svg { transition: transform var(--dur-fast) var(--ease); }

/* Retour au pôle parent, depuis une page d'acte. */
.odc-backlink {
	display: inline-flex;
	align-items: center;
	gap: .5rem;
	margin-top: 2.2rem;
	padding: .55rem .95rem;
	font-size: .9rem;
	font-weight: 600;
	color: var(--blue-600);
	background: var(--blue-50);
	border-radius: var(--r-pill);
	text-decoration: none;
}
.odc-backlink:hover { background: var(--blue-100); }
/* La flèche pointe vers l'amont : on la retourne. */
.odc-backlink svg { transform: rotate(180deg); }

/* Photo en tête d'une page d'acte. */
.odc-soin__figure {
	margin: 1.6rem 0 0;
	overflow: hidden;
	border-radius: var(--r-lg);
	border: 1px solid var(--line);
}
.odc-soin__img {
	display: block;
	width: 100%;
	height: auto;
	aspect-ratio: 16 / 10;
	object-fit: cover;
}

/* Vignettes du menu déroulant. */
.odc-nav__subs a {
	display: flex;
	align-items: center;
	gap: .55rem;
}
.odc-nav__thumb {
	flex: 0 0 auto;
	width: 40px;
	height: 26px;
	object-fit: cover;
	border-radius: var(--r-xs);
	/* Les photos sont claires, le panneau est sombre : sans ce léger voile
	   elles sautent aux yeux plus que les intitulés qu'elles accompagnent. */
	opacity: .82;
	transition: opacity var(--dur-fast) var(--ease);
}
.odc-nav__subs a:hover .odc-nav__thumb { opacity: 1; }
