/* Reset moderne et minimal. */
*,
*::before,
*::after {
  box-sizing: border-box;
}

* {
  margin: 0;
}

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
}

body {
  min-height: 100vh;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

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

input,
button,
textarea,
select {
  font: inherit;
  color: inherit;
}

button {
  cursor: pointer;
  background: none;
  border: none;
}

a {
  color: inherit;
  text-decoration: none;
}

ul,
ol {
  list-style: none;
  padding: 0;
}

:target {
  scroll-margin-top: 5rem;
}

@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }

  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}

/* Jetons de design : couleurs, espacements, rayons, ombres, typographie. */
:root {
  /* Couleurs de marque */
  --color-brand: #1f6feb;
  --color-brand-strong: #1a5fd0;
  --color-brand-soft: #e8f0fe;
  --color-accent: #b8860b;

  /* Surfaces & texte (thème clair) */
  --color-bg: #ffffff;
  --color-bg-muted: #f5f7fa;
  --color-surface: #ffffff;
  --color-border: #e2e6ec;
  --color-text: #1b1f24;
  --color-text-soft: #4a5560;
  --color-text-faint: #6b7685;
  --color-danger: #c02b3a;
  --color-success: #1a7f45;

  /* Typographie */
  --font-sans: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  --font-mono: ui-monospace, "SFMono-Regular", "Consolas", "Liberation Mono", monospace;
  --text-xs: 0.8125rem;
  --text-sm: 0.9375rem;
  --text-base: 1rem;
  --text-lg: 1.125rem;
  --text-xl: 1.375rem;
  --text-2xl: 1.75rem;
  --text-3xl: 2.25rem;
  --text-4xl: 3rem;

  /* Espacements */
  --space-1: 0.25rem;
  --space-2: 0.5rem;
  --space-3: 0.75rem;
  --space-4: 1rem;
  --space-5: 1.5rem;
  --space-6: 2rem;
  --space-8: 3rem;
  --space-10: 4rem;
  --space-12: 6rem;

  /* Divers */
  --radius-sm: 6px;
  --radius-md: 10px;
  --radius-lg: 16px;
  --radius-pill: 999px;
  --shadow-sm: 0 1px 2px rgba(16, 24, 40, 0.06), 0 1px 3px rgba(16, 24, 40, 0.1);
  --shadow-md: 0 4px 12px rgba(16, 24, 40, 0.08), 0 2px 4px rgba(16, 24, 40, 0.06);
  --shadow-lg: 0 12px 32px rgba(16, 24, 40, 0.12);
  --container-max: 1120px;
  --container-narrow: 720px;
  --header-height: 4rem;

  color-scheme: light;
}

/*
 * Thème sombre. Deux déclencheurs, mêmes déclarations (à garder synchronisées) :
 *   1. le système demande le sombre ET l'utilisateur n'a pas forcé le clair ;
 *   2. l'utilisateur a explicitement choisi « sombre » (cookie `theme=dark`,
 *      rendu en `<html data-theme="dark">`).
 * Le thème clair est l'état par défaut de `:root` ; « auto » ne pose aucun
 * attribut. Cf. `src/shared/theme.js` et `public/js/modules/themeSwitch.js`.
 */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --color-brand: #4d94ff;
    --color-brand-strong: #6aa8ff;
    --color-brand-soft: #16263f;
    --color-accent: #e0b64d;

    --color-bg: #0f1115;
    --color-bg-muted: #151922;
    --color-surface: #171b22;
    --color-border: #2a303b;
    --color-text: #e8eaed;
    --color-text-soft: #b3bac4;
    --color-text-faint: #8a94a1;
    --color-danger: #ff6b74;
    --color-success: #4cc27f;

    --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.4);
    --shadow-md: 0 4px 14px rgba(0, 0, 0, 0.45);
    --shadow-lg: 0 16px 40px rgba(0, 0, 0, 0.55);

    color-scheme: dark;
  }
}

:root[data-theme="dark"] {
  --color-brand: #4d94ff;
  --color-brand-strong: #6aa8ff;
  --color-brand-soft: #16263f;
  --color-accent: #e0b64d;

  --color-bg: #0f1115;
  --color-bg-muted: #151922;
  --color-surface: #171b22;
  --color-border: #2a303b;
  --color-text: #e8eaed;
  --color-text-soft: #b3bac4;
  --color-text-faint: #8a94a1;
  --color-danger: #ff6b74;
  --color-success: #4cc27f;

  --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.4);
  --shadow-md: 0 4px 14px rgba(0, 0, 0, 0.45);
  --shadow-lg: 0 16px 40px rgba(0, 0, 0, 0.55);

  color-scheme: dark;
}

/* Clair forcé : neutralise `color-scheme: dark` du système pour les contrôles natifs. */
:root[data-theme="light"] {
  color-scheme: light;
}

body {
  font-family: var(--font-sans);
  font-size: var(--text-base);
  color: var(--color-text);
  background-color: var(--color-bg);
}

h1,
h2,
h3,
h4 {
  line-height: 1.25;
  font-weight: 700;
  color: var(--color-text);
  text-wrap: balance;
}

h1 {
  font-size: var(--text-3xl);
}
h2 {
  font-size: var(--text-2xl);
}
h3 {
  font-size: var(--text-xl);
}

p {
  text-wrap: pretty;
}

a {
  color: var(--color-brand);
}

a:hover {
  color: var(--color-brand-strong);
}

code {
  font-family: var(--font-mono);
  font-size: 0.875em;
  background: var(--color-bg-muted);
  padding: 0.15em 0.4em;
  border-radius: var(--radius-sm);
}

:focus-visible {
  outline: 3px solid var(--color-brand);
  outline-offset: 2px;
  border-radius: var(--radius-sm);
}

.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

.skip-link {
  position: absolute;
  left: var(--space-2);
  top: var(--space-2);
  z-index: 100;
  padding: var(--space-2) var(--space-4);
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  transform: translateY(-150%);
  transition: transform 0.15s ease;
}

.skip-link:focus {
  transform: translateY(0);
}

.muted {
  color: var(--color-text-faint);
}

/* Ossature : conteneurs, sections, grilles génériques. */
.site-main {
  display: block;
  min-height: 60vh;
}

.container {
  width: 100%;
  max-width: var(--container-max);
  margin-inline: auto;
  padding-inline: var(--space-5);
}

.narrow {
  max-width: var(--container-narrow);
  margin-inline: auto;
}

.section {
  padding-block: var(--space-10);
}

.section--muted {
  background: var(--color-bg-muted);
}

.section--center {
  text-align: center;
  padding-block: var(--space-12);
}

.section__head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-4);
  margin-bottom: var(--space-6);
  flex-wrap: wrap;
}

.section__title {
  font-size: var(--text-2xl);
}

.section__link {
  font-size: var(--text-sm);
  font-weight: 600;
}

.section__actions {
  display: flex;
  gap: var(--space-3);
  justify-content: center;
  flex-wrap: wrap;
  margin-top: var(--space-6);
}

.grid {
  display: grid;
  gap: var(--space-5);
}

.grid--cards {
  grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
}

.grid--docs {
  grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
}

.layout-2col {
  display: grid;
  gap: var(--space-8);
  grid-template-columns: minmax(0, 1fr);
}

@media (min-width: 900px) {
  .layout-2col {
    grid-template-columns: minmax(0, 1fr) 320px;
    align-items: start;
  }

  .layout-2col--reverse {
    grid-template-columns: 260px minmax(0, 1fr);
  }
}

.feature-cols {
  display: grid;
  gap: var(--space-6);
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
}

.page-head {
  padding-block: var(--space-8) var(--space-6);
  background: var(--color-bg-muted);
  border-bottom: 1px solid var(--color-border);
}

.page-head__title {
  font-size: var(--text-3xl);
}

.page-head__lead {
  margin-top: var(--space-3);
  max-width: 60ch;
  color: var(--color-text-soft);
  font-size: var(--text-lg);
}

.breadcrumb {
  font-size: var(--text-sm);
  color: var(--color-text-faint);
  margin-bottom: var(--space-2);
}

.empty-state {
  padding: var(--space-6);
  border: 1px dashed var(--color-border);
  border-radius: var(--radius-md);
  color: var(--color-text-faint);
  text-align: center;
}

.big-emoji {
  font-size: 3.5rem;
  margin-bottom: var(--space-3);
}

@media (min-width: 640px) {
  .page-head__title {
    font-size: var(--text-4xl);
  }
}

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  padding: 0.625rem 1.125rem;
  border-radius: var(--radius-md);
  font-weight: 600;
  font-size: var(--text-sm);
  line-height: 1;
  border: 1px solid transparent;
  transition: background-color 0.15s ease, border-color 0.15s ease, transform 0.05s ease;
  white-space: nowrap;
}

.btn:active {
  transform: translateY(1px);
}

.btn--lg {
  padding: 0.85rem 1.5rem;
  font-size: var(--text-base);
}

.btn--primary {
  background: var(--color-brand);
  color: #fff;
}

.btn--primary:hover {
  background: var(--color-brand-strong);
  color: #fff;
}

.btn--ghost {
  background: transparent;
  border-color: var(--color-border);
  color: var(--color-text);
}

.btn--ghost:hover {
  background: var(--color-bg-muted);
  color: var(--color-text);
}

.btn[disabled],
.btn[aria-disabled="true"] {
  opacity: 0.6;
  pointer-events: none;
}

.site-header {
  position: sticky;
  top: 0;
  z-index: 50;
  background: color-mix(in srgb, var(--color-bg) 88%, transparent);
  backdrop-filter: blur(8px);
  border-bottom: 1px solid var(--color-border);
}

.site-header__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  min-height: var(--header-height);
}

/* Marque + sélecteur de langue, groupés à gauche de l'en-tête. */
.site-header__start {
  display: flex;
  align-items: center;
  gap: var(--space-3);
}

.site-header__brand {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  font-weight: 700;
  font-size: var(--text-lg);
  color: var(--color-text);
}

/* Verrou du lien-logo : les trois segments du nom ont leur propre couleur
   fixe (ci-dessous) et ne doivent pas hériter du `a:hover` global. */
.site-header__brand:hover {
  color: var(--color-text);
}

.site-header__logo {
  display: block;
  width: 2rem;
  height: 2rem;
}

/* Les trois segments reprennent les couleurs fixes du logo (valeurs non
   thématisées, cf. `public/images/logo.svg`) : la croix bronze (« Tech »),
   le F gris (vie terrestre, « For »), le F doré (vie éternelle, « Faith »). */
.site-header__name-tech {
  color: #c16700;
}

.site-header__name-for {
  color: #777777;
}

.site-header__name-faith {
  color: #f9bb00;
}

.site-header__toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.5rem;
  height: 2.5rem;
  border-radius: var(--radius-sm);
  border: 1px solid var(--color-border);
}

.site-header__burger,
.site-header__burger::before,
.site-header__burger::after {
  content: "";
  display: block;
  width: 1.1rem;
  height: 2px;
  background: var(--color-text);
  transition: transform 0.15s ease, opacity 0.15s ease;
}

.site-header__burger::before {
  transform: translateY(-6px);
}
.site-header__burger::after {
  transform: translateY(4px);
}

.site-nav {
  display: flex;
  align-items: center;
  gap: var(--space-5);
}

.site-nav__list {
  display: flex;
  align-items: center;
  gap: var(--space-2);
}

.site-nav__link {
  display: inline-block;
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-sm);
  font-size: var(--text-sm);
  font-weight: 500;
  color: var(--color-text-soft);
}

.site-nav__link:hover {
  color: var(--color-text);
  background: var(--color-bg-muted);
}

.site-nav__link.is-active {
  color: var(--color-brand);
  font-weight: 600;
}

/* --- Mobile --- */
@media (max-width: 860px) {
  .site-header__toggle {
    display: inline-flex;
  }

  .site-nav {
    position: absolute;
    inset: var(--header-height) 0 auto 0;
    flex-direction: column;
    align-items: stretch;
    gap: var(--space-3);
    padding: var(--space-4) var(--space-5) var(--space-6);
    background: var(--color-surface);
    border-bottom: 1px solid var(--color-border);
    box-shadow: var(--shadow-md);
    display: none;
  }

  .site-nav.is-open {
    display: flex;
  }

  .site-nav__list {
    flex-direction: column;
    align-items: stretch;
    gap: var(--space-1);
  }

  .site-nav__link {
    padding: var(--space-3);
    font-size: var(--text-base);
  }

  .site-nav__cta {
    width: 100%;
  }
}

@media (min-width: 861px) {
  .site-header__toggle {
    display: none;
  }
}

/*
 * Sélecteur de langue (en-tête, juste après la marque « TechForFaith »).
 *
 * Ouverture au clic uniquement, pilotée par la classe `.is-open`
 * (ajoutée/retirée par `public/js/modules/langSwitch.js`). Pas d'ouverture au
 * survol : cible fugace à la souris, comportement erratique en tactile, et
 * `:focus-within` piégeait le focus clavier. Le bouton porte `aria-expanded`
 * et le module ferme le menu sur Échap, clic extérieur ou sortie de focus.
 */
.lang-switch {
  position: relative;
  display: inline-flex;
}

.lang-switch__current {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 2.5rem;
  padding: var(--space-2) var(--space-3);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  background: var(--color-surface);
  cursor: pointer;
}

.lang-switch__current:hover,
.lang-switch.is-open .lang-switch__current {
  background: var(--color-bg-muted);
  border-color: var(--color-text-faint);
}

/* Code de langue affiché (« fr » → « FR » via la casse). */
.lang-switch__code {
  text-transform: uppercase;
  font-size: var(--text-sm);
  font-weight: 700;
  letter-spacing: 0.03em;
}

.lang-switch__menu {
  position: absolute;
  top: calc(100% + 4px);
  left: 0;
  z-index: 60;
  min-width: 12rem;
  margin: 0;
  padding: var(--space-1);
  list-style: none;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  box-shadow: var(--shadow-md);

  opacity: 0;
  visibility: hidden;
  transform: translateY(-4px);
  transition:
    opacity 0.14s ease,
    transform 0.14s ease,
    visibility 0s linear 0.14s;
}

.lang-switch.is-open .lang-switch__menu {
  opacity: 1;
  visibility: visible;
  transform: translateY(0);
  transition:
    opacity 0.14s ease,
    transform 0.14s ease,
    visibility 0s linear 0s;
}

.lang-switch__option {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-3);
  border-radius: var(--radius-sm);
  font-size: var(--text-sm);
  font-weight: 500;
  color: var(--color-text);
}

.lang-switch__option .lang-switch__code {
  color: var(--color-text-faint);
  min-width: 1.75rem;
}

.lang-switch__option:hover,
.lang-switch__option:focus-visible {
  background: var(--color-bg-muted);
}

@media (prefers-reduced-motion: reduce) {
  .lang-switch__menu,
  .lang-switch.is-open .lang-switch__menu {
    transition: none;
  }
}

/*
 * Sélecteur de thème (en-tête, à côté du sélecteur de langue).
 *
 * Trois choix : automatique / clair / sombre. Ouverture au clic, pilotée par
 * `public/js/modules/themeSwitch.js` (classe `.is-open` + `aria-expanded`).
 * L'icône du bouton reflète `data-value` sur la racine du composant.
 */
.theme-switch {
  position: relative;
  display: inline-flex;
}

.theme-switch__current {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.5rem;
  height: 2.5rem;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  background: var(--color-surface);
  color: var(--color-text-soft);
  cursor: pointer;
}

.theme-switch__current:hover,
.theme-switch.is-open .theme-switch__current {
  background: var(--color-bg-muted);
  border-color: var(--color-text-faint);
  color: var(--color-text);
}

/* Une seule icône visible, selon le thème courant. */
.theme-switch__icon {
  display: none;
}

.theme-switch[data-value="auto"] .theme-switch__icon--auto,
.theme-switch[data-value="light"] .theme-switch__icon--light,
.theme-switch[data-value="dark"] .theme-switch__icon--dark {
  display: block;
}

.theme-switch__menu {
  /* Aligné à droite du bouton : le composant est proche du bord droit de
     l'en-tête sur petit écran, un menu aligné à gauche déborderait. */
  position: absolute;
  top: calc(100% + 4px);
  right: 0;
  z-index: 60;
  min-width: 10rem;
  margin: 0;
  padding: var(--space-1);
  list-style: none;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  box-shadow: var(--shadow-md);

  opacity: 0;
  visibility: hidden;
  transform: translateY(-4px);
  transition:
    opacity 0.14s ease,
    transform 0.14s ease,
    visibility 0s linear 0.14s;
}

.theme-switch.is-open .theme-switch__menu {
  opacity: 1;
  visibility: visible;
  transform: translateY(0);
  transition:
    opacity 0.14s ease,
    transform 0.14s ease,
    visibility 0s linear 0s;
}

.theme-switch__option {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  width: 100%;
  padding: var(--space-3);
  border-radius: var(--radius-sm);
  font-size: var(--text-sm);
  font-weight: 500;
  color: var(--color-text);
  text-align: left;
  cursor: pointer;
}

.theme-switch__option:hover,
.theme-switch__option:focus-visible {
  background: var(--color-bg-muted);
}

.theme-switch__option[aria-checked="true"] {
  color: var(--color-brand);
  font-weight: 600;
}

/* Puce « choix actif ». */
.theme-switch__option::before {
  content: "";
  width: 0.5rem;
  height: 0.5rem;
  border-radius: 50%;
  background: currentColor;
  opacity: 0;
  flex-shrink: 0;
}

.theme-switch__option[aria-checked="true"]::before {
  opacity: 1;
}

@media (prefers-reduced-motion: reduce) {
  .theme-switch__menu,
  .theme-switch.is-open .theme-switch__menu {
    transition: none;
  }
}

.site-footer {
  margin-top: var(--space-12);
  background: var(--color-bg-muted);
  border-top: 1px solid var(--color-border);
}

.site-footer__inner {
  display: grid;
  gap: var(--space-6);
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  padding-block: var(--space-8);
}

.site-footer__brand {
  font-weight: 700;
  font-size: var(--text-lg);
}

.site-footer__tagline {
  margin-top: var(--space-2);
  color: var(--color-text-faint);
  font-size: var(--text-sm);
  max-width: 40ch;
}

.site-footer__heading {
  font-weight: 600;
  font-size: var(--text-sm);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--color-text-faint);
  margin-bottom: var(--space-3);
}

.site-footer__list {
  display: grid;
  gap: var(--space-2);
  font-size: var(--text-sm);
}

.site-footer__list a {
  color: var(--color-text-soft);
}

.site-footer__list a:hover {
  color: var(--color-brand);
}

.site-footer__bottom {
  padding-block: var(--space-4);
  border-top: 1px solid var(--color-border);
  font-size: var(--text-xs);
  color: var(--color-text-faint);
}

.card {
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  padding: var(--space-6);
  box-shadow: var(--shadow-sm);
}

/* Carte d'extension */
.ext-card {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  padding: var(--space-5);
  box-shadow: var(--shadow-sm);
  transition: box-shadow 0.15s ease, transform 0.15s ease, border-color 0.15s ease;
}

.ext-card:hover {
  box-shadow: var(--shadow-md);
  transform: translateY(-2px);
  border-color: color-mix(in srgb, var(--color-brand) 40%, var(--color-border));
}

.ext-card__head {
  display: flex;
  gap: var(--space-3);
  align-items: flex-start;
}

.ext-card__icon {
  width: 48px;
  height: 48px;
  border-radius: var(--radius-md);
  flex-shrink: 0;
}

.ext-card__icon--placeholder {
  display: grid;
  place-items: center;
  background: var(--color-brand-soft);
  color: var(--color-brand);
  font-size: 1.5rem;
}

.ext-card__title {
  font-size: var(--text-lg);
}

.ext-card__tagline {
  color: var(--color-text-faint);
  font-size: var(--text-sm);
}

.ext-card__summary {
  color: var(--color-text-soft);
  font-size: var(--text-sm);
  flex-grow: 1;
}

.ext-card__footer {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}

.ext-card__more {
  font-size: var(--text-sm);
  font-weight: 600;
}

/* Colonnes latérales & encarts */
.side-card {
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  padding: var(--space-5);
}

.side-card__title {
  font-size: var(--text-base);
  margin-bottom: var(--space-3);
}

.side-card__list {
  display: grid;
  gap: var(--space-2);
  font-size: var(--text-sm);
}

.side-card__list--plain {
  list-style: disc;
  padding-left: 1.1rem;
  color: var(--color-text-soft);
}

.side-card__note {
  margin-top: var(--space-3);
  font-size: var(--text-xs);
  color: var(--color-text-faint);
}

/* Bandeau d'appel au don */
.cta-band__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-6);
  flex-wrap: wrap;
  background: var(--color-brand-soft);
  border: 1px solid color-mix(in srgb, var(--color-brand) 25%, var(--color-border));
  border-radius: var(--radius-lg);
  padding: var(--space-6);
}

.cta-band__title {
  font-size: var(--text-xl);
}

.cta-band__text {
  margin-top: var(--space-2);
  color: var(--color-text-soft);
  max-width: 52ch;
}

.feature__title {
  font-size: var(--text-base);
  margin-bottom: var(--space-2);
}

.feature__link {
  display: inline-block;
  margin-top: var(--space-2);
  font-size: var(--text-sm);
  font-weight: 600;
}

.doc-index-card {
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  padding: var(--space-5);
}

.doc-index-card__title {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  font-size: var(--text-lg);
  margin-bottom: var(--space-2);
}

.doc-index-card__icon {
  width: 1.2em;
  height: 1.2em;
  border-radius: var(--radius-sm);
  flex-shrink: 0;
}

.doc-index-card__icon--placeholder {
  display: grid;
  place-items: center;
  background: var(--color-brand-soft);
  color: var(--color-brand);
  font-size: 0.75em;
}

.doc-index-card__text {
  color: var(--color-text-soft);
  font-size: var(--text-sm);
  margin-bottom: var(--space-3);
}

.badge-row {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
}

.badge {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  padding: 0.4rem 0.75rem;
  border-radius: var(--radius-pill);
  font-size: var(--text-xs);
  font-weight: 600;
  border: 1px solid var(--color-border);
  background: var(--color-surface);
  color: var(--color-text-soft);
}

.badge:hover {
  border-color: var(--color-brand);
  color: var(--color-brand);
}

.badge--chrome::before {
  content: "";
  width: 0.6rem;
  height: 0.6rem;
  border-radius: 50%;
  background: conic-gradient(#ea4335 0 25%, #fbbc05 0 50%, #34a853 0 75%, #4285f4 0 100%);
}

.badge--firefox::before {
  content: "🦊";
}

.form {
  display: flex;
  flex-direction: column;
  gap: var(--space-5);
}

.form__title {
  font-size: var(--text-xl);
}

.form__group {
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  padding: var(--space-4);
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}

.form__legend {
  font-weight: 600;
  font-size: var(--text-sm);
  padding-inline: var(--space-2);
}

.form__field {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}

.form__field--inline {
  flex-direction: row;
  align-items: center;
  gap: var(--space-3);
}

.form__row {
  display: grid;
  gap: var(--space-4);
}

@media (min-width: 560px) {
  .form__row {
    grid-template-columns: 1fr 1fr;
  }
}

.form__label {
  font-weight: 600;
  font-size: var(--text-sm);
  color: var(--color-text-soft);
}

.form input[type="text"],
.form input[type="email"],
.form input[type="number"],
.form textarea,
.form select {
  width: 100%;
  padding: 0.6rem 0.75rem;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  background: var(--color-bg);
  transition: border-color 0.15s ease, box-shadow 0.15s ease;
}

.form input:focus,
.form textarea:focus,
.form select:focus {
  outline: none;
  border-color: var(--color-brand);
  box-shadow: 0 0 0 3px var(--color-brand-soft);
}

.form textarea {
  resize: vertical;
  min-height: 7rem;
}

.form :is(input, textarea, select)[aria-invalid="true"] {
  border-color: var(--color-danger);
}

.field-error {
  color: var(--color-danger);
  font-size: var(--text-xs);
}

.choice-row {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
}

.choice-col {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}

.choice {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  padding: 0.5rem 0.85rem;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-pill);
  font-size: var(--text-sm);
  cursor: pointer;
  user-select: none;
}

.choice--block {
  border-radius: var(--radius-sm);
  width: 100%;
}

.choice:has(input:checked) {
  border-color: var(--color-brand);
  background: var(--color-brand-soft);
  color: var(--color-brand);
  font-weight: 600;
}

.choice:has(input:focus-visible) {
  outline: 3px solid var(--color-brand);
  outline-offset: 2px;
}

.choice input {
  accent-color: var(--color-brand);
}

.form__submit {
  align-self: flex-start;
}

.form__status {
  font-size: var(--text-sm);
  min-height: 1.25rem;
}

.form__status.is-error {
  color: var(--color-danger);
}

.form__status.is-success {
  color: var(--color-success);
}

.form__hint,
.doc-article__help {
  font-size: var(--text-xs);
  color: var(--color-text-faint);
}

.form__field--honeypot {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

/* Astérisque « champ obligatoire » */
.form__req {
  color: var(--color-danger);
  margin-left: 0.15em;
  font-weight: 700;
}

/* Compteur de caractères (ajouté par contactForm.js sous la zone de texte) */
.char-counter {
  align-self: flex-end;
  font-variant-numeric: tabular-nums;
}

.char-counter.is-warning {
  color: var(--color-danger);
  font-weight: 600;
}

/* Bouton pendant l'envoi : libellé « Envoi en cours… » + disque tournant */
.btn.is-busy {
  pointer-events: none;
}

.btn.is-busy::before {
  content: "";
  width: 1em;
  height: 1em;
  border: 2px solid currentColor;
  border-inline-end-color: transparent;
  border-radius: 50%;
  animation: btn-spin 0.6s linear infinite;
}

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

/* Panneau de confirmation qui remplace le formulaire après un envoi réussi */
.form-success {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-3);
  text-align: center;
}

.form-success__icon {
  display: grid;
  place-items: center;
  width: 3rem;
  height: 3rem;
  border-radius: var(--radius-pill);
  background: color-mix(in srgb, var(--color-success) 18%, transparent);
  color: var(--color-success);
  font-size: var(--text-xl);
  font-weight: 700;
}

.form-success__title {
  font-size: var(--text-xl);
}

.form-success__title:focus-visible {
  outline: none;
}

.form-success .btn {
  margin-top: var(--space-2);
}

.hero {
  position: relative;
  /* Piège tous les calques décoratifs (étoiles, nuages, cadeaux, avion —
     z-index négatifs, échelle détaillée plus bas) au-dessus du fond mais sous
     le contenu, sans toucher au z-index du texte. `overflow` borne la chute
     du cadeau à la section. */
  isolation: isolate;
  overflow: hidden;
  padding-block: var(--space-12);
  /* Ciel bleu en clair : accent de marque en haut à droite + dégradé qui reste
     bleu du haut jusqu'en bas (pas de fondu vers le blanc), avec un écart de
     teinte assez marqué pour que le haut et le bas restent visiblement
     distincts (bleu soutenu → bleu pâle). */
  --hero-sky-bg:
    radial-gradient(60rem 30rem at 80% -10%, var(--color-brand-soft), transparent 60%),
    linear-gradient(180deg, #4a97e8 0%, #7ec0f2 50%, #bfe0fa 100%);
  background: var(--hero-sky-bg);
  border-bottom: 1px solid var(--color-border);
  /* Les `cloudN.svg` ont une teinte unie pensée pour le ciel nocturne ; sur le
     ciel bleu clair ils manquent de contraste. Les nuages étant opaques (pas
     de transparence), c'est uniquement `brightness`/`saturate` qui les
     éclaircit et qui distingue le fond (plus délavé, lointain) du premier
     plan (plus présent) — l'effet de profondeur que l'opacité donnait avant. */
  --hero-cloud-tint-far: brightness(1.4) saturate(0.55);
  --hero-cloud-tint-near: brightness(1.75) saturate(0.35);
  /* `--color-brand` (bleu marque) manque de contraste sur le ciel clair : un
     bleu plus foncé rien que pour ce label. En sombre, `--color-brand` (déjà
     clair sur fond nuit) reste inchangé — voir les deux resets ci-dessous. */
  --hero-eyebrow-color: #0d3f8f;
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .hero {
    /* Ciel étoilé en sombre : même accent de marque, dégradé nuit profonde. */
    --hero-sky-bg:
      radial-gradient(60rem 30rem at 80% -10%, var(--color-brand-soft), transparent 60%),
      linear-gradient(180deg, #060b18 0%, #101b30 50%, var(--color-bg) 100%);
    /* Nuages opaques : sans la transparence d'avant pour laisser deviner le
       ciel nocturne derrière, la couleur d'origine des SVG paraît trop claire
       — il faut l'assombrir nous-mêmes, un peu plus encore pour le fond. */
    --hero-cloud-tint-far: brightness(0.55) saturate(0.85);
    --hero-cloud-tint-near: brightness(0.75) saturate(0.9);
    --hero-eyebrow-color: var(--color-brand);
  }

  :root:not([data-theme="light"]) .hero__stars {
    opacity: 1;
  }

  /* Durée et délai négatif (déphasage de départ) posés en inline par
     `heroClouds.js#spawnStars`, propres à chaque étoile ; l'animation n'est
     nommée qu'ici pour ne jamais tourner en clair (calque invisible). */
  :root:not([data-theme="light"]) .hero__star {
    animation-name: hero-star-twinkle;
    animation-timing-function: ease-in-out;
    animation-iteration-count: infinite;
  }
}

:root[data-theme="dark"] .hero {
  --hero-sky-bg:
    radial-gradient(60rem 30rem at 80% -10%, var(--color-brand-soft), transparent 60%),
    linear-gradient(180deg, #060b18 0%, #101b30 50%, var(--color-bg) 100%);
  --hero-cloud-tint-far: brightness(0.55) saturate(0.85);
  --hero-cloud-tint-near: brightness(0.75) saturate(0.9);
  --hero-eyebrow-color: var(--color-brand);
}

:root[data-theme="dark"] .hero__stars {
  opacity: 1;
}

:root[data-theme="dark"] .hero__star {
  animation-name: hero-star-twinkle;
  animation-timing-function: ease-in-out;
  animation-iteration-count: infinite;
}

/*
 * Échelle de profondeur commune à tous les calques décoratifs du hero — un
 * seul axe de `z-index` négatifs (donc sous `.hero__inner`, resté en
 * position statique : voir le commentaire sur `.hero` plus haut), plutôt
 * qu'un `z-index` partagé départagé par l'ordre du DOM. Fragile autrement :
 * cadeaux, avion et étoile filante sont ajoutés dynamiquement, à des moments
 * qui dépendent du hasard. Du plus profond au plus proche :
 *   1. étoiles fixes (`.hero__stars`)
 *   2. étoile filante (`.hero-shooting-star`)
 *   3. nuages de fond (`.hero-cloud--far`)
 *   4. cadeaux tombés d'un nuage de fond (`.hero__gift--far`)
 *   5. nuages de premier plan (`.hero-cloud--near`)
 *   6. cadeaux tombés d'un nuage de premier plan (`.hero__gift--near`)
 *   7. avion (`.hero__plane`)
 * Suppose que `.hero__sky` (conteneur des nuages) ne forme pas son propre
 * contexte d'empilement — voir son commentaire plus bas — sans quoi les deux
 * flots de nuages ne pourraient jamais s'intercaler avec les cadeaux et
 * l'avion, posés directement dans `.hero`.
 */

/* Étoiles : chacune est un `<span class="hero__star">` généré par
   `heroClouds.js#spawnStars` (position, taille, durée et déphasage
   aléatoires posés en inline) — pas un semis figé dans le CSS — pour qu'elles
   scintillent réellement indépendamment les unes des autres plutôt que par
   blocs synchronisés. Invisibles en clair (`opacity: 0` sur le calque),
   révélées en sombre par les sélecteurs plus haut. */
.hero__stars {
  position: absolute;
  inset: 0;
  z-index: -7;
  pointer-events: none;
  opacity: 0;
}

.hero__star {
  position: absolute;
  border-radius: 50%;
  background: radial-gradient(circle, #fff, transparent 70%);
}

/* `--star-twinkle-min` (posée en inline, une valeur différente par étoile)
   fait varier la profondeur du creux en plus de sa phase et de sa durée. */
@keyframes hero-star-twinkle {
  0%,
  100% {
    opacity: 1;
  }

  50% {
    opacity: var(--star-twinkle-min, 0.3);
  }
}

/*
 * Nuages animés : `.hero__sky` est un calque vide dont `modules/heroClouds.js`
 * remplit deux flots indépendants (fond « far », premier plan « near ») en y
 * insérant des `<img class="hero-cloud">` — image, taille, position verticale
 * et durée choisies au hasard, à intervalle aléatoire — puis en les retirant à
 * la fin de leur trajet (`animationend`). Sans motif de fond répétitif, les
 * espacements entre nuages ne se reproduisent jamais à l'identique. Nuages
 * opaques (pas de fondu du calque ni de transparence par nuage) : la
 * profondeur vient de `--hero-cloud-tint-*` (fond plus délavé/sombre) et du
 * flou du fond, pas de la transparence. Figé si `prefers-reduced-motion` (le
 * module pose alors quelques nuages fixes ; voir bloc plus bas).
 *
 * Pas de `z-index` ici (contrairement aux autres calques du hero) : avec
 * `position: absolute` seul, cet élément ne forme pas son propre contexte
 * d'empilement, donc le `z-index` de chaque `.hero-cloud--far`/`--near` se
 * compare directement à ceux des cadeaux/avion/étoile filante — posés, eux,
 * directement dans `.hero` — plutôt qu'au niveau du calque entier. Condition
 * nécessaire à l'échelle de profondeur ci-dessus.
 */
.hero__sky {
  position: absolute;
  inset: 0;
  overflow: hidden;
  pointer-events: none;
}

.hero-cloud {
  position: absolute;
  top: 0;
  height: auto;
  pointer-events: none;
  will-change: transform;
  animation-timing-function: linear;
  animation-fill-mode: forwards;
}

/* Les deux plans défilent dans le même sens, de gauche à droite. Démarrent
   juste avant le bord gauche (`right: 100%`) ; la translation ajoute une
   largeur de viewport puis une largeur d'image → ressortent toujours
   entièrement à droite, quelle que soit la largeur réelle du hero. */
.hero-cloud--far,
.hero-cloud--near {
  right: 100%;
  animation-name: hero-cloud-drift-right;
}

/* Fond : plus petit, plus lent, flouté et délavé par `--hero-cloud-tint-far`
   pour suggérer l'éloignement (nuages opaques : pas de transparence ici). */
.hero-cloud--far {
  z-index: -5;
  filter: blur(0.4px) var(--hero-cloud-tint-far);
}

/* Premier plan : plus grand, plus rapide, teinte plus présente. */
.hero-cloud--near {
  z-index: -3;
  filter: var(--hero-cloud-tint-near);
}

@keyframes hero-cloud-drift-right {
  to {
    transform: translateX(calc(100vw + 100%));
  }
}

/*
 * Un cadeau tombe occasionnellement d'un nuage qui passe hors de la colonne
 * de texte (`.hero__inner` dans `heroClouds.js#checkGiftZones`), là où le
 * module accroche un `<span class="hero__gift hero__gift--far">` (ou
 * `--near`) positionné sur le nuage au moment du déclenchement (`left`/`top`
 * et durée posés en inline par le JS) — le modificateur reprend la lane du
 * nuage d'origine, pour hériter sa place dans l'échelle de profondeur
 * (au-dessus de `.hero__stars`) plutôt que de dépendre de l'ordre du DOM.
 * `--gift-fall` (px) est calculée par le module pour que la chute atteigne la
 * limite basse du hero avant de disparaître, quelle que soit la hauteur du
 * nuage de départ — une distance fixe ne convient qu'à un seul cas. Chute
 * unique, non bouclée : l'élément est retiré à la fin de l'animation
 * (`animationend`). Comme cette chute n'existe qu'en réaction au déplacement
 * des nuages, elle ne se produit jamais quand `prefers-reduced-motion` a
 * figé les nuages (voir plus bas) — pas besoin de la couper explicitement.
 */
.hero__gift {
  position: absolute;
  width: 26px;
  height: 32px;
  pointer-events: none;
  background: url("/images/hero/gift.svg") center / contain no-repeat;
  --gift-fall: 220px;
  animation-name: hero-gift-drop;
  /* `linear`, pas `ease-in` : une fonction de temporisation s'applique à
     *chaque* segment entre deux points de passage, pas à l'animation entière.
     Avec `ease-in` ici, chaque palier (10 %, 60 %, 90 %) ré-accélérait depuis
     zéro puis freinait brusquement juste avant le suivant — d'autant plus
     visible que `--gift-fall` est grand. L'accélération de la chute vient
     déjà de l'écartement volontairement inégal des valeurs `translate` dans
     `@keyframes` ci-dessous ; `linear` se contente d'interpoler entre elles
     sans ajouter de courbe supplémentaire. */
  animation-timing-function: linear;
  animation-fill-mode: forwards;
}

.hero__gift--far {
  z-index: -4;
}

.hero__gift--near {
  z-index: -2;
}

@keyframes hero-gift-drop {
  0% {
    opacity: 0;
    transform: translate(0, -8px) rotate(-14deg);
  }
  10% {
    opacity: 1;
    transform: translate(3px, calc(var(--gift-fall) * 0.05)) rotate(-6deg);
  }
  60% {
    opacity: 1;
    transform: translate(-4px, calc(var(--gift-fall) * 0.55)) rotate(6deg);
  }
  90% {
    opacity: 1;
    transform: translate(4px, calc(var(--gift-fall) * 0.85)) rotate(13deg);
  }
  100% {
    opacity: 0;
    transform: translate(6px, var(--gift-fall)) rotate(17deg);
  }
}

/*
 * Étoile filante : de temps en temps, un trait lumineux traverse le ciel
 * nocturne (`heroClouds.js#scheduleShootingStars`, sombre uniquement),
 * toujours sous les nuages et les cadeaux mais au-dessus des étoiles fixes
 * (voir l'échelle de profondeur au-dessus de `.hero__stars`). Un seul élément
 * suffit à l'effet : une barre dégradée (transparent → blanc) déjà orientée
 * selon l'angle de trajectoire, qui se contente de glisser le long de son
 * propre axe — la partie opaque devient la « tête », la partie transparente
 * le sillage, sans second élément ni calcul de rotation séparé.
 */
.hero-shooting-star {
  position: absolute;
  top: 0;
  left: 0;
  height: 2px;
  z-index: -6;
  pointer-events: none;
  background: linear-gradient(90deg, transparent, rgb(255 255 255 / 90%) 70%, #fff);
  border-radius: 2px;
  animation-name: hero-shooting-star-move;
  animation-timing-function: linear;
  animation-fill-mode: forwards;
}

@keyframes hero-shooting-star-move {
  0% {
    opacity: 0;
    transform: translate(0, 0) rotate(25deg);
  }
  12% {
    opacity: 1;
  }
  80% {
    opacity: 1;
  }
  100% {
    opacity: 0;
    transform: translate(var(--shoot-distance), calc(var(--shoot-distance) * 0.4663)) rotate(25deg);
  }
}

/*
 * Avion, thème clair uniquement : `heroClouds.js#schedulePlane` fait
 * traverser le ciel de temps en temps à un biplan qui tire une banderole
 * (texte localisé, lu depuis `data-plane-banner` sur `.hero`, posé par
 * `home.html` — jamais en dur ici). Même traversée que les nuages, gauche →
 * droite : `.hero__plane` réutilise directement `hero-cloud-drift-right`,
 * pas besoin d'un second keyframe pour la même trajectoire. À l'intérieur,
 * banderole, corde et fuselage sont positionnés à taille fixe par rapport au
 * conteneur (l'hélice fait partie du SVG `plane.svg`, pas un élément animé
 * séparé) :
 *   - la banderole garde un rectangle plein pour le texte (lisibilité dans
 *     les deux langues) et gagne juste une pointe « queue d'aronde » côté
 *     libre (`::before` + `clip-path`) plutôt qu'un simple rectangle ;
 *   - la corde devient une bride en V (`rope.svg`, même pattern que
 *     `plane.svg`/`gift.svg` en `background-image`) : deux brins reliant le
 *     haut et le bas de la banderole à la queue de l'avion, avec un léger
 *     affaissement et une texture torsadée, au lieu d'un simple trait.
 * Toujours devant nuages et cadeaux (voir l'échelle de profondeur au-dessus
 * de `.hero__stars`).
 */
.hero__plane {
  position: absolute;
  right: 100%;
  width: 330px;
  height: 60px;
  z-index: -1;
  pointer-events: none;
  animation-name: hero-cloud-drift-right;
  animation-timing-function: linear;
  animation-fill-mode: forwards;
}

.hero__plane-banner {
  position: absolute;
  left: 26px;
  top: 8px;
  width: 160px;
  height: 34px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: #fff;
  border-radius: 2px 6px 6px 2px;
  color: #8a1414;
  font-weight: 700;
  font-size: 0.95rem;
  letter-spacing: 0.04em;
  white-space: nowrap;
  padding-inline: 8px;
  /* Flottement façon tissu, indépendant du défilement horizontal (l'avion
     entier dérive via `hero-cloud-drift-right`) : rotation autour du bord
     d'attache (à droite, côté bride) pour que la pointe libre (`::before`)
     soit la partie qui débat le plus, comme un fanion tenu par un seul bord.
     Le déplacement induit à l'attache (bord de rotation) reste sous le pixel
     à cette amplitude : la bride en V, dessin statique, n'a pas besoin de
     suivre. */
  transform-origin: 100% 50%;
  animation: hero-flag-flutter 2.6s ease-in-out infinite;
}

/* Pointe « queue d'aronde » du bord libre de la banderole : seule cette
   pointe est découpée (`clip-path`), le rectangle du texte reste intact pour
   rester lisible dans les deux langues. Même fond que la banderole — couleur
   dupliquée plutôt que `currentColor`, déjà utilisé par le texte. */
.hero__plane-banner::before {
  content: "";
  position: absolute;
  left: -26px;
  top: 0;
  width: 26px;
  height: 100%;
  background: #fff;
  clip-path: polygon(100% 0%, 100% 100%, 0% 80%, 45% 50%, 0% 20%);
}

@keyframes hero-flag-flutter {
  0%,
  100% {
    transform: rotate(-1.6deg);
  }

  50% {
    transform: rotate(1.6deg);
  }
}

.hero__plane-rope {
  position: absolute;
  left: 186px;
  top: 0;
  width: 49px;
  height: 60px;
  background: url("/images/hero/rope.svg") center / 100% 100% no-repeat;
}

.hero__plane-body {
  position: absolute;
  left: 226px;
  top: 6px;
  width: 90px;
  height: 45px;
  background: url("/images/hero/plane.svg") center / contain no-repeat;
}

@media (prefers-reduced-motion: reduce) {
  .hero-cloud,
  .hero__star,
  .hero__plane,
  .hero__plane-banner {
    animation: none;
  }

  .hero-shooting-star {
    display: none;
  }
}

.hero__inner {
  max-width: 46rem;
}

.hero__eyebrow {
  text-transform: uppercase;
  letter-spacing: 0.08em;
  font-size: var(--text-xs);
  font-weight: 700;
  color: var(--hero-eyebrow-color);
  margin-bottom: var(--space-3);
}

.hero__title {
  font-size: var(--text-3xl);
  letter-spacing: -0.01em;
}

.hero__lead {
  margin-top: var(--space-4);
  font-size: var(--text-lg);
  color: var(--color-text-soft);
}

.hero__actions {
  margin-top: var(--space-6);
  display: flex;
  gap: var(--space-3);
  flex-wrap: wrap;
}

/* Sur le ciel du hero, le bouton fantôme (transparent par défaut) gagne un
   fond blanc semi-transparent pour mieux se détacher des nuages. */
.hero__actions .btn--ghost {
  background: rgb(255 255 255 / 50%);
}

@media (min-width: 640px) {
  .hero__title {
    font-size: var(--text-4xl);
  }
}

/* Contenu long : fiches, documentation, pages éditoriales. */
.prose {
  color: var(--color-text-soft);
  max-width: 68ch;
}

.prose > * + * {
  margin-top: var(--space-4);
}

.prose h2 {
  margin-top: var(--space-8);
  color: var(--color-text);
  font-size: var(--text-xl);
}

.prose h3 {
  margin-top: var(--space-6);
  color: var(--color-text);
}

.prose ul,
.prose ol {
  padding-left: 1.25rem;
}

.prose ul {
  list-style: disc;
}
.prose ol {
  list-style: decimal;
}

.prose li + li {
  margin-top: var(--space-2);
}

.prose hr {
  border: none;
  border-top: 1px solid var(--color-border);
  margin-block: var(--space-6);
}

.prose blockquote {
  padding: var(--space-3) var(--space-4);
  border-left: 3px solid var(--color-brand);
  background: var(--color-bg-muted);
  border-radius: var(--radius-sm);
  font-style: italic;
  color: var(--color-text-soft);
}

.prose blockquote + blockquote {
  margin-top: var(--space-3);
}

.prose blockquote cite {
  display: block;
  margin-top: var(--space-2);
  font-style: normal;
  font-size: var(--text-sm);
  color: var(--color-text-faint);
}

.prose__note {
  padding: var(--space-3) var(--space-4);
  border-left: 3px solid var(--color-brand);
  background: var(--color-bg-muted);
  border-radius: var(--radius-sm);
  font-size: var(--text-sm);
}

.prose__note cite {
  display: block;
  margin-top: var(--space-2);
  font-style: normal;
  font-size: var(--text-xs);
  color: var(--color-text-faint);
}

.about-logo-row {
  display: flex;
  align-items: center;
  gap: var(--space-5);
}

.about-logo {
  flex: none;
  width: 120px;
  height: 120px;
}

@media (max-width: 560px) {
  .about-logo-row {
    flex-direction: column;
    text-align: center;
  }
}

/* Fiche extension */
.ext-detail__head {
  display: flex;
  gap: var(--space-4);
  align-items: flex-start;
  flex-wrap: wrap;
}

.ext-detail__icon {
  width: 72px;
  height: 72px;
  border-radius: var(--radius-md);
}

/* Listes de doc */
.doc-list {
  display: grid;
  gap: var(--space-2);
}

.doc-list a {
  display: inline-block;
  font-weight: 500;
}

/* Navigation de documentation */
.doc-nav {
  position: sticky;
  top: calc(var(--header-height) + var(--space-4));
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  padding: var(--space-4);
  background: var(--color-surface);
}

.doc-nav__heading {
  font-size: var(--text-xs);
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--color-text-faint);
  margin-bottom: var(--space-3);
}

.doc-nav__list {
  display: grid;
  gap: var(--space-1);
}

.doc-nav__link {
  display: block;
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-sm);
  font-size: var(--text-sm);
  color: var(--color-text-soft);
}

.doc-nav__link:hover {
  background: var(--color-bg-muted);
  color: var(--color-text);
}

.doc-nav__link.is-active {
  background: var(--color-brand-soft);
  color: var(--color-brand);
  font-weight: 600;
}

.doc-nav__foot {
  margin-top: var(--space-4);
  padding-top: var(--space-3);
  border-top: 1px solid var(--color-border);
  font-size: var(--text-sm);
}

.doc-article h2 {
  margin-top: 0;
}
