:root {
  color-scheme: light;
  --bg: #ffffff;
  --surface: #ffffff;
  --surface-2: #f6f9fc;
  --text: #1a1f36;
  --muted: #596780;
  --line: #e3e8ee;
  --brand: #5469d4;
  --brand-strong: #4458b5;
  --brand-soft: #eef1fc;
  --step-bg: #e6f0fa;
  --step-fg: #6b7c93;
  --callout-bg: #f9f9f9;
  --accent: #f59e0b;
  --danger: #b42318;
  --success: #18794e;
  --shadow: 0 12px 30px rgba(50, 50, 93, .08);
  --radius: 18px;
  --header-h: 64px;
  --section-nav-h: 46px;
  --font-mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace;
  /* Palette du panneau de code, identique en thème clair et sombre. */
  --code-bg: #1b2131;
  --code-head: #141a27;
  --code-line: #2b3346;
  --code-fg: #e3e8f2;
  --code-muted: #8a95ac;
  --code-ok: #6ee7a8;
  --code-tag: #82b8ff;
  --code-attr: #9edcb0;
  --code-string: #f0a882;
  --code-comment: #6e7b94;
  /* Chevron utilisé devant chaque lien du sommaire de chapitre. */
  --icon-anchor: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m9 18 6-6-6-6'/%3E%3C/svg%3E");
  /* Lucide « moon » et « sun », pour la bascule de thème. */
  --icon-moon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M12 3a6 6 0 0 0 9 9 9 9 0 1 1-9-9Z'/%3E%3C/svg%3E");
  --icon-sun: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='4'/%3E%3Cpath d='M12 2v2'/%3E%3Cpath d='M12 20v2'/%3E%3Cpath d='m4.93 4.93 1.41 1.41'/%3E%3Cpath d='m17.66 17.66 1.41 1.41'/%3E%3Cpath d='M2 12h2'/%3E%3Cpath d='M20 12h2'/%3E%3Cpath d='m6.34 17.66-1.41 1.41'/%3E%3Cpath d='m19.07 4.93-1.41 1.41'/%3E%3C/svg%3E");
  /* Lucide, pour les boutons d'action du configurateur. */
  --icon-maximize: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M8 3H5a2 2 0 0 0-2 2v3'/%3E%3Cpath d='M21 8V5a2 2 0 0 0-2-2h-3'/%3E%3Cpath d='M3 16v3a2 2 0 0 0 2 2h3'/%3E%3Cpath d='M16 21h3a2 2 0 0 0 2-2v-3'/%3E%3C/svg%3E");
  --icon-minimize: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M8 3v3a2 2 0 0 1-2 2H3'/%3E%3Cpath d='M21 8h-3a2 2 0 0 1-2-2V3'/%3E%3Cpath d='M3 16h3a2 2 0 0 1 2 2v3'/%3E%3Cpath d='M16 21v-3a2 2 0 0 1 2-2h3'/%3E%3C/svg%3E");
  --icon-reset: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8'/%3E%3Cpath d='M3 3v5h5'/%3E%3C/svg%3E");
  /* Lucide « droplet-off » : annule la couleur de fond simulée. Volontairement
     distincte de --icon-reset, sinon les deux boutons semblent identiques. */
  --icon-droplet-off: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M18.715 13.186C18.29 11.858 17.384 10.607 16 9.5c-2-1.6-3.5-4-4-6.5a10.7 10.7 0 0 1-.884 2.586'/%3E%3Cpath d='m2 2 20 20'/%3E%3Cpath d='M8.795 8.797A11 11 0 0 1 8 9.5C6 11.1 5 13 5 15a7 7 0 0 0 13.222 3.208'/%3E%3C/svg%3E");
  /* Lucide « monitor » et « smartphone » : largeur simulée de l'aperçu. */
  --icon-monitor: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='2' y='3' width='20' height='14' rx='2'/%3E%3Cpath d='M8 21h8'/%3E%3Cpath d='M12 17v4'/%3E%3C/svg%3E");
  --icon-smartphone: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='5' y='2' width='14' height='20' rx='2'/%3E%3Cpath d='M12.5 18h-1'/%3E%3C/svg%3E");
  --icon-pause: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='14' y='4' width='4' height='16' rx='1'/%3E%3Crect x='6' y='4' width='4' height='16' rx='1'/%3E%3C/svg%3E");
  --icon-play: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolygon points='6 3 20 12 6 21 6 3'/%3E%3C/svg%3E");
  /* Lucide « settings-2 » : des réglages que l'on manipule. Préféré à la roue
     dentée, dont les dents deviennent illisibles à 15 pixels. */
  --icon-settings: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 7h-9'/%3E%3Cpath d='M14 17H5'/%3E%3Ccircle cx='17' cy='17' r='3'/%3E%3Ccircle cx='7' cy='7' r='3'/%3E%3C/svg%3E");
  /* Variante petite taille de l'icône ci-dessus, tracé épaissi. */
  --icon-settings-sm: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.75' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 7h-9'/%3E%3Cpath d='M14 17H5'/%3E%3Ccircle cx='17' cy='17' r='3'/%3E%3Ccircle cx='7' cy='7' r='3'/%3E%3C/svg%3E");
  /* Chevron du sélecteur, en image de fond : une image de fond ne peut pas
     hériter de currentColor, la teinte est donc déclinée par thème. */
  --icon-chevron: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%2364748b' stroke-width='2.25' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
  /* Lucide « info », pour les pastilles d'aide du configurateur. */
  --icon-info: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='10'/%3E%3Cpath d='M12 16v-4'/%3E%3Cpath d='M12 8h.01'/%3E%3C/svg%3E");
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
}

html[data-theme="dark"] {
  color-scheme: dark;
  --bg: #0f1117;
  --surface: #0f1117;
  --surface-2: #171a24;
  --text: #f0f3f8;
  --muted: #a3acc2;
  --line: #292d3a;
  --brand: #8798e8;
  --brand-strong: #a4b2f0;
  --brand-soft: #1e2440;
  --step-bg: #1c2634;
  --step-fg: #9fb6cd;
  --callout-bg: #15181f;
  --accent: #fbbf24;
  --danger: #ff8d85;
  --success: #62d49b;
  --icon-chevron: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%2394a3b8' stroke-width='2.25' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
  --shadow: 0 18px 55px rgba(0, 0, 0, .3);
}

* { box-sizing: border-box; }
/* Pas de défilement animé sur les liens d'ancre : un clic dans la navigation
   doit arriver directement sur la section, sans traverser les précédentes.
   Le retour en haut et les résultats de recherche demandent explicitement
   l'animation en JS et restent donc fluides. */
html { scroll-padding-top: calc(var(--header-h) + var(--section-nav-h) + 20px); }
body { margin: 0; background: var(--bg); color: var(--text); font-size: 16px; line-height: 1.68; }
button, input { font: inherit; }
a { color: var(--brand-strong); text-underline-offset: 3px; }
a:hover { text-decoration-thickness: 2px; }

.topbar { position: sticky; top: 0; z-index: 50; height: var(--header-h); display: flex; align-items: center; gap: 18px; padding: 0 24px; background: color-mix(in srgb, var(--surface-2) 94%, transparent); border-bottom: 1px solid var(--line); backdrop-filter: blur(16px); }
.brand { display: flex; align-items: center; min-width: 280px; text-decoration: none; }
.brand:hover { opacity: .78; }
.brand-text { display: flex; align-items: baseline; gap: 9px; line-height: 1; white-space: nowrap; }
.brand-text strong { color: var(--text); font-size: 1.5rem; font-weight: 650; letter-spacing: -.045em; }
.brand-text span { color: var(--brand); font-size: 1.1rem; font-weight: 600; letter-spacing: .005em; text-transform: uppercase; }
.search-shell { position: relative; flex: 1; max-width: 520px; margin-inline: auto; }
.search { position: relative; display: block; width: 100%; }
.search input { width: 100%; height: 38px; padding: 0 40px 0 38px; color: var(--text); background: var(--surface); border: 1px solid var(--line); border-radius: 8px; outline: 0; box-shadow: 0 1px 2px rgba(50,50,93,.06); }
.search input::placeholder { color: color-mix(in srgb, var(--muted) 82%, transparent); }
.search input:focus { border-color: color-mix(in srgb, var(--brand) 70%, var(--line)); box-shadow: 0 0 0 3px color-mix(in srgb, var(--brand) 14%, transparent); }
.search svg { position: absolute; left: 12px; top: 10px; width: 17px; color: var(--muted); }
.search kbd { position: absolute; right: 8px; top: 7px; min-width: 24px; padding: 1px 6px; color: var(--muted); text-align: center; background: var(--surface-2); border: 1px solid var(--line); border-radius: 5px; font-size: .72rem; line-height: 20px; }
.search-results { position: absolute; z-index: 80; top: calc(100% + 8px); left: 0; right: 0; max-height: min(65vh, 520px); overflow-y: auto; padding: 7px; background: var(--surface); border: 1px solid var(--line); border-radius: 12px; box-shadow: 0 18px 48px rgba(50, 50, 93, .18); }
.search-results[hidden] { display: none; }
.search-result { display: block; width: 100%; padding: 11px 12px; color: var(--text); text-align: left; text-decoration: none; background: transparent; border: 0; border-radius: 8px; cursor: pointer; }
.search-result:hover, .search-result[aria-selected="true"] { background: var(--brand-soft); }
.search-result-head { display: flex; align-items: baseline; gap: 10px; margin-bottom: 2px; }
.search-result strong { flex: 1 1 auto; min-width: 0; overflow: hidden; color: var(--text); font-size: .9rem; text-overflow: ellipsis; white-space: nowrap; }
/* Une teinte par univers, dérivée d'une seule variable --tag : le texte est
   mélangé à la couleur de la page, le fond reste un voile. Le contraste suit
   donc automatiquement le thème clair comme le thème sombre. */
.search-result-tag { flex: 0 0 auto; padding: 1px 7px; border-radius: 999px; font-size: .6rem; font-weight: 600; letter-spacing: .05em; text-transform: uppercase; --tag: var(--brand); color: color-mix(in srgb, var(--tag) 76%, var(--text)); background: color-mix(in srgb, var(--tag) 14%, transparent); }
.search-result-tag[data-univers="demarrer"] { --tag: #64748b; }
.search-result-tag[data-univers="boutique"] { --tag: #5469d4; }
.search-result-tag[data-univers="manager"] { --tag: #0d9488; }
.search-result-tag[data-univers="widget"] { --tag: #d97706; }
.search-result-tag[data-univers="securiser"] { --tag: #be123c; }
.search-result-excerpt { display: block; overflow: hidden; color: var(--muted); font-size: .8rem; line-height: 1.4; text-overflow: ellipsis; white-space: nowrap; }
.search-result mark { color: inherit; background: color-mix(in srgb, var(--accent) 32%, transparent); border-radius: 3px; }
.search-suggest-title { margin: 0; padding: 8px 12px 6px; color: var(--muted); font-size: .78rem; font-weight: 600; }
.search-suggestion { display: flex; align-items: center; gap: 12px; }
.search-suggestion svg { flex: 0 0 auto; width: 18px; height: 18px; }
.search-no-result { margin: 0; padding: 18px 14px; color: var(--muted); text-align: center; font-size: .86rem; }
.toolbar { display: flex; gap: 8px; }
.icon-btn { display: grid; place-items: center; width: 42px; height: 42px; color: var(--text); background: var(--surface); border: 1px solid var(--line); border-radius: 12px; cursor: pointer; }
.icon-btn:hover { color: var(--brand-strong); border-color: var(--brand); }
.icon-btn svg { width: 19px; height: 19px; }
/* Bascule de thème : icônes Lucide monochromes, pilotées par le thème courant
   plutôt que par un glyphe que le système rendrait en couleur. */
[data-theme-toggle] span { display: block; width: 19px; height: 19px; background: currentColor; -webkit-mask: var(--icon-moon) center / 19px 19px no-repeat; mask: var(--icon-moon) center / 19px 19px no-repeat; }
html[data-theme="dark"] [data-theme-toggle] span { -webkit-mask-image: var(--icon-sun); mask-image: var(--icon-sun); }
.menu-btn { display: none; }
.section-bar { position: sticky; top: var(--header-h); z-index: 49; display: flex; align-items: stretch; gap: 26px; height: var(--section-nav-h); padding: 0 24px; overflow-x: auto; background: color-mix(in srgb, var(--surface) 96%, transparent); border-bottom: 1px solid var(--line); scrollbar-width: none; }
.section-bar::-webkit-scrollbar { display: none; }
.section-bar a { display: flex; align-items: center; flex: 0 0 auto; color: var(--muted); text-decoration: none; border-bottom: 2px solid transparent; font-size: .86rem; font-weight: 590; }
.section-bar a:hover, .section-bar a.active { color: var(--text); border-color: var(--brand); }

/* Barre latérale collée à gauche, puis le groupe « contenu + sommaire » centré
   dans l'espace restant : les deux pistes 1fr vides absorbent les marges. */
.layout { display: grid; grid-template-columns: 268px minmax(0, 1fr) minmax(0, 980px) auto minmax(0, 1fr); width: 100%; }
/* Pages outils : pas de sommaire à droite, contenu large pour deux colonnes. */
.layout-wide { grid-template-columns: 268px minmax(0, 1fr) minmax(0, 1480px) minmax(0, 1fr); }

.page-toc { grid-column: 4; position: sticky; top: calc(var(--header-h) + var(--section-nav-h)); align-self: start; width: 244px; max-height: calc(100vh - var(--header-h) - var(--section-nav-h)); padding: 52px 24px 40px 4px; overflow-y: auto; }
.page-toc[hidden] { display: none; }
.page-toc-title { margin: 0 0 12px; padding-left: 10px; color: var(--text); font-size: .74rem; font-weight: 700; letter-spacing: .09em; text-transform: uppercase; }
.page-toc-nav { display: grid; gap: 1px; }
.page-toc-nav a { padding: 6px 10px; color: var(--muted); text-decoration: none; font-size: .855rem; line-height: 1.4; border-radius: 6px; }
.page-toc-nav a:hover { color: var(--text); background: var(--surface-2); }
.page-toc-nav a.active { color: var(--brand-strong); font-weight: 650; }
.page-toc-nav a.level-2 { margin-left: 10px; padding-left: 13px; border-left: 1px solid var(--line); border-radius: 0 6px 6px 0; font-size: .825rem; }
.page-toc-nav a.level-2.active { border-left-color: var(--brand); }
.sidebar { position: sticky; top: calc(var(--header-h) + var(--section-nav-h)); height: calc(100vh - var(--header-h) - var(--section-nav-h)); padding: 24px 16px 36px; overflow-y: auto; background: var(--surface); border-right: 1px solid var(--line); }
/* Les univers servent de repères dans une barre latérale longue : l'accent les
   détache des chapitres, qui restent en gris. */
.nav-label { margin: 0 10px 8px; color: var(--brand-strong); font-size: .72rem; font-weight: 700; letter-spacing: 0.05em; text-transform: uppercase; }
.side-nav { display: grid; gap: 3px; margin-bottom: 22px; }
.side-nav a { display: flex; align-items: center; gap: 10px; padding: 7px 11px; color: var(--muted); text-decoration: none; border-radius: 7px; font-size: .88rem; font-weight: 540; line-height: 1.35; }
.side-nav > a > span { display: none; }
.side-nav a:hover { color: var(--text); background: var(--surface-2); }
.side-nav > a.active { color: var(--text); background: transparent; box-shadow: none; font-weight: 760; }
/* Vingt-cinq chapitres et leurs sous-sections dépliées rendaient la barre
   latérale interminable : seules les sous-sections du chapitre courant sont
   visibles. Les autres se déplient en s'y rendant, puisque l'entrée de
   premier niveau est un lien. */
/* Pastille d'état collée à droite de l'entrée : le configurateur rend un vrai
   widget, à la différence des autres chapitres qui ne font que le décrire.
   L'icône remplace le mot, qui reste présent pour les lecteurs d'écran. */
.nav-tag { margin-left: auto; display: inline-flex; align-items: center; justify-content: center; width: 18px; height: 18px; padding: 0; color: var(--brand-strong); background: var(--brand-soft); border-radius: 999px; font-style: normal; }
.nav-tag span { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
/* Même icône que le bouton du configurateur, avec un tracé renforcé : à 11 px
   de côté, l'épaisseur courante de 2 tomberait sous le pixel. */
.nav-tag::before { content: ""; width: 11px; height: 11px; background: currentColor; -webkit-mask: var(--icon-settings-sm) center / 11px 11px no-repeat; mask: var(--icon-settings-sm) center / 11px 11px no-repeat; }
.side-nav > a { position: relative; padding-left: 28px; }
.nav-chevron { position: absolute; left: 6px; top: 50%; width: 18px; height: 18px; margin-top: -9px; border-radius: 5px; cursor: pointer; }
.nav-chevron::before { content: ""; position: absolute; inset: 0; background: currentColor; opacity: .55; -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m9 6 6 6-6 6'/%3E%3C/svg%3E") center / 14px 14px no-repeat; mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m9 6 6 6-6 6'/%3E%3C/svg%3E") center / 14px 14px no-repeat; transition: transform .25s ease, opacity .15s; }
.nav-chevron:hover { background: var(--line); }
.nav-chevron:hover::before { opacity: 1; }
.side-nav > a.is-open .nav-chevron::before { transform: rotate(90deg); }
/* Hauteur animée par grille : 0fr → 1fr évite de mesurer le contenu en JS. */
.nav-subsections { display: grid; grid-template-rows: 0fr; margin: 0 0 0 12px; border-left: 1px solid var(--line); visibility: hidden; opacity: 0; transition: grid-template-rows .28s ease, margin .28s ease, opacity .2s ease, visibility 0s linear .28s; }
.nav-subsections.is-open { grid-template-rows: 1fr; margin: 2px 0 12px 12px; visibility: visible; opacity: 1; transition: grid-template-rows .28s ease, margin .28s ease, opacity .25s ease .05s, visibility 0s; }
.nav-subsections-inner { min-height: 0; overflow: hidden; display: grid; padding-left: 13px; }
.nav-init .nav-subsections, .nav-init .nav-chevron::before { transition: none !important; }
@media (prefers-reduced-motion: reduce) { .nav-subsections, .nav-subsections.is-open, .nav-chevron::before { transition: none; } }
.side-nav .nav-subsections a { padding: 5px 8px; border-radius: 6px; font-size: .8rem; font-weight: 520; }
.side-nav .nav-subsections a.active { box-shadow: none; color: var(--brand-strong); background: transparent; font-weight: 720; }

.content { grid-column: 3; min-width: 0; width: 100%; padding: 52px clamp(28px, 4vw, 68px) 90px; }
.hero { position: relative; overflow: hidden; margin-bottom: 0; padding: 34px 0 46px; color: var(--text); background-color: var(--surface); background-image: radial-gradient(color-mix(in srgb, var(--brand) 22%, transparent) 1px, transparent 1px); background-size: 18px 18px; border-bottom: 1px solid var(--line); }
.hero::after { content: ""; position: absolute; inset: 0; background: linear-gradient(90deg, var(--surface) 0%, transparent 60%, var(--surface) 100%); pointer-events: none; }
.eyebrow { margin: 0 0 10px; color: var(--brand-strong); font-size: .76rem; font-weight: 850; letter-spacing: .12em; text-transform: uppercase; }
.hero .eyebrow { color: var(--brand-strong); }
.hero h1 { position: relative; z-index: 1; max-width: 900px; margin: 0; font-size: clamp(2rem, 3.5vw, 3rem); line-height: 1.08; letter-spacing: -.04em; }
.hero p { position: relative; z-index: 1; max-width: 880px; margin: 16px 0 0; color: var(--muted); font-size: 1.05rem; }

.chapter { margin: 0; padding: 46px 0 58px; background: var(--surface); border-bottom: 1px solid var(--line); }
.chapter[hidden] { display: none; }
.chapter-head { display: block; margin-bottom: 28px; }
.chapter-number { display: none; }
.chapter h2 { margin: 0; font-size: clamp(1.75rem, 2.6vw, 2.2rem); line-height: 1.18; letter-spacing: -.03em; }
.chapter-head p { max-width: 820px; margin: 7px 0 0; color: var(--muted); font-size: 1rem; }
.chapter h3 { margin: 36px 0 12px; font-size: 1.3rem; line-height: 1.3; letter-spacing: -.015em; }
.chapter h4 { margin: 27px 0 9px; font-size: 1.02rem; }
.chapter h5 { margin: 20px 0 8px; font-size: .92rem; color: var(--muted); text-transform: uppercase; letter-spacing: .04em; }
.chapter p { margin: 0 0 13px; }
.lead { color: var(--muted); font-size: 1.05rem; }

.cards { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 14px; margin: 20px 0; }
.card { padding: 18px; background: var(--surface-2); border: 1px solid var(--line); border-radius: 14px; }
.card:has(.card-icon) { display: grid; grid-template-columns: auto minmax(0, 1fr); column-gap: 12px; align-items: start; }
.card:has(.card-icon) > .card-icon { grid-row: 1 / span 2; }
.card:has(.card-icon) > strong, .card:has(.card-icon) > p { grid-column: 2; }
.card-icon { display: grid; place-items: center; margin-top: 1px; color: var(--muted); }
.card-icon svg { width: 26px; height: 26px; }
.card strong { display: block; margin-bottom: 5px; }
.card p { margin: 0; color: var(--muted); font-size: .91rem; }
/* Une ligne par couple mot-clé / valeur : les <b> se placent en colonne 1,
   les <i> en colonne 2, l'alternance du balisage suffit au placement auto. */
.route { display: grid; grid-template-columns: auto minmax(0, 1fr); gap: 5px 14px; margin: 16px 0 22px; padding: 12px 15px; background: var(--brand-soft); border-radius: 10px; font-size: .9rem; }
.route b { color: var(--brand-strong); white-space: nowrap; }
.route i { color: var(--muted); font-style: normal; }
.callout { --callout-color: var(--brand); margin: 20px 0; padding: 12px 16px; background: var(--callout-bg); border-left: 3px solid var(--callout-color); border-radius: 0 8px 8px 0; font-size: .91rem; }
.callout strong { color: color-mix(in srgb, var(--callout-color) 72%, var(--text)); }
.callout.warning { --callout-color: var(--accent); }
.callout.danger, .callout.error { --callout-color: var(--danger); }
.callout.success { --callout-color: var(--success); }
.chapter-toc { margin: 26px 0 30px; padding: 12px 0; border-top: 1px solid var(--line); border-bottom: 1px solid var(--line); }
.chapter-toc > strong { display: block; margin-bottom: 8px; color: var(--muted); font-size: .7rem; font-weight: 700; letter-spacing: .1em; text-transform: uppercase; }
.chapter-toc div { display: flex; flex-wrap: wrap; align-items: center; gap: 7px 20px; }
.chapter-toc a { display: inline-flex; align-items: center; gap: 6px; color: var(--muted); font-size: .86rem; font-weight: 500; text-decoration: none; }
.chapter-toc a::before { content: ""; flex: 0 0 12px; width: 12px; height: 12px; background: currentColor; opacity: .5; -webkit-mask: var(--icon-anchor) center / 12px 12px no-repeat; mask: var(--icon-anchor) center / 12px 12px no-repeat; }
.chapter-toc a:hover { color: var(--brand-strong); }
.chapter-toc a:hover::before { opacity: 1; }
.option-section { margin: 0; padding: 46px 0 24px; border-top: 1px solid var(--line); }
.option-section > h3 { margin: 0 0 20px; font-size: 1.45rem; letter-spacing: -.02em; }
.option-section > h3 span { display: none; }
.option-section.search-focus, .chapter.search-focus { animation: search-focus 1.6s ease-out; }
@keyframes search-focus { 0%, 35% { background: color-mix(in srgb, var(--brand) 9%, transparent); box-shadow: 0 0 0 14px color-mix(in srgb, var(--brand) 9%, transparent); } 100% { background: transparent; box-shadow: 0 0 0 0 transparent; } }
.option-content { padding: 0; }
.option-content h4 { color: var(--brand-strong); }
.field-example { margin: 14px 0; padding: 13px 15px; background: var(--brand-soft); border-radius: 10px; font-size: .91rem; }
.field-example strong { color: var(--brand-strong); }
.technical-list { overflow-wrap: anywhere; line-height: 1.75; }
.steps { list-style: none; counter-reset: steps; padding: 0; margin: 18px 0; }
.steps > li { position: relative; counter-increment: steps; min-height: 26px; margin: 0 0 16px; padding-left: 38px; }
.steps > li::before { content: counter(steps); position: absolute; left: 0; top: 1px; display: grid; place-items: center; width: 24px; height: 24px; color: var(--step-fg); background: var(--step-bg); border-radius: 50%; font-size: .78rem; font-weight: 650; }
.checklist { list-style: none; padding: 0; }
.checklist li { position: relative; margin: 8px 0; padding-left: 28px; }
.checklist li::before { content: "✓"; position: absolute; left: 0; color: var(--success); font-weight: 900; }

.table-wrap { margin: 18px 0 24px; overflow-x: auto; border: 1px solid var(--line); border-radius: 13px; }
table { width: 100%; border-collapse: collapse; min-width: 650px; font-size: .9rem; }
th, td { padding: 12px 14px; vertical-align: top; text-align: left; border-bottom: 1px solid var(--line); }
th { color: var(--text); background: var(--surface-2); font-size: .79rem; letter-spacing: .025em; }
tr:last-child td { border-bottom: 0; }
td:first-child { font-weight: 700; }
/* Première colonne : elle porte des libellés courts, en gras, qui se lisent
   mal coupés sur deux lignes. Une largeur minimale de 20ch tient la grande
   majorité d'entre eux sur une seule ligne ; les rares formulations longues
   passent encore à la ligne, mais en évitant les lignes orphelines. */
th:first-child, td:first-child { min-width: 26ch; }
td:first-child { text-wrap: pretty; }
/* 26ch tient les noms de champs ACF jusqu'à vingt-cinq caractères sur une
   seule ligne, soit la quasi-totalité d'entre eux. La césure reste autorisée
   au-delà : les quelques noms de quarante caractères des modèles d'e-mails
   imposeraient sinon une colonne de trois cents pixels à tout le tableau. */
code { padding: .12em .38em; color: var(--brand-strong); background: var(--brand-soft); border-radius: 5px; font-family: var(--font-mono); font-size: .86em; overflow-wrap: anywhere; }

/* Panneau de code sombre dans les deux thèmes : il se lit immédiatement comme
   du code et ne dépend pas des couleurs de la page. */
.code-block { margin: 18px 0 26px; overflow: hidden; background: var(--code-bg); border: 1px solid var(--code-head); border-radius: 10px; }
.code-block-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 7px 9px 7px 14px; background: var(--code-head); border-bottom: 1px solid var(--code-line); }
.code-lang { color: var(--code-muted); font-family: var(--font-mono); font-size: .7rem; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; }
.copy-btn { display: inline-flex; align-items: center; gap: 6px; padding: 3px 10px; color: var(--code-muted); background: transparent; border: 1px solid var(--code-line); border-radius: 6px; cursor: pointer; font-size: .74rem; font-weight: 600; }
.copy-btn:hover { color: var(--code-fg); border-color: var(--code-muted); }
.copy-btn.copied { color: var(--code-ok); border-color: var(--code-ok); }
.code-block pre { margin: 0; padding: 14px 16px 16px; overflow-x: auto; }
.code-block code { padding: 0; color: var(--code-fg); background: none; border-radius: 0; font-family: var(--font-mono); font-size: .82rem; line-height: 1.55; white-space: pre; overflow-wrap: normal; -webkit-font-smoothing: antialiased; }
.code-block .tok-tag { color: var(--code-tag); }
.code-block .tok-attr { color: var(--code-attr); }
.code-block .tok-string { color: var(--code-string); }
.code-block .tok-comment { color: var(--code-comment); font-style: italic; }

.badge { display: inline-block; padding: 1px 9px; border-radius: 999px; font-size: .69rem; font-weight: 800; letter-spacing: .035em; text-transform: uppercase; white-space: nowrap; }
.badge-req { color: var(--danger); background: color-mix(in srgb, var(--danger) 13%, transparent); }
.badge-opt { color: var(--muted); background: var(--surface-2); border: 1px solid var(--line); }
.badge-new { color: var(--brand-strong); background: var(--brand-soft); }

.swatches { display: grid; grid-template-columns: repeat(auto-fill, minmax(176px, 1fr)); gap: 12px; margin: 20px 0 24px; }
.swatch { display: grid; grid-template-columns: auto minmax(0, 1fr); align-items: center; gap: 12px; padding: 12px 14px; background: var(--surface-2); border: 1px solid var(--line); border-radius: 13px; }
.swatch-dot { width: 26px; height: 26px; border-radius: 50%; background: var(--swatch); box-shadow: inset 0 0 0 1px rgba(0, 0, 0, .12); }
.swatch b { display: block; font-family: var(--font-mono); font-size: .82rem; }
.swatch span { display: block; color: var(--muted); font-size: .76rem; }

/* Appel à l'action mis en avant dans le corps d'un chapitre */
.cta { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 16px; margin: 24px 0 28px; padding: 17px 20px; background: var(--brand-soft); border: 1px solid color-mix(in srgb, var(--brand) 26%, var(--line)); border-radius: 12px; }
.cta div { flex: 1 1 340px; min-width: 0; }
.cta strong { display: block; margin-bottom: 3px; font-size: 1.02rem; }
.cta p { margin: 0; color: var(--muted); font-size: .89rem; }
.cta-link { flex: 0 0 auto; display: inline-flex; align-items: center; gap: 8px; padding: 9px 16px; color: var(--surface); background: var(--brand); border-radius: 9px; font-size: .88rem; font-weight: 650; text-decoration: none; }
.cta-link:hover { background: var(--brand-strong); }
.cta-link-guide::before { display: none; }
/* Réglages en tête, chevron en fin : ce qu'on obtient, puis le fait qu'on
   change de page. Le gap du bouton espace les deux. */
.cta-link::before { content: ""; width: 15px; height: 15px; background: currentColor; -webkit-mask: var(--icon-settings) center / 15px 15px no-repeat; mask: var(--icon-settings) center / 15px 15px no-repeat; }
.cta-link::after { content: ""; width: 13px; height: 13px; background: currentColor; -webkit-mask: var(--icon-anchor) center / 13px 13px no-repeat; mask: var(--icon-anchor) center / 13px 13px no-repeat; }

/* Configurateur de widget : réglages à gauche, aperçu et code à droite. */
/* Les deux colonnes partagent la même hauteur : l'aperçu s'étire pour suivre
   la colonne des réglages, le code restant docké en bas. */
.configurator { display: grid; grid-template-columns: minmax(0, 400px) minmax(0, 1fr); gap: 26px; margin: 24px 0 10px; }
.config-form, .config-side { min-width: 0; }
/* Espacement porté par le conteneur : une marge sur les cartes laisserait un
   vide sous la dernière, et l'aperçu dépasserait d'autant. */
.config-form { display: flex; flex-direction: column; gap: 16px; }
.config-form > .config-pane-head { margin-bottom: 0; }
.config-side { display: flex; flex-direction: column; }
.config-pane { display: flex; flex-direction: column; flex: 1 1 auto; min-width: 0; min-height: 0; }
.config-pane-head { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 12px; margin-bottom: 10px; }
.config-pane-head h3 { margin: 0; font-size: 1.1rem; }
.config-pane-actions { display: flex; flex-wrap: nowrap; align-items: center; gap: 8px; }
/* Respiration après le sélecteur de périmètre, présent au seul type Catalogue. */
.config-field-scope + .config-fields { margin-top: 16px; }
.config-viewport .config-code { margin: 0; border: 0; border-top: 1px solid var(--code-head); border-radius: 0; }
.config-viewport .config-code pre { max-height: 290px; }
/* Scène et code forment un seul bloc : le code est docké sous l'aperçu,
   à la manière d'un terminal sous une fenêtre. */
.config-viewport { display: flex; flex-direction: column; flex: 1 1 auto; min-height: 0; overflow: hidden; border: 1px solid var(--line); border-radius: 12px; }

/* Cadre et messages occupent la même cellule : un message reste centré
   verticalement, y compris pendant le chargement du widget. */
.config-stage { display: grid; grid-template-areas: "stage"; place-items: center; flex: 1 1 auto; min-height: 480px; padding: 22px; overflow: hidden; background-color: var(--surface-2); background-image: radial-gradient(color-mix(in srgb, var(--muted) 24%, transparent) 1px, transparent 1px); background-size: 16px 16px; }
.config-stage[data-bg] { background-image: none; }
.config-stage > * { grid-area: stage; max-width: 100%; }
/* Plein cadre : tout le configurateur occupe la fenêtre, chaque colonne
   défilant pour son compte. Pas l'API Fullscreen, pas toujours autorisée. */
.configurator.is-fullscreen { position: fixed; inset: 0; z-index: 100; grid-template-rows: minmax(0, 1fr); margin: 0; padding: 20px; background: var(--bg); }
.configurator.is-fullscreen .config-form { overflow-y: auto; padding-right: 4px; }
.configurator.is-fullscreen .config-side { min-height: 0; }
body.config-fullscreen { overflow: hidden; }
/* La barre d'actions reste accessible quand la colonne de réglages défile. */
.configurator.is-fullscreen .config-pane-head { position: sticky; top: 0; z-index: 1; padding-bottom: 10px; background: var(--bg); }
/* Le cadre occupe toute la scène : le débordement éventuel se gère à
   l'intérieur, comme dans une vraie fenêtre, sans scroll sur la page. */
.config-frame { display: block; align-self: stretch; justify-self: stretch; width: 100%; border: 0; background: transparent; }
/* Aperçu mobile : le cadre est ramené à la largeur d'un téléphone courant.
   Les media queries du widget répondent à la largeur du cadre, pas à celle
   de la page : réduire le cadre suffit à voir le rendu mobile réel.
   Les dimensions viennent du modèle choisi, la scène les plafonne : un
   téléphone plus haut que la scène se contente de la place disponible. */
.config-stage[data-viewport="mobile"] .config-frame { align-self: start; justify-self: center; margin-block: auto; width: var(--preview-w, 393px); height: var(--preview-h, 852px); max-width: 100%; max-height: none; flex: none; border: 1px solid color-mix(in srgb, var(--text) 14%, transparent); border-radius: 16px; }
/* Sélecteur descendant : .chapter p impose sinon une marge basse qui
   décentrerait le message dans la scène. */
.config-stage .config-stage-note { max-width: 42ch; margin: 0; color: var(--muted); font-size: .88rem; text-align: center; }
.config-stage-note[hidden] { display: none; }
@media (max-width: 1080px) {
  .configurator { grid-template-columns: minmax(0, 1fr); }
}
.config-group { margin: 0; padding: 15px 18px 18px; background: var(--surface-2); border: 1px solid var(--line); border-radius: 12px; }
/* L'attribut hidden doit l'emporter sur les display: grid du formulaire. */
.configurator [hidden] { display: none; }
.config-group[hidden] { display: none; }
.config-group legend { padding: 0 7px; margin-left: -7px; color: var(--text); font-size: .72rem; font-weight: 800; letter-spacing: 0; text-transform: uppercase; }
.config-hint { margin: 10px 0 0; color: var(--muted); font-size: .85rem; }
.config-hint.always { margin: 2px 0 14px; }
.config-hint[hidden] { display: none; }
.config-fields { display: grid; grid-template-columns: repeat(auto-fit, minmax(215px, 1fr)); gap: 14px; }
.config-field { display: grid; gap: 5px; align-content: start; }
.config-field[hidden] { display: none; }
.config-field > span { display: flex; align-items: center; gap: 6px; color: var(--muted); font-size: .77rem; font-weight: 650; }
.config-field em { color: var(--danger); font-style: normal; font-weight: 700; }

/* Pastille d'aide : icône Lucide « info », description au survol ou au focus.
   L'icône passe par ::before pour que le masque n'affecte pas l'infobulle. */
.config-info { position: relative; flex: 0 0 auto; display: grid; place-items: center; width: 15px; height: 15px; padding: 0; color: var(--muted); background: none; border: 0; cursor: pointer; }
.config-info::before { content: ""; width: 15px; height: 15px; background: currentColor; -webkit-mask: var(--icon-info) center / 15px 15px no-repeat; mask: var(--icon-info) center / 15px 15px no-repeat; }
.config-info:hover, .config-info:focus-visible, .config-info.is-open { color: var(--brand-strong); }
.config-info::after { content: attr(data-info); position: absolute; left: 50%; bottom: calc(100% + 8px); z-index: 6; width: max-content; max-width: 250px; padding: 8px 11px; color: var(--surface); background: color-mix(in srgb, var(--text) 93%, transparent); border-radius: 8px; box-shadow: var(--shadow); font-size: .76rem; font-weight: 500; font-style: normal; letter-spacing: 0; line-height: 1.45; text-align: left; text-transform: none; transform: translateX(-50%); opacity: 0; pointer-events: none; transition: opacity .12s ease; }
.config-info.is-open::after { opacity: 1; pointer-events: auto; }
.config-group legend .config-info { margin-left: 7px; vertical-align: middle; }
.configurator input, .configurator select { width: 100%; height: 36px; padding: 0 10px; color: var(--text); background: var(--surface); border: 1px solid var(--line); border-radius: 8px; outline: 0; font-size: .85rem; }
.configurator input::placeholder { color: color-mix(in srgb, var(--muted) 72%, transparent); }
.configurator input:focus, .configurator select:focus { border-color: var(--brand); box-shadow: 0 0 0 3px color-mix(in srgb, var(--brand) 14%, transparent); }

.segmented { display: inline-flex; gap: 2px; margin-top: 4px; padding: 3px; background: var(--surface); border: 1px solid var(--line); border-radius: 10px; }
.segmented label { position: relative; display: block; }
.segmented input { position: absolute; inset: 0; width: 100%; height: 100%; margin: 0; opacity: 0; cursor: pointer; }
.segmented span { display: block; padding: 6px 15px; color: var(--muted); border-radius: 7px; font-size: .84rem; font-weight: 650; }
.segmented input:checked + span { color: var(--brand-strong); background: var(--brand-soft); }
.segmented input:focus-visible + span { box-shadow: 0 0 0 3px color-mix(in srgb, var(--brand) 20%, transparent); }

.config-sites { display: grid; gap: 9px; margin-bottom: 12px; }
/* Un champ par ligne, sur toute la largeur de la colonne de réglages.
   Le bouton de retrait ferme le bloc, aligné à droite. */
.config-site { display: grid; grid-template-columns: minmax(0, 1fr); gap: 8px; padding-bottom: 12px; border-bottom: 1px solid var(--line); }
.config-site:last-child { padding-bottom: 0; border-bottom: 0; }
.config-site [data-remove-site] { justify-self: end; }
.config-site-remove { width: 34px; height: 36px; padding: 0; color: var(--muted); background: var(--surface); border: 1px solid var(--line); border-radius: 8px; cursor: pointer; font-size: 1.05rem; line-height: 1; }
.config-site-remove:hover { color: var(--danger); border-color: var(--danger); }
.config-site-remove[hidden] { display: none; }
.config-btn { padding: 7px 14px; color: var(--brand-strong); background: var(--surface); border: 1px solid var(--line); border-radius: 8px; cursor: pointer; font-size: .82rem; font-weight: 650; }
.config-btn:hover { border-color: var(--brand); }

/* Boutons d'action en icône : l'état est porté par un attribut, le masque suit. */
.config-icon-btn { display: grid; place-items: center; width: 34px; height: 34px; padding: 0; color: var(--muted); background: var(--surface); border: 1px solid var(--line); border-radius: 8px; cursor: pointer; }
.config-icon-btn::before { content: ""; width: 17px; height: 17px; background: currentColor; -webkit-mask-size: 17px 17px; mask-size: 17px 17px; -webkit-mask-position: center; mask-position: center; -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat; }
.config-icon-btn:hover { color: var(--brand-strong); border-color: var(--brand); }
.config-icon-btn:disabled { opacity: .45; cursor: not-allowed; }
.config-icon-btn:disabled:hover { color: var(--muted); border-color: var(--line); }
[data-fullscreen]::before { -webkit-mask-image: var(--icon-maximize); mask-image: var(--icon-maximize); }
[data-fullscreen][aria-pressed="true"]::before { -webkit-mask-image: var(--icon-minimize); mask-image: var(--icon-minimize); }
[data-reset]::before { -webkit-mask-image: var(--icon-reset); mask-image: var(--icon-reset); }
/* Groupe desktop / mobile : deux boutons dans un même cadre, à la manière du
   .segmented des réglages. Le mode retenu porte l'accent, les deux icônes
   restent visibles — on lit l'état sans survoler. */
.config-seg { display: inline-flex; gap: 2px; padding: 2px; background: var(--surface); border: 1px solid var(--line); border-radius: 8px; }
.config-seg-btn { display: grid; place-items: center; width: 30px; height: 28px; padding: 0; color: var(--muted); background: none; border: 0; border-radius: 6px; cursor: pointer; }
.config-seg-btn::before { content: ""; width: 16px; height: 16px; background: currentColor; -webkit-mask-size: 16px 16px; mask-size: 16px 16px; -webkit-mask-position: center; mask-position: center; -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat; }
.config-seg-btn:hover { color: var(--brand-strong); }
.config-seg-btn[aria-pressed="true"] { color: var(--brand-strong); background: var(--brand-soft); }
.config-seg-btn:focus-visible { box-shadow: 0 0 0 3px color-mix(in srgb, var(--brand) 20%, transparent); }
/* Liste des modèles, affichée au seul mode mobile. Largeur sur le contenu :
   les champs du configurateur occupent sinon toute la largeur disponible. */
.configurator .config-device { width: auto; height: 34px; padding: 0 6px; font-size: .8rem; font-weight: 650; }
.configurator .config-device[hidden] { display: none; }
[data-viewport-set="desktop"]::before { -webkit-mask-image: var(--icon-monitor); mask-image: var(--icon-monitor); }
[data-viewport-set="mobile"]::before { -webkit-mask-image: var(--icon-smartphone); mask-image: var(--icon-smartphone); }
[data-preview-toggle]::before { -webkit-mask-image: var(--icon-pause); mask-image: var(--icon-pause); }
[data-preview-toggle][data-state="paused"]::before { -webkit-mask-image: var(--icon-play); mask-image: var(--icon-play); }
[data-stage-bg-reset]::before { -webkit-mask-image: var(--icon-droplet-off); mask-image: var(--icon-droplet-off); }

/* Séparateur entre les actions de l outil et celles de l aperçu. */
.config-sep { width: 1px; align-self: stretch; margin: 0 3px; background: var(--line); }

/* Sélecteur de fond : pastille déclencheuse et popover de teintes. */
.config-bg-picker { position: relative; }
/* Pas d icône masquée ici : seule la pastille de couleur s affiche. */
.config-bg-trigger { padding: 3px; }
.config-bg-trigger::before { content: none; }
.config-bg-chip { width: 100%; height: 100%; border-radius: 5px; background: var(--chip, var(--surface-2)); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--text) 16%, transparent); }
.config-bg-trigger[aria-expanded="true"] { color: var(--brand-strong); border-color: var(--brand); }
.config-bg-popover { position: absolute; top: calc(100% + 8px); right: 0; z-index: 20; width: 262px; padding: 14px; background: var(--surface); border: 1px solid var(--line); border-radius: 12px; box-shadow: 0 18px 48px rgba(50, 50, 93, .2); }
.config-bg-popover[hidden] { display: none; }
.config-bg-title { margin: 0 0 10px; color: var(--muted); font-size: .7rem; font-weight: 800; letter-spacing: .08em; text-transform: uppercase; }
.config-bg-swatches { display: grid; grid-template-columns: repeat(8, 1fr); gap: 5px; }
.config-bg-swatch { height: 23px; padding: 0; background: var(--swatch); border: 1px solid color-mix(in srgb, var(--text) 14%, transparent); border-radius: 5px; cursor: pointer; }
.config-bg-swatch:hover { transform: translateY(-1px); }
.config-bg-swatch[aria-pressed="true"] { box-shadow: 0 0 0 2px var(--surface), 0 0 0 3px var(--brand); }
.config-bg-custom { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin: 14px 0 12px; color: var(--muted); font-size: .8rem; font-weight: 600; }
.config-bg-custom input { width: 42px; height: 28px; padding: 0; background: none; border: 1px solid var(--line); border-radius: 6px; cursor: pointer; }
.config-bg-custom input::-webkit-color-swatch-wrapper { padding: 2px; }
.config-bg-custom input::-webkit-color-swatch { border: 0; border-radius: 4px; }
.config-bg-reset { width: 100%; padding: 8px 10px; color: var(--brand-strong); background: var(--surface-2); border: 1px solid var(--line); border-radius: 8px; cursor: pointer; font-size: .8rem; font-weight: 650; }
.config-bg-reset:hover { border-color: var(--brand); }

/* Terminal repliable : le libellé sert de bascule. */
.config-code-toggle { display: inline-flex; align-items: center; gap: 8px; padding: 0; color: var(--code-muted); background: none; border: 0; cursor: pointer; }
.config-code-toggle::before { content: ""; width: 12px; height: 12px; background: currentColor; -webkit-mask: var(--icon-anchor) center / 12px 12px no-repeat; mask: var(--icon-anchor) center / 12px 12px no-repeat; transform: rotate(90deg); transition: transform .15s ease; }
.config-code-toggle[aria-expanded="false"]::before { transform: rotate(0deg); }
.config-code-toggle:hover { color: var(--code-fg); }
.config-code[data-collapsed="true"] pre { display: none; }

/* Fenêtre d'exemples. <dialog> plutôt qu'une surcouche maison : le fond, le
   piège de tabulation et la fermeture au clavier sont fournis par le
   navigateur. La fenêtre est le seul conteneur qui défile : les blocs de
   texte, eux, s'étendent, pour éviter un ascenseur dans l'ascenseur. */
.modal { width: min(720px, calc(100vw - 28px)); max-height: min(86vh, 820px); padding: 18px 20px 20px; color: var(--text); background: var(--surface); border: 1px solid var(--line); border-radius: 14px; box-shadow: var(--shadow); overflow-y: auto; overscroll-behavior: contain; }
.modal::backdrop { background: rgba(15, 23, 42, .46); backdrop-filter: blur(2px); }
.modal-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 14px; }
.modal-head h5 { margin: 0; font-size: 1.04rem; }
.modal-close { width: 28px; height: 28px; flex: 0 0 auto; padding: 0; color: var(--muted); background: none; border: 1px solid var(--line); border-radius: 7px; cursor: pointer; }
.modal-close:hover { color: var(--text); border-color: var(--muted); }
.modal-intro { margin: 7px 0 0; color: var(--muted); font-size: .84rem; line-height: 1.55; }

/* Sélecteur sobre : libellé discret, chevron dessiné, aucune graisse ni
   capitale qui viendrait concurrencer le titre de la fenêtre. */
.modal-toolbar { display: flex; align-items: center; gap: 10px; margin: 15px 0 13px; padding-bottom: 13px; border-bottom: 1px solid var(--line); }
.modal-toolbar label { flex: 0 0 auto; color: var(--muted); font-size: .82rem; }
.modal-toolbar select { flex: 1 1 auto; min-width: 0; max-width: 300px; height: 34px; padding: 0 30px 0 11px; color: var(--text); background: var(--surface); background-image: var(--icon-chevron); background-repeat: no-repeat; background-position: right 10px center; background-size: 13px 13px; border: 1px solid var(--line); border-radius: 8px; outline: 0; font-size: .85rem; appearance: none; }
.modal-toolbar select:hover { border-color: var(--muted); }
.modal-toolbar select:focus-visible { border-color: var(--brand); box-shadow: 0 0 0 3px color-mix(in srgb, var(--brand) 18%, transparent); }

/* Blocs de texte : fond de page, pas de panneau sombre — ce sont des
   messages clients, et l'habillage suit le thème. */
.modal-body { display: grid; gap: 12px; }
.exemple { background: var(--surface-2); border: 1px solid var(--line); border-radius: 10px; overflow: hidden; }
/* L'en-tête se détache du corps du message : teinte de marque, et le filet
   reste pour marquer la limite même en thème sombre. */
.exemple-head { display: flex; align-items: center; justify-content: space-between; gap: 10px; padding: 7px 8px 7px 12px; background: var(--brand-soft); border-bottom: 1px solid var(--line); }
.exemple-head span { color: var(--brand-strong); font-size: .7rem; font-weight: 700; letter-spacing: .04em; text-transform: uppercase; }
.exemple-copy { padding: 3px 9px; color: var(--muted); background: var(--surface); border: 1px solid var(--line); border-radius: 6px; cursor: pointer; font-size: .72rem; font-weight: 600; }
.exemple-copy:hover { color: var(--text); border-color: var(--muted); }
.exemple-copy.copied { color: var(--success); border-color: var(--success); }
.exemple-texte { padding: 10px 12px 12px; font-size: .84rem; line-height: 1.58; white-space: pre-wrap; overflow-wrap: break-word; }

/* Déclencheur en forme de lien, dans une cellule de tableau. */
.link-btn { padding: 0; color: var(--brand-strong); background: none; border: 0; cursor: pointer; font: inherit; font-weight: 650; text-align: left; text-decoration: underline; text-underline-offset: 3px; }
.link-btn:hover { text-decoration-thickness: 2px; }

.config-result { margin-top: 26px; padding-top: 22px; border-top: 1px solid var(--line); }
.config-result-head { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 12px; }
.config-result-head h3 { margin: 0; font-size: 1.2rem; }

.tabs { margin: 20px 0; border: 1px solid var(--line); border-radius: 14px; overflow: hidden; }
.tab-buttons { display: flex; gap: 0; overflow-x: auto; background: var(--surface-2); border-bottom: 1px solid var(--line); }
.tab-buttons button { flex: 0 0 auto; padding: 12px 15px; color: var(--muted); background: none; border: 0; border-bottom: 3px solid transparent; cursor: pointer; font-weight: 700; }
.tab-buttons button[aria-selected="true"] { color: var(--brand-strong); border-color: var(--brand); background: var(--surface); }
.tab-panel { padding: 19px; }
.tab-panel[hidden] { display: none; }
.tab-panel > :first-child { margin-top: 0; }

.search-empty { display: none; padding: 38px; text-align: center; color: var(--muted); background: var(--surface); border: 1px dashed var(--line); border-radius: var(--radius); }
.search-empty.visible { display: block; }
.related { margin: 10px 0 36px; padding-top: 34px; border-top: 1px solid var(--line); }
.related h2 { margin: 0 0 8px; font-size: 1.35rem; letter-spacing: -.02em; }
.related-intro { max-width: 920px; margin: 0 0 16px; color: var(--muted); font-size: .96rem; line-height: 1.65; }
.related-links { display: grid; gap: 5px; margin: 0; padding: 0; list-style: none; }
.related-links li { margin: 0; padding: 0; }
.related-links a { display: inline-flex; align-items: center; gap: 10px; padding: 2px 0; color: var(--brand); text-decoration: none; font-size: .94rem; font-weight: 690; }
.related-links a:hover { color: var(--brand-strong); text-decoration: underline; text-underline-offset: 4px; }
.related-links svg { flex: 0 0 18px; width: 18px; height: 18px; }
.related-links span { display: inline; }
.footer { padding: 14px 0 0; color: var(--muted); font-size: .82rem; text-align: center; }
.back-top { position: fixed; right: 24px; bottom: 24px; z-index: 30; opacity: 0; pointer-events: none; transition: .2s; }
.back-top.visible { opacity: 1; pointer-events: auto; }

@media (max-width: 1280px) {
  .page-toc { display: none; }
}

@media (max-width: 1050px) {
  .cards { grid-template-columns: 1fr 1fr; }
  .brand { min-width: auto; }
}

@media (max-width: 820px) {
  :root { --header-h: 64px; }
  .topbar { padding: 0 14px; gap: 10px; }
  .brand-text { display: none; }
  .menu-btn { display: grid; }
  .search kbd { display: none; }
  .layout { display: block; }
  .section-bar { gap: 22px; padding-inline: 16px; }
  .sidebar { position: fixed; z-index: 48; top: calc(var(--header-h) + var(--section-nav-h)); left: 0; width: min(86vw, 320px); height: calc(100vh - var(--header-h) - var(--section-nav-h)); background: var(--bg); transform: translateX(-105%); transition: transform .22s ease; box-shadow: 20px 0 50px rgba(0,0,0,.2); }
  body.nav-open .sidebar { transform: translateX(0); }
  body.nav-open::after { content: ""; position: fixed; z-index: 47; inset: calc(var(--header-h) + var(--section-nav-h)) 0 0; background: rgba(0,0,0,.35); }
  .content { padding: 22px 18px 70px; }
  .hero { padding-top: 28px; }
  .chapter { padding: 38px 0 44px; }
  .chapter-head { display: block; }
}

@media (max-width: 560px) {
  .cards { grid-template-columns: 1fr; }
  .chapter-toc div { column-gap: 16px; }
  .config-site { grid-template-columns: minmax(0, 1fr) 34px; }
  .segmented { display: grid; width: 100%; }
  .hero h1 { font-size: 2.1rem; }
  .hero p { font-size: .98rem; }
  .back-top { right: 14px; bottom: 14px; }
}

@media print {
  :root { --bg: #fff; --surface: #fff; --surface-2: #f4f6f7; --text: #111; --muted: #4b5563; --line: #cdd4da; }
  .topbar, .section-bar, .sidebar, .page-toc, .back-top, .tab-buttons, .search-results, .copy-btn { display: none !important; }
  .code-block pre { white-space: pre-wrap; }
  .code-block { background: #fff; border-color: #cdd4da; }
  .code-block-head { background: #f4f6f7; border-bottom-color: #cdd4da; }
  .code-lang { color: #4b5563; }
  .code-block code, .code-block .tok-tag, .code-block .tok-attr, .code-block .tok-string, .code-block .tok-comment { color: #111; }
  .layout { display: block; }
  .content { max-width: none; padding: 0; }
  .hero { color: #111; background: #f6f9fc; box-shadow: none; page-break-after: always; }
  .hero .eyebrow, .hero p { color: #243942; }
  .chapter { border: 0; box-shadow: none; page-break-before: always; }
  .tab-panel[hidden] { display: block; }
  a { color: inherit; text-decoration: none; }
}

/* Adresse de la boutique : bouton de la barre du haut et fenêtre de saisie. */
.toolbar .icon-btn { position: relative; }
.icon-btn.has-store::after { content: ""; position: absolute; top: 7px; right: 7px; width: 8px; height: 8px; background: var(--brand); border: 2px solid var(--surface); border-radius: 50%; box-sizing: content-box; }
.store-modal { width: min(460px, calc(100vw - 28px)); }
.store-label { display: block; margin: 16px 0 6px; color: var(--muted); font-size: .82rem; }
.store-field { display: flex; align-items: stretch; background: var(--surface); border: 1px solid var(--line); border-radius: 8px; overflow: hidden; }
.store-field:focus-within { border-color: var(--brand); box-shadow: 0 0 0 3px color-mix(in srgb, var(--brand) 18%, transparent); }
.store-prefix { display: flex; align-items: center; padding: 0 10px; color: var(--muted); background: var(--surface-2); border-right: 1px solid var(--line); font-family: var(--mono, ui-monospace, monospace); font-size: .84rem; }
.store-field input { flex: 1 1 auto; min-width: 0; height: 38px; padding: 0 11px; color: var(--text); background: transparent; border: 0; outline: 0; font-size: .9rem; }
.store-error { margin: 8px 0 0; color: #be123c; font-size: .8rem; }
.store-actions { display: flex; justify-content: flex-end; gap: 10px; margin-top: 20px; }
.config-btn-primary { color: #fff; background: var(--brand); border-color: var(--brand); }
.config-btn-primary:hover { background: var(--brand-strong); border-color: var(--brand-strong); }
[data-theme="dark"] .config-btn-primary { color: #0f172a; }
.store-modal .modal-head h5 { font-size: 1.15rem; }
.modal-close { display: grid; place-items: center; }
.modal-close svg { width: 16px; height: 16px; }
.store-connected { display: grid; justify-items: center; gap: 4px; padding: 22px 0 2px; text-align: center; }
.store-connected[hidden] { display: none; }
.store-connected-icon { display: grid; place-items: center; width: 56px; height: 56px; margin-bottom: 10px; color: var(--brand-strong); background: var(--brand-soft); border-radius: 50%; }
.store-connected-icon svg { width: 26px; height: 26px; }
.store-connected-title { margin: 0; color: var(--text); font-size: 1rem; font-weight: 650; }
.store-connected-url { margin: 0; max-width: 100%; color: var(--muted); font-size: .88rem; overflow-wrap: anywhere; }
.store-disconnect { width: 100%; margin-top: 18px; padding: 10px 14px; }
[data-store-edit][hidden] { display: none; }
[data-store-link][hidden] { display: none; }

/* Ascenseur discret du panneau de réglages du configurateur : caché au repos,
   visible au survol, avec un espace confortable entre les champs et la barre. */
.config-form { scrollbar-width: thin; scrollbar-color: transparent transparent; }
.config-form:hover { scrollbar-color: color-mix(in srgb, var(--muted) 35%, transparent) transparent; }
.configurator.is-fullscreen .config-form { padding-right: 20px; }
.config-form::-webkit-scrollbar { width: 6px; }
.config-form::-webkit-scrollbar-track { background: transparent; }
.config-form::-webkit-scrollbar-thumb { background: transparent; border-radius: 999px; }
.config-form:hover::-webkit-scrollbar-thumb { background: color-mix(in srgb, var(--muted) 35%, transparent); }
.config-form:hover::-webkit-scrollbar-thumb:hover { background: color-mix(in srgb, var(--muted) 60%, transparent); }

/* Listes déroulantes : bouton et liste dessinés, le <select> natif reste masqué. */
.select { position: relative; width: 100%; min-width: 0; }
.modal-toolbar .select { flex: 1 1 auto; max-width: 300px; }
.select-native { position: absolute; inset: 0; width: 100%; height: 100%; opacity: 0; pointer-events: none; }
.select-trigger { display: flex; align-items: center; justify-content: space-between; gap: 10px; width: 100%; height: 36px; padding: 0 10px 0 12px; color: var(--text); background: var(--surface); border: 1px solid var(--line); border-radius: 8px; cursor: pointer; font: inherit; font-size: .85rem; text-align: left; transition: border-color .15s, box-shadow .15s; }
.modal-toolbar .select-trigger { height: 34px; }
.select-trigger:hover { border-color: var(--muted); }
.select-trigger:focus-visible, .select-trigger[aria-expanded="true"] { border-color: var(--brand); box-shadow: 0 0 0 3px color-mix(in srgb, var(--brand) 16%, transparent); outline: 0; }
.select-trigger:disabled { opacity: .5; cursor: not-allowed; }
.select-value { display: flex; align-items: baseline; gap: 8px; min-width: 0; overflow: hidden; white-space: nowrap; }
.select-main { font-weight: 560; }
.select-desc { overflow: hidden; color: var(--muted); text-overflow: ellipsis; }
.select-chevron { display: grid; flex: 0 0 auto; place-items: center; color: var(--muted); transition: transform .2s ease; }
.select-chevron svg { width: 15px; height: 15px; }
.select-trigger[aria-expanded="true"] .select-chevron { transform: rotate(180deg); color: var(--brand-strong); }
.select-list { position: fixed; z-index: 1000; display: grid; gap: 1px; align-content: start; padding: 5px; overflow-y: auto; background: var(--surface); border: 1px solid var(--line); border-radius: 10px; box-shadow: 0 16px 40px rgba(15, 23, 42, .18), 0 2px 6px rgba(15, 23, 42, .06); animation: select-in .12s ease-out; scrollbar-width: thin; }
.select-list[hidden] { display: none; }
@keyframes select-in { from { opacity: 0; transform: translateY(-4px); } }
.select-option { display: flex; align-items: center; justify-content: space-between; gap: 10px; padding: 8px 10px; color: var(--text); border-radius: 6px; cursor: pointer; font-size: .85rem; line-height: 1.3; }
.select-option-text { display: flex; align-items: baseline; gap: 8px; min-width: 0; }
.select-option.is-active { background: var(--surface-2); }
.select-option[aria-selected="true"] { color: var(--brand-strong); background: var(--brand-soft); }
.select-option[aria-selected="true"] .select-main { font-weight: 700; }
.select-option[aria-disabled="true"] { opacity: .45; cursor: not-allowed; }
.select-check { display: none; flex: 0 0 auto; color: var(--brand-strong); }
.select-option[aria-selected="true"] .select-check { display: grid; }
.select-check svg { width: 15px; height: 15px; }
@media (prefers-reduced-motion: reduce) { .select-list { animation: none; } .select-chevron { transition: none; } }
.select[hidden] { display: none; }
/* Variante compacte : modèle de mobile simulé, sur la même ligne que les outils d'aperçu. */
.select-compact { width: 165px; flex: 0 0 auto; }
.select-compact .select-trigger { height: 34px; padding: 0 8px 0 10px; font-size: .8rem; }
.select-compact .select-desc { display: none; }
.select-compact .select-chevron svg { width: 14px; height: 14px; }

/* Aperçu mobile plus haut que la scène : la scène défile au lieu de réduire le
   téléphone. Le cadre reste centré tant qu'il tient, puis s'aligne en haut. */
.config-stage[data-viewport="mobile"] { overflow: auto; place-items: start center; scrollbar-width: thin; scrollbar-color: color-mix(in srgb, var(--muted) 40%, transparent) transparent; }
.config-stage[data-viewport="mobile"]::-webkit-scrollbar { width: 8px; height: 8px; }
.config-stage[data-viewport="mobile"]::-webkit-scrollbar-thumb { background: color-mix(in srgb, var(--muted) 40%, transparent); border-radius: 999px; }
.config-stage[data-viewport="mobile"]::-webkit-scrollbar-track { background: transparent; }
.config-stage[data-viewport="mobile"] > * { margin-block: auto; }

/* Ascenseur du menu de gauche : fin et discret, mais toujours visible dès que
   le menu défile. */
.sidebar { scrollbar-width: thin; scrollbar-color: color-mix(in srgb, var(--muted) 35%, transparent) transparent; }
.sidebar::-webkit-scrollbar { width: 6px; }
.sidebar::-webkit-scrollbar-track { background: transparent; }
.sidebar::-webkit-scrollbar-thumb { background: color-mix(in srgb, var(--muted) 35%, transparent); border-radius: 999px; }
.sidebar::-webkit-scrollbar-thumb:hover { background: color-mix(in srgb, var(--muted) 60%, transparent); }

/* Scène d'aperçu : même ascenseur discret en desktop et en mobile. */
.config-stage { scrollbar-width: thin; scrollbar-color: color-mix(in srgb, var(--muted) 40%, transparent) transparent; }
.config-stage::-webkit-scrollbar { width: 6px; height: 6px; }
.config-stage::-webkit-scrollbar-track { background: transparent; }
.config-stage::-webkit-scrollbar-thumb { background: color-mix(in srgb, var(--muted) 40%, transparent); border-radius: 999px; }
.config-stage::-webkit-scrollbar-thumb:hover { background: color-mix(in srgb, var(--muted) 65%, transparent); }

/* Sommaire « Sur cette page » : même ascenseur discret que le menu de gauche. */
.page-toc { scrollbar-width: thin; scrollbar-color: color-mix(in srgb, var(--muted) 35%, transparent) transparent; }
.page-toc::-webkit-scrollbar { width: 6px; }
.page-toc::-webkit-scrollbar-track { background: transparent; }
.page-toc::-webkit-scrollbar-thumb { background: color-mix(in srgb, var(--muted) 35%, transparent); border-radius: 999px; }
.page-toc::-webkit-scrollbar-thumb:hover { background: color-mix(in srgb, var(--muted) 60%, transparent); }

/* Desktop : pas de marge en haut, en bas ni à droite, l'ascenseur du cadre occupe toute la hauteur de la scène. */
.config-stage:not([data-viewport="mobile"]) { padding: 0 0 0 22px; }

/* Hors plein écran, l'aperçu a la même hauteur que la colonne des réglages, en
   desktop comme en mobile : la scène prend la place restante et le bloc
   « Code à intégrer » reste collé en bas. Un téléphone plus haut que la scène
   y défile. */
.configurator:not(.is-fullscreen) .config-viewport { flex: 1 1 auto; height: auto; }
.configurator:not(.is-fullscreen) .config-stage { flex: 1 1 0; height: auto; min-height: 480px; }
.config-viewport .config-code { flex: none; margin-top: auto; }
