/* =============================================
   TOKENS
   ============================================= */
:root {
  /* Palette — révisée en Phase 2 ter (2026-09-10) d'après un mockup
     d'inspiration fourni par Lionel : ambiance crème / vert sauge, avec des
     touches végétales décoratives et une pointe de bleu poudré en rôle
     secondaire. Remplace la direction bleu clair/blanc de la carte de visite
     (Phase 2 bis). Le vert sauge --c-accent est la couleur principale
     (liens, focus, titres d'accent, bouton primaire plein + texte crème) ;
     le tan --c-gold ne sert qu'aux petits détails (filet du portrait,
     puce-feuille, cœur du slogan). Aucune valeur hex hors de ce bloc. Valeurs
     indicatives du mockup ajustées pour un contraste AA sur tous les couples
     texte/fond réellement utilisés.
     Phase 2 quater : --c-surface-alt et --c-blue-soft ne sont plus référencés
     (fonds de section opaques et blob bleu de la zone contact retirés au
     profit de l'image de fond) — conservés dans la palette pour un usage
     futur éventuel. */
  --c-bg:            #FAF5EA;  /* crème / beige chaud — fond général. Phase 2 quater : échantillonné (moyenne 800x500) au centre de l'image source des 4 coins décoratifs (assets/images/fond-vegetal-*.*) pour un raccord invisible entre l'image de fond fixe et le repli */
  --c-surface:       #FFFDF9;  /* blanc chaud — cartes, formulaire */
  --c-surface-alt:   #EAF0E4;  /* vert sauge très clair — non référencé depuis Phase 2 quater (voir note ci-dessus) */
  --c-ink:           #2B332C;  /* vert-charbon très sombre — texte principal */
  --c-muted:         #4E5B4B;  /* vert-gris — texte secondaire. Phase 2 quater : légèrement assombri (était #556353) en ceinture-bretelles du voile --c-veil pour le texte secondaire qui défile au-dessus de l'image de fond ; le voile reste la protection principale du contraste */
  --c-border:        #D9E0D2;  /* bordures douces — sauge clair : cartes, séparateurs, cadres de photos (décoratifs, pas de seuil de contraste requis) */
  --c-border-ui:     #758A79;  /* bordure des CONTRÔLES de formulaire (champs, champ fichier, case d'autorisation, cadre du widget anti-robot) — Phase 6, porte QA F4. WCAG 1.4.11 exige 3:1 pour repérer un composant d'interface ; --c-border ne fait que 1,33:1 sur --c-surface. Ratios calculés : 3,65:1 sur --c-surface (#FFFDF9, fond réel des champs), 3,71:1 sur blanc, 3,41:1 sur --c-bg (le fond de page le plus clair/chaud). Ne PAS l'utiliser pour de la décoration, ni changer --c-border */

  --c-accent:        #3F6B4E;  /* vert sauge profond — liens, focus, titres d'accent, fond du bouton primaire */
  --c-accent-h:      #345A41;  /* vert sauge plus foncé — hover, et texte/symbole sur fond --c-accent-soft */
  --c-accent-soft:   #D7E5D2;  /* vert sauge clair — badges, halos décoratifs, fonds ponctuels */
  --c-accent-soft-h: #C4D8BD;  /* hover du sauge clair */

  --c-blue-soft:     #D6E4EA;  /* bleu poudré doux — non référencé depuis Phase 2 quater (voir note ci-dessus) */

  --c-gold:          #C9A876;  /* beige doré / tan — petits motifs décoratifs (feuillages, empreintes, cœurs, filets) */
  --c-gold-soft:     #F0E4CE;  /* tan très éclairci — badges secondaires, fonds ponctuels */
  --c-gold-ink:      #6E5326;  /* brun lisible sur fond --c-gold-soft (contraste AA) */

  --c-success:       #1A7A42;
  --c-error:         #C22F2F;

  --c-bg-translucent:     rgba(250, 245, 234, 0.94); /* --c-bg avec alpha — header en overlay */
  --c-accent-focus-ring:  rgba(63, 107, 78, 0.22);   /* --c-accent avec alpha — halo de focus */
  --c-error-focus-ring:   rgba(194, 47, 47, 0.22);   /* --c-error avec alpha — halo de focus d'un champ en erreur (reste distinct du halo vert normal) */

  /* Voiles translucides — Phase 2 quater. L'image de fond végétale fixe
     (body::before) porte toute la décoration ; ces voiles laissent
     transparaître le décor tout en garantissant le contraste AA du texte qui
     défile, au fil du scroll, au-dessus des feuillages les plus denses des
     coins de l'image — à toutes les largeurs (360 → 1920). Translucides,
     jamais opaques ; opacité calée sur le pire cas mesuré : texte secondaire
     pleine largeur par-dessus le pixel le plus sombre du WebP réellement servi
     (~[65,68,53]), sous le lavis --deco-veil.
     Correctif porte QA 2 quater : --c-veil relevé de 0.62 à 0.82 — 0.62 (et le
     "transparent" des sections de contenu) ne tenait pas le 4.5:1 sur les
     coins décorés. */
  --c-veil:     rgba(255, 253, 249, 0.82); /* --c-surface + alpha — voile sous TOUT le contenu (.section) + séparateurs en vague */
  --c-veil-alt: rgba(247, 242, 231, 0.85); /* --c-bg + alpha, teinte crème et un cran plus dense — .section--alt, conserve le rythme une-section-sur-deux */
  --deco-veil:  rgba(250, 245, 234, 0.26); /* --c-bg avec alpha — léger lavis crème posé SUR l'image de fond pour adoucir les motifs */

  /* Motifs décoratifs — masques SVG inline monochromes (la couleur vient d'un
     token --c-* via `background`, le SVG ne sert que d'alpha). Phase 2 quater :
     les grands motifs (rameau --deco-sprig, empreintes --deco-paw) sont retirés,
     l'image de fond végétale les porte. Ne restent que deux détails
     fonctionnels discrets : la puce-feuille des listes et des titres de section
     (--deco-leaf) et le petit cœur devant le slogan (--deco-heart). */
  --deco-leaf:  url("data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2020%2020'%3E%3Cpath%20fill='black'%20d='M10,19%20C3,15%201,8%204,2%20C11,3%2018,7%2018,13%20C18,16%2014,18%2010,19%20Z'/%3E%3C/svg%3E");
  --deco-heart: url("data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2032%2032'%3E%3Cpath%20fill='black'%20d='M16,27%20C6,20%202,14%202,9%20C2,5%205,2%209,2%20C12,2%2015,4%2016,7%20C17,4%2020,2%2023,2%20C27,2%2030,5%2030,9%20C30,14%2026,20%2016,27%20Z'/%3E%3C/svg%3E");

  /* Coche de la case d'autorisation habillée (Phase 6, porte QA F6c) — même
     principe que les motifs ci-dessus : masque monochrome, couleur par token. */
  --deco-check: url("data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2024%2024'%3E%3Cpath%20fill='none'%20stroke='black'%20stroke-width='3.4'%20stroke-linecap='round'%20stroke-linejoin='round'%20d='M5,12.5%20L10,17.5%20L19,7'/%3E%3C/svg%3E");

  /* Typographie — Montserrat uniquement (Phase 2 bis : la police décorative
     "Saestwo" utilisée un temps pour le slogan a été retirée). */
  --f-display: 'Montserrat', system-ui, sans-serif;
  --f-body:    'Montserrat', system-ui, sans-serif;

  /* Échelle */
  --t-xs:   0.75rem;
  --t-sm:   0.875rem;
  --t-base: 1rem;
  --t-lg:   1.125rem;
  --t-xl:   1.375rem;
  --t-2xl:  1.75rem;
  --t-3xl:  2.5rem;
  --t-4xl:  3.5rem;

  /* Espacement */
  --s-1: 0.25rem;
  --s-2: 0.5rem;
  --s-3: 0.75rem;
  --s-4: 1rem;
  --s-6: 1.5rem;
  --s-8: 2rem;
  --s-12: 3rem;
  --s-16: 4rem;
  --s-24: 6rem;

  /* Layout */
  --max-w: 1100px;
  --radius: 10px;
  --radius-lg: 22px;

  /* Ombres — toujours dérivées de --c-ink pour rester cohérentes avec la palette */
  --shadow-sm: 0 2px 10px rgba(43, 51, 44, 0.06);
  --shadow-md: 0 10px 32px rgba(43, 51, 44, 0.10);
  --shadow-lg: 0 18px 48px rgba(43, 51, 44, 0.14);

  /* Opacité d'un contrôle désactivé (bouton d'envoi pendant la requête) */
  --o-disabled: 0.6;

  /* Transitions */
  --ease: 0.18s ease;
  --ease-slow: 0.32s ease;
}

/* =============================================
   POLICES LOCALES — Montserrat uniquement (Phase 2 bis)
   Fichiers copiés depuis Ressources/noema_rendu/polices/, pas de Google Fonts.
   ============================================= */
@font-face {
  font-family: 'Montserrat';
  src: url('../assets/fonts/Montserrat-Regular.woff2') format('woff2'),
       url('../assets/fonts/Montserrat-Regular.woff') format('woff');
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'Montserrat';
  src: url('../assets/fonts/Montserrat-Medium.woff2') format('woff2'),
       url('../assets/fonts/Montserrat-Medium.woff') format('woff');
  font-weight: 500;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'Montserrat';
  src: url('../assets/fonts/Montserrat-SemiBold.woff2') format('woff2'),
       url('../assets/fonts/Montserrat-SemiBold.woff') format('woff');
  font-weight: 600;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'Montserrat';
  src: url('../assets/fonts/Montserrat-Bold.woff2') format('woff2'),
       url('../assets/fonts/Montserrat-Bold.woff') format('woff');
  font-weight: 700;
  font-style: normal;
  font-display: swap;
}
@font-face {
  /* Utilisé volontairement en Phase 2 : H1 de chaque page (hero__title) et
     guillemet décoratif des cartes témoignages (.testimonial::before) — sert
     à marquer la hiérarchie typographique entre le titre principal et le
     reste des titres (SemiBold/Bold). */
  font-family: 'Montserrat';
  src: url('../assets/fonts/Montserrat-ExtraBold.woff2') format('woff2'),
       url('../assets/fonts/Montserrat-ExtraBold.woff') format('woff');
  font-weight: 800;
  font-style: normal;
  font-display: swap;
}
/* =============================================
   RESET & BASE
   ============================================= */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }

html { scroll-behavior: smooth; }

body {
  position: relative;
  background: var(--c-bg);
  color: var(--c-ink);
  font-family: var(--f-body);
  font-size: var(--t-base);
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
}

/* =============================================
   COUCHE DÉCORATIVE DE FOND — Phase 2 quater, revue Phase 2 quinquies
   4 coins aquarelle (feuillages sauge, empreintes dorées, cœurs) découpés
   dans la même image que la Phase 2 quater, ancrés CHACUN dans son coin de
   viewport plutôt qu'une image unique en `cover`.
   - Pourquoi ce changement : une seule image paysage (1672×941) en `cover`
     sur un viewport étroit et haut (mobile, ou fenêtre desktop très verticale)
     doit "zoomer" pour couvrir toute la hauteur, ce qui pousse les coins
     décorés hors-champ — sur mobile en particulier, le fond redevenait quasi
     uni. 4 images ancrées à `top left/top right/bottom left/bottom right` en
     `no-repeat` restent visibles quel que soit le format d'écran.
   - position: fixed sur le pseudo-élément — PAS background-attachment: fixed
     (capricieux/ignoré sur iOS Safari). La couche reste calée sur le viewport,
     le contenu défile par-dessus le centre crème.
   - z-index: -1 → derrière tout le contenu, au-dessus du fond crème du body.
   - pointer-events: none + pseudo-élément → jamais cliquable, jamais lue par un
     lecteur d'écran.
   - Taille de chaque coin : min(420px, 40vw), largeur réelle de l'image
     source 620px (donc jamais agrandie, seulement réduite) — plafonnée pour
     ne pas envahir le centre sur très grand écran, réduite proportionnellement
     sur mobile plutôt que recadrée hors-champ.
   - WebP (~6 Ko/coin, ~24 Ko au total) servi en priorité via image-set(),
     repli PNG (~60 Ko/coin) ; repli ultime = --c-bg si aucune image ne charge
     (raccord invisible, même crème échantillonné).
   - Le lavis --deco-veil est conservé tel quel par-dessus les 4 images : les
     coins couvrant désormais moins de surface qu'avant (Phase 2 quater), le
     contraste du texte qui défile par-dessus ne peut que s'améliorer par
     rapport au pire cas déjà validé en QA (5.76:1).
   ============================================= */
body::before {
  content: "";
  position: fixed;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  background-color: var(--c-bg);
  background-image:
    linear-gradient(var(--deco-veil), var(--deco-veil)),
    url("../assets/images/fond-vegetal-tl.png"),
    url("../assets/images/fond-vegetal-tr.png"),
    url("../assets/images/fond-vegetal-bl.png"),
    url("../assets/images/fond-vegetal-br.png");
  background-image:
    linear-gradient(var(--deco-veil), var(--deco-veil)),
    -webkit-image-set(url("../assets/images/fond-vegetal-tl.webp") type("image/webp"), url("../assets/images/fond-vegetal-tl.png") type("image/png")),
    -webkit-image-set(url("../assets/images/fond-vegetal-tr.webp") type("image/webp"), url("../assets/images/fond-vegetal-tr.png") type("image/png")),
    -webkit-image-set(url("../assets/images/fond-vegetal-bl.webp") type("image/webp"), url("../assets/images/fond-vegetal-bl.png") type("image/png")),
    -webkit-image-set(url("../assets/images/fond-vegetal-br.webp") type("image/webp"), url("../assets/images/fond-vegetal-br.png") type("image/png"));
  background-image:
    linear-gradient(var(--deco-veil), var(--deco-veil)),
    image-set(url("../assets/images/fond-vegetal-tl.webp") type("image/webp"), url("../assets/images/fond-vegetal-tl.png") type("image/png")),
    image-set(url("../assets/images/fond-vegetal-tr.webp") type("image/webp"), url("../assets/images/fond-vegetal-tr.png") type("image/png")),
    image-set(url("../assets/images/fond-vegetal-bl.webp") type("image/webp"), url("../assets/images/fond-vegetal-bl.png") type("image/png")),
    image-set(url("../assets/images/fond-vegetal-br.webp") type("image/webp"), url("../assets/images/fond-vegetal-br.png") type("image/png"));
  background-position: center, top left, top right, bottom left, bottom right;
  background-size: cover, min(420px, 40vw) auto, min(420px, 40vw) auto, min(420px, 40vw) auto, min(420px, 40vw) auto;
  background-repeat: no-repeat;
}

img, svg { display: block; max-width: 100%; }
a { color: inherit; text-decoration: none; }
ul { list-style: none; }
button { cursor: pointer; font: inherit; border: none; background: none; }
input, textarea { font: inherit; }

:focus-visible {
  outline: 3px solid var(--c-accent);
  outline-offset: 3px;
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: 0.01ms !important; transition-duration: 0.01ms !important; }
  /* Porte QA F6a : un défilement animé (ancres #contact…) est aussi un mouvement,
     et une animation de 0,01 ms en boucle infinie (spinner du widget) scintille
     au lieu de s'arrêter — on la supprime vraiment (voir bloc ALTCHA plus bas). */
  html { scroll-behavior: auto; }
  altcha-widget .altcha-spinner { animation: none; }
}

/* =============================================
   UTILITAIRES
   ============================================= */
.container {
  width: min(var(--max-w), 100% - var(--s-8));
  margin-inline: auto;
  min-width: 0;
}

.section {
  position: relative;
  padding-block: var(--s-24);
  /* Phase 2 quater (correctif porte QA) : voile translucide sous TOUT le
     contenu qui défile au-dessus de l'image de fond fixe. Garantit le
     contraste AA (≥ 4.5:1) même quand un bloc de texte balaie, au fil du
     scroll, les feuillages les plus denses des coins de l'image — à toutes
     les largeurs testées (360 → 1920). L'image transparaît encore (~18 %). */
  background: var(--c-veil);
}

/* Phase 2 quater : toutes les sections de contenu portent le voile --c-veil
   (défini sur .section ci-dessus). --alt reçoit une variante un cran plus
   dense et teintée crème pour garder le rythme une-section-sur-deux au-dessus
   de l'image. --surface = voile par défaut de .section (plus de règle dédiée :
   le "transparent" de la première passe de la Phase 2 quater ne tenait pas le
   contraste sur les coins décorés). */
.section--alt {
  background: var(--c-veil-alt);
}

.section--centered {
  text-align: center;
}

.section--tight {
  padding-block: var(--s-8) var(--s-12);
}

.section--centered .section__intro {
  margin-inline: auto;
}

.visually-hidden {
  position: absolute;
  width: 1px; height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}

/* =============================================
   TYPOGRAPHIE
   ============================================= */
h1, h2, h3 {
  font-family: var(--f-display);
  font-weight: 700;
  line-height: 1.2;
  color: var(--c-ink);
  overflow-wrap: break-word;
}

h3 { font-weight: 600; }

.eyebrow {
  display: inline-flex;
  align-items: center;
  font-size: var(--t-sm);
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--c-accent);
  margin-bottom: var(--s-4);
  /* Phase 2 quinquies : petit fond voilé derrière le texte, comme .section
     (--c-veil, déjà validé au pire cas mesuré sur le fond décoratif). Sans ça,
     ce texte non voilé peut retomber sous le seuil AA quand un coin décoré
     dense passe juste derrière lui (mesuré : 2.96:1 à 768-834px sur le hero
     de index.html, correctif appliqué ici aussi par cohérence de style). */
  padding: var(--s-1) var(--s-3);
  border-radius: 999px;
  background: var(--c-veil);
}

/* Eyebrow placé SOUS le titre (page Communication animale, Phase 2 ter) —
   accroche basse plutôt que sur-titre. */
.eyebrow--below {
  margin-top: var(--s-4);
  margin-bottom: 0;
}

.section__title {
  font-size: var(--t-3xl);
  margin-bottom: var(--s-8);
}

/* Petite feuille décorative devant chaque titre de section — motif masqué,
   couleur pilotée par --c-accent (jamais de couleur en dur). En inline-block
   pour suivre aussi bien un titre aligné à gauche qu'un titre centré. */
.section__title::before {
  content: '';
  display: inline-block;
  width: 24px;
  height: 24px;
  margin-right: var(--s-3);
  vertical-align: -0.18em;
  background: var(--c-accent);
  -webkit-mask: var(--deco-leaf) center / contain no-repeat;
          mask: var(--deco-leaf) center / contain no-repeat;
}

.section__intro {
  color: var(--c-muted);
  font-size: var(--t-lg);
  max-width: 700px;
  margin-bottom: var(--s-8);
  line-height: 1.7;
}

.prose p {
  color: var(--c-ink);
  margin-bottom: var(--s-4);
  max-width: 70ch;
}

.prose h2 {
  font-size: var(--t-2xl);
  margin-top: var(--s-12);
  margin-bottom: var(--s-4);
  color: var(--c-ink);
}

.prose h3 {
  font-size: var(--t-xl);
  margin-top: var(--s-12);
  margin-bottom: var(--s-4);
}

/* Liens dans le corps de texte — soulignés + couleur d'accent : distinguables
   autrement que par la seule couleur (accessibilité). */
.prose a {
  color: var(--c-accent-h);
  font-weight: 600;
  text-decoration: underline;
  text-underline-offset: 2px;
}
.prose a:hover { color: var(--c-accent); }

/* Listes du corps de texte — puce en forme de feuille (motif masqué,
   couleur pilotée par --c-accent). */
.prose ul {
  list-style: none;
  max-width: 70ch;
  margin: var(--s-4) 0 var(--s-6);
  padding: 0;
}

.prose ul li {
  position: relative;
  padding-left: var(--s-8);
  margin-bottom: var(--s-3);
  color: var(--c-ink);
}

.prose ul li::before {
  content: '';
  position: absolute;
  left: 0;
  top: 0.45em;
  width: 15px;
  height: 15px;
  background: var(--c-accent);
  -webkit-mask: var(--deco-leaf) center / contain no-repeat;
          mask: var(--deco-leaf) center / contain no-repeat;
}

.prose--spaced {
  margin-top: var(--s-12);
}

/* =============================================
   BOUTONS
   ============================================= */
.btn {
  display: inline-flex;
  align-items: center;
  gap: var(--s-2);
  padding: var(--s-3) var(--s-6);
  border-radius: var(--radius);
  font-size: var(--t-sm);
  font-weight: 600;
  transition: background var(--ease), color var(--ease), border-color var(--ease), transform var(--ease);
}

/* Bouton principal — Phase 2 ter : le mockup crème/vert sauge demande un
   bouton primaire PLEIN en vert sauge avec texte crème. Contraste texte
   crème (--c-bg) sur --c-accent vérifié AA. */
.btn--primary {
  background: var(--c-accent);
  color: var(--c-bg);
  border: 1.5px solid var(--c-accent);
}
.btn--primary:hover {
  background: var(--c-accent-h);
  border-color: var(--c-accent-h);
  transform: translateY(-1px);
}

/* Bouton secondaire — contour vert sauge (mockup). */
.btn--outline {
  background: transparent;
  color: var(--c-accent);
  border: 1.5px solid var(--c-accent);
}
.btn--outline:hover { background: var(--c-accent-soft); color: var(--c-accent-h); border-color: var(--c-accent-h); }

.btn--ghost {
  background: transparent;
  color: var(--c-accent);
  border: 1.5px solid var(--c-accent);
}
.btn--ghost:hover { background: var(--c-accent-soft); color: var(--c-accent-h); border-color: var(--c-accent-h); }

/* =============================================
   HEADER / NAV
   ============================================= */
.site-header {
  position: sticky;
  top: 0;
  z-index: 100;
  background: var(--c-bg-translucent);
  backdrop-filter: blur(10px);
  border-bottom: 1px solid var(--c-border);
}

.nav {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding-block: var(--s-4);
  gap: var(--s-6);
}

.nav__logo {
  display: flex;
  align-items: center;
  gap: var(--s-2);
}

.nav__logo img {
  height: 64px;
  width: auto;
}

.nav__links {
  display: flex;
  align-items: center;
  gap: var(--s-8);
}

.nav__links a {
  font-size: var(--t-sm);
  font-weight: 500;
  color: var(--c-muted);
  transition: color var(--ease);
  padding-block: var(--s-1);
  border-bottom: 2px solid transparent;
}
.nav__links a:hover { color: var(--c-ink); }

.nav__links a[aria-current="page"] {
  color: var(--c-accent);
  font-weight: 600;
  border-bottom-color: var(--c-accent);
}

.nav__burger { display: none; flex-direction: column; gap: 5px; padding: var(--s-2); }
.nav__burger span { display: block; width: 22px; height: 2px; background: var(--c-ink); border-radius: 2px; transition: transform var(--ease), opacity var(--ease); }

/* Mobile nav */
@media (max-width: 700px) {
  .nav__burger { display: flex; }

  .nav__links {
    display: none;
    position: absolute;
    top: 100%;
    inset-inline: 0;
    background: var(--c-bg);
    border-bottom: 1px solid var(--c-border);
    flex-direction: column;
    align-items: flex-start;
    padding: var(--s-6) var(--s-4);
    gap: var(--s-6);
  }
  .nav__links.is-open { display: flex; }

  .nav__burger[aria-expanded="true"] span:nth-child(1) { transform: translateY(7px) rotate(45deg); }
  .nav__burger[aria-expanded="true"] span:nth-child(2) { opacity: 0; }
  .nav__burger[aria-expanded="true"] span:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }
}

/* =============================================
   HERO
   ============================================= */
.hero {
  position: relative;
  padding-block: var(--s-24) var(--s-16);
  border-bottom: 1px solid var(--c-border);
}

/* Phase 2 quater : les blobs organiques et le rameau SVG du hero sont retirés
   — l'image de fond végétale fixe porte cette décoration. */

.hero__inner {
  position: relative;
  z-index: 1;
  max-width: 760px;
}

.hero__title {
  font-size: clamp(var(--t-2xl), 7vw, var(--t-4xl));
  font-weight: 800; /* Montserrat ExtraBold */
  letter-spacing: -0.01em;
  color: var(--c-ink);
  margin-bottom: var(--s-6);
}

.hero__slogan {
  display: inline-flex;
  align-items: center;
  font-family: var(--f-display);
  font-weight: 600;
  letter-spacing: 0.01em;
  font-size: var(--t-xl);
  color: var(--c-accent);
  margin-bottom: var(--s-4);
  /* Phase 2 quinquies : même correctif de contraste que .eyebrow (voir sa
     note) — mesuré à 2.96-3.22:1 (< seuil AA 4.5:1) entre 768 et 834px de
     largeur, là où un coin décoré dense passe juste derrière ce texte non
     voilé du hero. */
  padding: var(--s-1) var(--s-3);
  border-radius: 999px;
  background: var(--c-veil);
}

/* Petit cœur décoratif devant le slogan (motif masqué, couleur = token tan) —
   toujours dans le flux, jamais clippé. */
.hero__slogan::before {
  content: '';
  display: inline-block;
  flex-shrink: 0;
  width: 15px;
  height: 15px;
  margin-right: var(--s-2);
  background: var(--c-gold);
  -webkit-mask: var(--deco-heart) center / contain no-repeat;
          mask: var(--deco-heart) center / contain no-repeat;
}

.hero__sub {
  font-size: var(--t-lg);
  color: var(--c-muted);
  max-width: 620px;
  margin-bottom: var(--s-8);
  line-height: 1.7;
}

/* Sous-titre hero mis en évidence (page Présentation, Phase 2 bis) — plus
   grand, plus gras, dans le bleu d'accent, pour se démarquer du reste du
   texte de présentation qui suit juste en dessous. */
.hero__sub--lead {
  font-size: var(--t-xl);
  font-weight: 600;
  color: var(--c-accent);
}

.hero__cta {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-4);
}

/* =============================================
   SÉPARATEUR DE SECTION — courbe douce
   SVG inline dans le HTML (fill="currentColor"), la couleur vient d'ici via
   `color`, jamais en dur dans le SVG — reste piloté par les tokens.
   ============================================= */
.section-divider {
  display: block;
  position: absolute;
  left: 0;
  bottom: -1px; /* évite un filet de fond entre la section et la courbe */
  width: 100%;
  height: 48px;
  pointer-events: none;
}

/* Phase 2 quater : les sections de contenu étant devenues transparentes/
   voilées, les trois variantes peignent la même vague en voile translucide —
   transition douce au-dessus de l'image de fond, plus aucune couleur de
   section pleine à raccorder. */
.section-divider--alt,
.section-divider--surface,
.section-divider--bg {
  color: var(--c-veil);
}

/* =============================================
   PRÉSENTATION (index)
   ============================================= */
.presentation {
  /* Phase 2 quater : porte le voile --c-veil de .section (correctif porte QA —
     le texte de présentation, colonne large, balayait les feuillages des coins
     de l'image et tombait sous 4.5:1 sans voile). */
  background: var(--c-veil);
}

.presentation__grid {
  display: grid;
  grid-template-columns: 1fr 1.3fr;
  gap: var(--s-16);
  align-items: start;
}

.presentation__portrait {
  position: sticky;
  top: calc(var(--s-24));
  padding: var(--s-4) var(--s-4) 0 0;
}

.presentation__portrait-frame {
  position: relative;
}

/* Arc doux derrière le portrait, écho du cercle du logo Noëmà — purement
   décoratif (pseudo-élément, jamais lu par un lecteur d'écran). Limité au
   wrapper de l'image uniquement (jamais à .presentation__portrait dans son
   ensemble, qui contient aussi la ligne de badges en dessous). Déborde
   uniquement en haut et à droite, dans l'espace réservé par le padding
   (--s-4) de .presentation__portrait : jamais vers le bas/la gauche, donc
   jamais en direction de .badge-row qui suit en flux normal. */
.presentation__portrait-frame::before {
  content: '';
  position: absolute;
  inset: calc(-1 * var(--s-4)) calc(-1 * var(--s-4)) var(--s-4) var(--s-4);
  border: 2px solid var(--c-gold);
  border-radius: var(--radius-lg);
  z-index: 0;
}

/* Phase 2 quater : les rameaux SVG au coin des cadres photo sont retirés —
   l'image de fond végétale porte cette décoration. Le filet doré discret
   (.presentation__portrait-frame::before) est conservé comme simple
   traitement photo, pas comme décor de page. */

.presentation__portrait img {
  position: relative;
  z-index: 1;
  width: 100%;
  border-radius: var(--radius-lg);
  border: 1px solid var(--c-border);
  box-shadow: var(--shadow-md);
}

@media (max-width: 800px) {
  .presentation__grid { grid-template-columns: 1fr; }
  .presentation__portrait { position: static; max-width: 340px; margin-inline: auto; }
}

.badge-row {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-3);
  margin-top: var(--s-6);
}

.badge {
  /* Agrandi en Phase 2 bis (retour de Lionel) — était var(--t-xs)/s-2 s-4. */
  display: inline-flex;
  align-items: center;
  padding: var(--s-3) var(--s-6);
  border-radius: 999px;
  font-size: var(--t-sm);
  font-weight: 600;
  background: var(--c-accent-soft);
  color: var(--c-accent-h);
}

.badge--gold {
  background: var(--c-gold-soft);
  color: var(--c-gold-ink);
}

/* =============================================
   MEDIA-GRID — photo + texte, réutilisé sur les pages
   Communication animale et Témoignages (Phase 2 : repositionnement des
   2 photos non retenues comme portrait principal). Aucun object-fit/crop
   forcé : chaque photo garde son cadrage d'origine, seule la largeur de
   colonne varie — c'est ce qui évite de couper un visage n'importe où.
   ============================================= */
.media-grid {
  display: grid;
  grid-template-columns: 1fr 1.2fr;
  gap: var(--s-12);
  align-items: center;
}

.media-grid--reverse {
  grid-template-columns: 1.2fr 1fr;
}

.media-grid__photo {
  position: relative;
}

.media-grid--reverse .media-grid__photo {
  order: 2;
}

.media-grid__photo img {
  display: block;
  width: 100%;
  /* La photo source est un portrait 9:16 très haut : sans contrainte, elle
     forme un monolithe vertical à côté d'un bloc de texte bien plus court.
     On la recadre discrètement en portrait doux (visage de Marielle, en
     haut-centre, gardé dans le cadre via object-position). */
  aspect-ratio: 4 / 5;
  object-fit: cover;
  object-position: center 20%;
  border-radius: var(--radius-lg);
  border: 1px solid var(--c-border);
  box-shadow: var(--shadow-md);
}

@media (max-width: 800px) {
  .media-grid,
  .media-grid--reverse {
    grid-template-columns: 1fr;
  }
  .media-grid--reverse .media-grid__photo { order: 0; }
  /* On contraint le conteneur (pas seulement l'image) pour que la photo reste
     centrée et de largeur raisonnable en mobile. */
  .media-grid__photo { max-width: 360px; margin-inline: auto; }
}

/* Photo isolée, encadrée, utilisée comme respiration visuelle entre deux
   sections (ex. page Témoignages). Pas d'aspect-ratio forcé : le cadrage
   d'origine de la photo est conservé intégralement. */
.feature-photo {
  position: relative;
  max-width: 420px;
  margin-inline: auto;
}

.feature-photo img {
  width: 100%;
  border-radius: var(--radius-lg);
  border: 1px solid var(--c-border);
  box-shadow: var(--shadow-md);
}

/* =============================================
   TÉMOIGNAGES
   ============================================= */
.testimonials {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: var(--s-8);
}

.testimonial {
  position: relative;
  background: var(--c-surface);
  border: 1px solid var(--c-border);
  border-top: 4px solid var(--c-gold);
  border-radius: var(--radius-lg);
  padding: var(--s-8);
  padding-top: var(--s-12);
  display: flex;
  flex-direction: column;
  gap: var(--s-4);
  box-shadow: var(--shadow-sm);
  transition: box-shadow var(--ease-slow), transform var(--ease-slow);
}

.testimonial:hover {
  box-shadow: var(--shadow-lg);
  transform: translateY(-4px);
}

/* Photo optionnelle de témoignage (Phase 2 bis, `docs/PRD.md` § 5) — capacité
   d'affichage du gabarit, contenu ajouté à la main dans le HTML. Un
   témoignage sans photo n'a simplement pas cet élément : pas de cadre vide,
   la carte garde son padding-top habituel réservé au guillemet décoratif.
   z-index: 1 pour que la photo (contenu normal du flux) passe bien au-dessus
   du grand guillemet décoratif (::before, positionné, z-index: 0). */
.testimonial__photo {
  position: relative;
  z-index: 1;
  border-radius: var(--radius);
  overflow: hidden;
  border: 1px solid var(--c-border);
}

.testimonial__photo img {
  display: block;
  width: 100%;
  aspect-ratio: 4 / 3;
  object-fit: cover;
}

/* Légende visible sous la photo — distincte de l'`alt` (lu uniquement par les
   technologies d'assistance) : garantit qu'un·e visiteur·se voyant ne peut pas
   confondre une photo de démonstration avec une vraie photo liée au
   témoignage, sans avoir à lire l'`alt`. Même famille visuelle que
   `.example-note` (fond/texte or = "attention, ceci n'est pas réel") mais
   rattachée physiquement à la photo, dans le même cadre bordé/arrondi
   qu'`.testimonial__photo` (overflow: hidden sur le parent découpe les coins
   du bas proprement). N'apparaît que si une légende est explicitement ajoutée
   dans le HTML : une photo de témoignage réelle n'a pas cet élément. */
.testimonial__photo-caption {
  position: relative;
  z-index: 1;
  margin: 0;
  padding: var(--s-2) var(--s-3);
  font-size: var(--t-xs);
  font-weight: 600;
  text-align: center;
  color: var(--c-gold-ink);
  background: var(--c-gold-soft);
  border-top: 1px solid var(--c-border);
}

/* Grand guillemet décoratif en fond de carte */
.testimonial::before {
  content: '\201C';
  position: absolute;
  top: var(--s-2);
  left: var(--s-6);
  font-family: var(--f-display);
  font-size: 4.5rem;
  font-weight: 800;
  line-height: 1;
  color: var(--c-accent-soft);
  z-index: 0;
  pointer-events: none;
}

.testimonial__quote {
  position: relative;
  z-index: 1;
  color: var(--c-ink);
  font-size: var(--t-base);
  line-height: 1.7;
}

.testimonial__author {
  position: relative;
  z-index: 1;
  display: flex;
  align-items: center;
  gap: var(--s-3);
  font-size: var(--t-sm);
  font-weight: 600;
  color: var(--c-muted);
}

.testimonial__author::before {
  content: '';
  flex-shrink: 0;
  width: 34px;
  height: 34px;
  border-radius: 50%;
  background: linear-gradient(135deg, var(--c-accent-soft), var(--c-gold-soft));
  border: 1px solid var(--c-border);
}

.example-note {
  position: relative;
  z-index: 1;
  display: inline-block;
  margin-top: var(--s-2);
  font-size: var(--t-xs);
  font-weight: 600;
  color: var(--c-gold-ink);
  background: var(--c-gold-soft);
  padding: var(--s-1) var(--s-3);
  border-radius: 999px;
  align-self: flex-start;
}

/* =============================================
   CARTES GÉNÉRIQUES (ex. sous-sections communication animale)
   ============================================= */
.card-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: var(--s-6);
  margin-top: var(--s-8);
}

.card {
  background: var(--c-surface);
  border: 1px solid var(--c-border);
  border-radius: var(--radius);
  padding: var(--s-8);
  transition: box-shadow var(--ease), transform var(--ease);
}
.card:hover {
  box-shadow: var(--shadow-md);
  transform: translateY(-2px);
}

.card__title {
  font-size: var(--t-xl);
  margin-bottom: var(--s-3);
}

.card__body {
  color: var(--c-muted);
  font-size: var(--t-sm);
  line-height: 1.7;
}

/* =============================================
   CONTACT
   ============================================= */
/* Phase 2 quater : plus de fond sauge opaque ni de blob bleu (l'image de fond
   les porte). La section porte le voile --c-veil de .section (correctif porte
   QA : .contact__sub, paragraphe pleine largeur, balayait les coins décorés de
   l'image). Le formulaire et les cartes de coordonnées gardent leur surface
   opaque pour rester détachés du fond. */
.contact {
  position: relative;
  background: var(--c-veil);
  border-block: 1px solid var(--c-border);
}

.contact__grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--s-16);
  align-items: start;
}

/* Les deux colonnes doivent pouvoir se réduire sous la largeur intrinsèque de
   leur contenu (l'e-mail contact@… très long) pour que word-break agisse.
   Sans min-width: 0, un item de grille garde min-width: auto et déborde en
   mobile étroit — débordement jusqu'ici masqué par un overflow: hidden sur
   .contact (retiré en Phase 2 quater avec le décor de la section). */
.contact__grid > * {
  min-width: 0;
}

@media (max-width: 800px) {
  .contact__grid { grid-template-columns: 1fr; }
}

.contact__sub {
  color: var(--c-muted);
  margin-bottom: var(--s-8);
}

.contact-info {
  display: flex;
  flex-direction: column;
  gap: var(--s-4);
}

.contact-info__item {
  display: flex;
  align-items: center;
  gap: var(--s-3);
  padding: var(--s-4);
  background: var(--c-surface);
  border: 1px solid var(--c-border);
  border-radius: var(--radius);
  box-shadow: var(--shadow-sm);
  min-width: 0;
  transition: box-shadow var(--ease-slow), transform var(--ease-slow), border-color var(--ease);
}

.contact-info__item:hover {
  box-shadow: var(--shadow-md);
  transform: translateY(-2px);
  border-color: var(--c-accent-soft-h);
}

.contact-info__item > div {
  min-width: 0;
}

.contact-info__icon {
  flex-shrink: 0;
  width: 40px;
  height: 40px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 999px;
  background: var(--c-accent-soft);
  color: var(--c-accent-h);
  font-weight: 700;
}

.contact-info__label {
  display: block;
  font-size: var(--t-xs);
  color: var(--c-muted);
  margin-bottom: 2px;
}

.contact-info__value {
  display: block;
  font-weight: 600;
  color: var(--c-ink);
  overflow-wrap: break-word;
  word-break: break-word;
}

.contact-info a.contact-info__value:hover {
  color: var(--c-accent);
}

/* Carte de formulaire — partagée par le formulaire de contact (index.html,
   .contact__form) et le formulaire de témoignage (temoignages.html,
   .form-card). Aucun cookie, aucun tiers : voir politique-de-confidentialite.html. */
.contact__form,
.form-card {
  position: relative;
  text-align: left;
  background: var(--c-surface);
  border: 1px solid var(--c-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-md);
  padding: var(--s-8);
}

/* Phase 6 : le formulaire de témoignage occupe une colonne de lecture
   confortable, alignée à gauche comme le reste du texte de la page. */
.form-card {
  max-width: 720px;
}

/* Mobile très étroit (320 px) : un peu moins de marge intérieure pour que le
   libellé de la case d'autorisation (adresse e-mail incluse) tienne sans être
   coupé en milieu de mot. */
@media (max-width: 400px) {
  .contact__form,
  .form-card {
    padding: var(--s-6) var(--s-4);
  }
}

.form__row {
  margin-bottom: var(--s-6);
  display: flex;
  flex-direction: column;
  gap: var(--s-2);
}

.form__row label {
  font-size: var(--t-sm);
  font-weight: 600;
  color: var(--c-ink);
}

.form__optional {
  font-weight: 400;
  color: var(--c-muted);
}

/* Sélecteurs enfants directs (>) : les champs du widget ALTCHA (case à
   cocher, champ caché) sont plus profonds dans le DOM et ne doivent PAS hériter
   de ces styles de champ de texte. */
.form__row > input,
.form__row > textarea {
  width: 100%;
  padding: var(--s-3) var(--s-4);
  border: 1.5px solid var(--c-border-ui); /* porte QA F4 : ≥ 3:1 (WCAG 1.4.11), voir le token */
  border-radius: var(--radius);
  background: var(--c-surface);
  color: var(--c-ink);
  transition: border-color var(--ease), box-shadow var(--ease);
  resize: vertical;
}

/* Porte QA F3 : sans règle, WebKit/Safari affiche son gris par défaut (#A9A9A9,
   2,31:1) et Firefox atténue le sien. --c-muted = 7,07:1 sur --c-surface. */
.form__row > input::placeholder,
.form__row > textarea::placeholder {
  color: var(--c-muted);
  opacity: 1;
}

/* Priorité des états (du plus faible au plus fort, à spécificité égale c'est
   l'ordre qui compte) : repos < focus (bordure + halo verts) < erreur (bordure
   rouge) < erreur + focus (bordure rouge + halo rouge). */
.form__row > input:focus,
.form__row > textarea:focus {
  outline: none;
  border-color: var(--c-accent);
  box-shadow: 0 0 0 3px var(--c-accent-focus-ring);
}

.form__row > input.error,
.form__row > textarea.error {
  border-color: var(--c-error);
}

.form__row > input.error:focus,
.form__row > textarea.error:focus {
  box-shadow: 0 0 0 3px var(--c-error-focus-ring);
}

/* Champ photo (facultatif) — bouton natif « Choisir un fichier » habillé aux
   couleurs du site ; l'indication de format/poids est dans .form__hint. */
.form__row > input[type="file"] {
  padding: var(--s-2);
  font-size: var(--t-sm);
  color: var(--c-muted);
  cursor: pointer;
}
.form__row > input[type="file"]::file-selector-button {
  margin-right: var(--s-3);
  padding: var(--s-2) var(--s-4);
  border: 1.5px solid var(--c-accent);
  border-radius: var(--radius);
  background: transparent;
  color: var(--c-accent);
  font: inherit;
  font-weight: 600;
  cursor: pointer;
  transition: background var(--ease), color var(--ease);
}
.form__row > input[type="file"]::file-selector-button:hover {
  background: var(--c-accent-soft);
  color: var(--c-accent-h);
}
.form__row > input[type="file"]:focus-visible {
  outline: 3px solid var(--c-accent);
  outline-offset: 3px;
}

.form__hint {
  font-size: var(--t-sm);
  color: var(--c-muted);
}

/* Case d'autorisation de publication — case à gauche, texte (long) à droite.
   La zone d'erreur éventuelle (.form__error) passe sur sa propre ligne. */
.form__row--check {
  flex-direction: row;
  flex-wrap: wrap;
  align-items: flex-start;
  gap: var(--s-3);
}
/* Case habillée (porte QA F6c) : l'apparence native de Safari/WebKit donne un
   bord à 1,59:1. On reprend le dessin de la case du widget ALTCHA : bordure
   --c-border-ui (≥ 3:1), fond plein --c-accent une fois cochée, coche dessinée
   par un masque data: (autorisé par la CSP, comme --deco-leaf). Taille
   (--s-6 = 24 px) et zone cliquable (case + libellé entier) inchangées ; reste
   un vrai <input type="checkbox"> : clavier, lecteur d'écran et validation
   intacts. */
.form__row--check > input[type="checkbox"] {
  -webkit-appearance: none;
          appearance: none;
  position: relative;
  flex-shrink: 0;
  width: var(--s-6);
  height: var(--s-6);
  margin: 0;
  padding: 0;
  border: 1.5px solid var(--c-border-ui);
  border-radius: var(--s-1);
  background: var(--c-surface);
  cursor: pointer;
  transition: background var(--ease), border-color var(--ease);
}
.form__row--check > input[type="checkbox"]:checked {
  background: var(--c-accent);
  border-color: var(--c-accent);
}
.form__row--check > input[type="checkbox"]::after {
  content: '';
  position: absolute;
  inset: 0;
  background: var(--c-surface);
  -webkit-mask: var(--deco-check) center / 72% no-repeat;
          mask: var(--deco-check) center / 72% no-repeat;
  opacity: 0;
}
.form__row--check > input[type="checkbox"]:checked::after {
  opacity: 1;
}
.form__row--check > input[type="checkbox"]:focus-visible {
  outline: 3px solid var(--c-accent);
  outline-offset: 3px;
  box-shadow: none;
}
.form__row--check > input[type="checkbox"].error {
  border-color: var(--c-error);
  outline: 2px solid var(--c-error);
  outline-offset: 2px;
}
.form__row--check > input[type="checkbox"].error:focus-visible {
  outline-width: 3px;
  outline-offset: 3px;
}
.form__row--check label {
  flex: 1 1 0;
  min-width: 0;
  font-weight: 400;
  line-height: 1.55;
  overflow-wrap: anywhere; /* l'adresse e-mail du texte légal ne doit jamais déborder (coupée aux <wbr> / tirets d'abord) */
  cursor: pointer;
}

/* Mode contraste élevé de Windows : les couleurs de fond sont remplacées par
   le système, la coche (un fond masqué) disparaîtrait — on la redessine avec
   les couleurs système. */
@media (forced-colors: active) {
  .form__row--check > input[type="checkbox"]:checked {
    forced-color-adjust: none;
    background: Highlight;
    border-color: Highlight;
  }
  .form__row--check > input[type="checkbox"]:checked::after {
    forced-color-adjust: none;
    background: HighlightText;
  }
}
.form__row--check .form__error {
  flex-basis: 100%;
}
.form__check-link {
  display: block;
  margin-top: var(--s-2);
}
.form__check-link a {
  color: var(--c-accent-h);
  font-weight: 600;
  text-decoration: underline;
  text-underline-offset: 2px;
}
.form__check-link a:hover { color: var(--c-accent); }

/* Message d'erreur rattaché à un champ (créé par js/main.js, textContent). */
.form__error {
  font-size: var(--t-sm);
  font-weight: 600;
  color: var(--c-error);
}

.form__feedback {
  margin-top: var(--s-4);
  font-size: var(--t-sm);
  color: var(--c-muted);
  min-height: 1.4em;
  white-space: pre-line; /* message de l'API + texte de repli sur deux lignes (porte QA F2) */
  overflow-wrap: break-word;
}
.form__feedback.success { color: var(--c-success); }
.form__feedback.error   { color: var(--c-error); }

.form__note {
  margin-top: var(--s-4);
  font-size: var(--t-sm);
  color: var(--c-muted);
}
.form__note a,
.form__noscript a {
  color: var(--c-accent-h);
  font-weight: 600;
  text-decoration: underline;
  text-underline-offset: 2px;
}
.form__note a:hover,
.form__noscript a:hover { color: var(--c-accent); }

/* Affiché seulement sans JavaScript (le widget anti-robot en a besoin). */
.form__noscript {
  margin-bottom: var(--s-6);
  font-size: var(--t-sm);
  color: var(--c-ink);
}

/* Piège anti-robot (champ « siteweb ») — masqué visuellement hors écran, jamais
   display:none (certains robots l'ignorent), et retiré du parcours clavier/
   lecteur d'écran pour un utilisateur réel (tabindex="-1" + aria-hidden sur
   le conteneur). */
.form__honeypot {
  position: absolute;
  left: -9999px;
  top: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

/* Bouton d'envoi pendant la requête (désactivé par js/main.js). */
.btn:disabled {
  opacity: var(--o-disabled);
  cursor: not-allowed;
  transform: none;
}

/* =============================================
   WIDGET ANTI-ROBOT ALTCHA — auto-hébergé (assets/js/altcha/)
   Feuille vendorisée altcha.css chargée AVANT ce fichier ; ici on ne fait que
   piloter ses variables --altcha-* avec les tokens du site (aucune couleur en
   dur). Défaut du widget : 320 px de large max, police héritée (Montserrat).
   Portée sur l'élément <altcha-widget> (plus spécifique que le :root du widget).
   ============================================= */
altcha-widget {
  display: block;
  max-width: 100%;

  --altcha-color-base:                var(--c-surface);
  --altcha-color-base-content:        var(--c-ink);
  --altcha-color-neutral:             var(--c-border);
  --altcha-color-neutral-content:     var(--c-muted);
  --altcha-color-primary:             var(--c-accent);
  --altcha-color-primary-content:     var(--c-bg);
  --altcha-color-success:             var(--c-success);
  --altcha-color-success-content:     var(--c-surface);
  --altcha-color-error:               var(--c-error);
  --altcha-color-error-content:       var(--c-surface);
  --altcha-border-color:              var(--c-border-ui); /* cadre du widget : même contraste ≥ 3:1 que les champs (porte QA F4) */
  --altcha-border-radius:             var(--radius);
  --altcha-checkbox-border-color:     var(--c-accent);   /* contour de case lisible (≥ 3:1) */
  --altcha-checkbox-border-radius:    var(--s-1);
  --altcha-checkbox-size:             var(--s-6);
  --altcha-checkbox-outline-color:    var(--c-accent);   /* anneau de focus clavier */
  --altcha-input-background-color:    var(--c-surface);
  --altcha-input-border-radius:       var(--radius);
  --altcha-spinner-color:             var(--c-accent);
  --altcha-padding:                   var(--s-4);
}
altcha-widget .altcha-main {
  font-size: var(--t-sm);
  font-weight: 500;
}
/* Anneau de focus de la case, en TOUT état (porte QA F6b). Pendant « Vérification
   en cours », le widget rend la case transparente (opacity: 0) et affiche un
   spinner à sa place : l'anneau posé sur l'<input> disparaissait avec elle, alors
   que main.js y place le focus après un échec. On le porte donc par le conteneur
   .altcha-checkbox (jamais transparent) dès que la case reçoit le focus ; :focus
   et non :focus-visible, car ce focus est donné par script (sans clavier, le
   navigateur ne le jugerait pas « visible »). Le contour propre de l'<input> est
   retiré pour éviter un double anneau. */
altcha-widget .altcha-checkbox {
  border-radius: var(--altcha-checkbox-border-radius);
}
altcha-widget .altcha-checkbox:focus-within {
  outline: 3px solid var(--c-accent);
  outline-offset: 3px;
}
altcha-widget .altcha-checkbox input:focus,
altcha-widget .altcha-checkbox input:focus-visible {
  outline: none;
}

/* =============================================
   FOOTER
   ============================================= */
.site-footer {
  border-top: 1px solid var(--c-border);
  padding-block: var(--s-8);
  background: var(--c-surface);
}

.footer__inner {
  display: flex;
  justify-content: space-between;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--s-4);
}

.footer__brand {
  display: flex;
  align-items: center;
  gap: var(--s-2);
  font-family: var(--f-display);
  font-weight: 700;
  font-size: var(--t-lg);
}

.footer__brand img { height: 40px; width: auto; }

.footer__links {
  display: flex;
  gap: var(--s-6);
  flex-wrap: wrap;
}

.footer__links a {
  font-size: var(--t-sm);
  color: var(--c-muted);
}
.footer__links a:hover { color: var(--c-accent); }

.footer__copy {
  font-size: var(--t-xs);
  color: var(--c-muted);
  width: 100%;
  text-align: center;
  margin-top: var(--s-4);
}
