/* ==========================================================================
   Portfolio — Andy Rakotondrabe
   Style : épuré & professionnel · fond neutre · accent bleu technologique
   ========================================================================== */

/* Police auto-hébergée : Inter (variable, sous-ensemble latin, 47 Ko).
   Servir la police depuis le site supprime une requête tierce bloquante sur le
   chemin critique (≈ 950 ms mesurés) et n'expose plus l'adresse IP des visiteurs
   à un fournisseur de polices. Licence : assets/fonts/LICENSE-Inter.txt */
@font-face {
  font-family: "Inter";
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url("../assets/fonts/inter-latin-var.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
    U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193,
    U+2212, U+2215, U+FEFF, U+FFFD;
}

:root {
  --bg: #ffffff;
  --bg-soft: #f6f8fb;
  --text: #0f172a;
  /* Gris secondaire : choisi pour rester au-dessus de 4,5:1 (AA) sur les deux
     fonds du site — #fff (5,19:1) et --bg-soft (4,87:1). L'ancien #64748b
     tombait à 4,47:1 sur les sections teintées. */
  --text-muted: #5f6e84;
  --border: #e2e8f0;
  --accent: #2563eb;
  --accent-hover: #1d4ed8;
  --accent-soft: #eff6ff;
  --radius: 12px;
  --shadow-sm: 0 1px 2px rgba(15, 23, 42, 0.06);
  --shadow-md: 0 8px 28px rgba(15, 23, 42, 0.08);
  /* Largeur de lecture commune aux blocs de texte (hero, À propos, etc.) */
  --measure: 640px;
  --header-h: 68px;
  --font: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
    "Helvetica Neue", Arial, sans-serif;
}

/* ---------- Reset & base ---------- */
*,
*::before,
*::after {
  box-sizing: border-box;
}

html {
  scroll-behavior: smooth;
  scroll-padding-top: calc(var(--header-h) + 16px);
  /* Permet l'animation des hauteurs « auto » (accordéon FAQ) */
  interpolate-size: allow-keywords;
}

body {
  margin: 0;
  font-family: var(--font);
  font-size: 1.0625rem;
  line-height: 1.65;
  color: var(--text);
  background: var(--bg);
  -webkit-font-smoothing: antialiased;
}

img,
svg {
  display: block;
  max-width: 100%;
}

h1,
h2,
h3,
p {
  margin: 0;
}

a {
  color: var(--accent);
  text-decoration: none;
}

a:hover {
  text-decoration: underline;
}

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

.container {
  width: 100%;
  max-width: 1100px;
  margin: 0 auto;
  padding: 0 24px;
}

.skip-link {
  position: absolute;
  left: -999px;
  top: 0;
  z-index: 100;
  padding: 12px 18px;
  background: var(--accent);
  color: #fff;
  border-radius: 0 0 8px 0;
  font-weight: 600;
}

.skip-link:focus {
  left: 0;
}

/* Texte réservé aux lecteurs d'écran. Contrairement à .skip-link, qui doit
   redevenir visible au clavier, ce motif ne prend jamais le focus : il ajoute
   une précision que la mise en page ne peut pas afficher (par exemple
   « (nouvel onglet) » après un lien sortant). */
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* ---------- Boutons ---------- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 13px 24px;
  border-radius: 10px;
  font-size: 1rem;
  font-weight: 600;
  line-height: 1;
  font-family: inherit;
  cursor: pointer;
  border: 1px solid transparent;
  transition: background-color 0.18s ease, border-color 0.18s ease,
    color 0.18s ease, transform 0.18s ease, box-shadow 0.18s ease;
}

.btn:hover {
  text-decoration: none;
  transform: translateY(-1px);
}

.btn-primary {
  background: var(--accent);
  color: #fff;
  box-shadow: 0 2px 12px rgba(37, 99, 235, 0.25);
}

.btn-primary:hover {
  background: var(--accent-hover);
}

.btn-secondary {
  background: #fff;
  color: var(--text);
  border-color: var(--border);
}

.btn-secondary:hover {
  border-color: var(--accent);
  color: var(--accent);
}

/* ---------- En-tête ---------- */
.site-header {
  position: sticky;
  top: 0;
  z-index: 50;
  /* min-height (et non height) : avec un texte agrandi à 200 %, l'en-tête
     grandit au lieu de rogner les liens (WCAG 1.4.4) */
  min-height: var(--header-h);
  display: flex;
  align-items: center;
  background: rgba(255, 255, 255, 0.88);
  backdrop-filter: blur(10px);
  border-bottom: 1px solid var(--border);
}

.header-inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  /* Repli sur deux lignes si la navigation ne tient plus (taille de texte
     agrandie) : jamais de débordement horizontal (WCAG 1.4.4 / 1.4.10) */
  flex-wrap: wrap;
  gap: 24px;
}

.brand {
  display: inline-flex;
  align-items: center;
  gap: 12px;
  color: var(--text);
  font-weight: 700;
}

.brand:hover {
  text-decoration: none;
}

/* Pictogramme du logo (dérivé de sources/logo-*.png par tools/generate-images.py).
   Image décorative (alt="" + aria-hidden) : le nom accessible du lien reste
   « Andy Rakotondrabe — accueil » (WCAG 2.5.3, libellé dans le nom). Taille en
   px fixes, stable si la taille de texte du navigateur double (WCAG 1.4.4). */
.brand-mark {
  display: inline-flex;
  align-items: center;
  flex: none;
}

.brand-mark img {
  display: block;
  height: 38px;
  width: auto;
}

.brand-name {
  font-size: 1rem;
  letter-spacing: -0.01em;
}

.nav-list {
  display: flex;
  align-items: center;
  gap: 4px;
  /* Si la navigation entient plus à 200 % de texte, les liens passent sur
     plusieurs lignes dans l'en-tête au lieu de déborder (WCAG 1.4.4). */
  flex-wrap: wrap;
  list-style: none;
  margin: 0;
  padding: 0;
}

.nav-list a {
  display: inline-block;
  padding: 9px 14px;
  border-radius: 8px;
  color: var(--text-muted);
  font-size: 0.95rem;
  font-weight: 500;
  transition: color 0.15s ease, background-color 0.15s ease;
}

.nav-list a:hover {
  color: var(--text);
  background: var(--bg-soft);
  text-decoration: none;
}

/* Section courante : couleur ET soulignement — l'information ne doit pas
   reposer sur la seule couleur (WCAG 1.4.1). Le soulignement survit au survol
   (spécificité supérieure à .nav-list a:hover). `aria-current="location"` est
   posé en JS par le scrollspy. */
.nav-list a.active {
  color: var(--accent);
  text-decoration: underline;
  text-decoration-thickness: 2px;
  text-underline-offset: 5px;
}

/* Le CTA « Me contacter » est un lien de la liste : les règles ciblées ci-dessous
   portent le niveau de spécificité de `.nav-list a` (gris) pour ne pas dépendre
   de `!important`. En section courante, le texte reste blanc (bleu sur bleu
   serait illisible) ; le soulignement signale l'état actif. */
.nav-list a.nav-cta {
  margin-left: 8px;
  padding: 10px 18px;
  font-size: 0.95rem;
  color: #fff;
}

.nav-list a.nav-cta:hover {
  color: #fff;
  background: var(--accent-hover);
}

.nav-list a.nav-cta.active {
  color: #fff;
}

.nav-toggle {
  display: none;
  flex-direction: column;
  justify-content: center;
  gap: 5px;
  width: 44px;
  height: 44px;
  padding: 10px;
  background: #fff;
  border: 1px solid var(--border);
  border-radius: 10px;
  cursor: pointer;
}

.nav-toggle span {
  display: block;
  height: 2px;
  background: var(--text);
  border-radius: 2px;
}

/* ---------- Hero ---------- */
.hero {
  padding: 96px 0 88px;
  background:
    radial-gradient(900px 400px at 80% -10%, var(--accent-soft), transparent 60%),
    var(--bg);
  border-bottom: 1px solid var(--border);
}

.hero-inner {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: center;
  gap: 56px;
}

.hero-photo {
  justify-self: end;
}

.hero-photo picture {
  display: block;
}

.hero-photo img {
  display: block;
  width: 300px;
  height: auto;
  aspect-ratio: 1 / 1;
  max-width: 100%;
  object-fit: cover;
  border-radius: 50%;
  border: 4px solid #fff;
  box-shadow: 0 14px 44px rgba(15, 23, 42, 0.16);
}

.hero-eyebrow {
  text-transform: uppercase;
  letter-spacing: 0.14em;
  font-size: 0.8rem;
  font-weight: 700;
  color: var(--accent);
  margin-bottom: 14px;
}

.hero-title {
  font-size: clamp(2.4rem, 6vw, 3.6rem);
  line-height: 1.08;
  letter-spacing: -0.03em;
  font-weight: 800;
  /* « Rakotondrabe » est trop long pour tenir dans la colonne à 200 % de
     texte : on autorise la coupure du mot plutôt que le débordement horizontal
     (WCAG 1.4.4). À taille normale, le mot tient : rien ne change visuellement. */
  overflow-wrap: anywhere;
}

/* Signature de marque (titre de métier anglais) : volontairement discrète,
   la promesse ci-dessous porte le message. */
.hero-subtitle {
  margin-top: 10px;
  font-size: clamp(1.05rem, 2vw, 1.15rem);
  font-weight: 600;
  color: var(--text-muted);
}

/* Promesse : le message principal du hero (le bénéfice client). Remontée
   au-dessus de la liste de prestations et mise en avant. La barre d'accent
   est décorative et sortie du flux, pour que le texte démarre exactement sur
   la même colonne que « À propos ». */
.hero-promise {
  position: relative;
  margin-top: 26px;
  font-size: clamp(1.1rem, 2.2vw, 1.3rem);
  font-weight: 500;
  line-height: 1.55;
  color: var(--text);
  max-width: var(--measure);
}

.hero-promise::before {
  content: "";
  position: absolute;
  left: -14px;
  top: 4px;
  bottom: 4px;
  width: 3px;
  border-radius: 2px;
  background: var(--accent);
}

/* Livrables : la liste de ce qui est concrètement produit, en retrait. */
.hero-tagline {
  margin-top: 14px;
  font-size: 1rem;
  color: var(--text-muted);
  max-width: var(--measure);
}

.hero-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  margin-top: 16px;
}

/* Trois appels à l'action sur une seule ligne dans la colonne de texte du hero
   (≥ 1049 px) : on resserre le padding horizontal et l'espacement, pas la
   typographie. En dessous, les boutons se replient normalement (flex-wrap). */
.hero-actions .btn {
  padding: 11px 12px;
}

/* Signal de disponibilité : statut stable, sans date à maintenir (règle du
   site : n'afficher que des faits qui ne se périment pas). Badge pilule mis
   en évidence au-dessus des CTA (le statut rassure juste avant la décision
   de clic) — vert « succès » du formulaire (#15803d) sur fond vert très
   clair (contraste ≈ 4,8:1, conforme AA). Le point vert porte un halo
   pulsé (signal « en activité »), neutralisé sous prefers-reduced-motion. */
.hero-availability {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  margin-top: 18px;
  padding: 8px 16px;
  font-size: 0.95rem;
  font-weight: 700;
  color: #15803d;
  background: #f0fdf4;
  border: 1px solid #bbf7d0;
  border-radius: 999px;
  box-shadow: 0 2px 10px rgba(21, 128, 61, 0.12);
}

.hero-availability::before {
  content: "";
  flex: none;
  width: 0.6rem;
  height: 0.6rem;
  border-radius: 50%;
  background: #15803d;
  animation: dispo-pulse 2.4s ease-out infinite;
}

@keyframes dispo-pulse {
  0% {
    box-shadow: 0 0 0 0 rgba(21, 128, 61, 0.45);
  }
  70% {
    box-shadow: 0 0 0 8px rgba(21, 128, 61, 0);
  }
  100% {
    box-shadow: 0 0 0 0 rgba(21, 128, 61, 0);
  }
}

/* Variantes du protocole à 3 états (README « Protocole de disponibilité ») :
   une seule pastille affichée à la fois, l'état canonique étant la classe du
   badge. Palettes conformes AA comme le vert — ambre ≈ 6,8:1, rouge ≈ 5,9:1 —
   et la couleur n'est jamais le seul signal : le libellé texte porte le sens
   (WCAG 1.4.1). Chaque variante a ses propres keyframes, teintées à sa couleur. */
.hero-availability--limite {
  color: #92400e;
  background: #fffbeb;
  border-color: #fde68a;
  box-shadow: 0 2px 10px rgba(146, 64, 14, 0.12);
}

.hero-availability--limite::before {
  background: #d97706;
  animation-name: dispo-pulse-limite;
}

@keyframes dispo-pulse-limite {
  0% {
    box-shadow: 0 0 0 0 rgba(217, 119, 6, 0.45);
  }
  70% {
    box-shadow: 0 0 0 8px rgba(217, 119, 6, 0);
  }
  100% {
    box-shadow: 0 0 0 0 rgba(217, 119, 6, 0);
  }
}

.hero-availability--complet {
  color: #b91c1c;
  background: #fef2f2;
  border-color: #fecaca;
  box-shadow: 0 2px 10px rgba(185, 28, 28, 0.12);
}

.hero-availability--complet::before {
  background: #dc2626;
  animation-name: dispo-pulse-complet;
}

@keyframes dispo-pulse-complet {
  0% {
    box-shadow: 0 0 0 0 rgba(220, 38, 38, 0.45);
  }
  70% {
    box-shadow: 0 0 0 8px rgba(220, 38, 38, 0);
  }
  100% {
    box-shadow: 0 0 0 0 rgba(220, 38, 38, 0);
  }
}

/* Micro-réassurance collée au CTA principal : le délai de réponse est la
   première objection avant d'écrire à un freelance. */
.hero-reassurance {
  margin-top: 14px;
  font-size: 0.9rem;
  font-weight: 600;
  color: var(--text-muted);
}

.hero-meta {
  margin-top: 26px;
  font-size: 0.92rem;
  color: var(--text-muted);
  font-weight: 500;
}

/* ---------- Sections ---------- */
.section {
  padding: 84px 0;
}

.section-soft {
  background: var(--bg-soft);
  border-top: 1px solid var(--border);
  border-bottom: 1px solid var(--border);
}

.section-eyebrow {
  text-transform: uppercase;
  letter-spacing: 0.14em;
  font-size: 0.78rem;
  font-weight: 700;
  color: var(--accent);
  margin-bottom: 10px;
}

.section-title {
  font-size: clamp(1.7rem, 3.4vw, 2.1rem);
  letter-spacing: -0.02em;
  font-weight: 800;
  margin-bottom: 28px;
  /* Répartit la longueur des lignes si le titre venait à se replier. */
  text-wrap: balance;
  /* « Réalisations » ne tient plus dans la colonne à 320 px × 200 % de
     texte : coupure du mot autorisée plutôt que débordement (WCAG 1.4.4). */
  overflow-wrap: anywhere;
}

/* Chapeau de section : une phrase de cadrage (pour qui / quel résultat)
   placée sous le titre, sur la même largeur de lecture que les autres blocs. */
.section-lead {
  max-width: var(--measure);
  margin: -12px 0 32px;
  color: var(--text-muted);
  font-size: 1.05rem;
}

/* ---------- Prose ---------- */
.prose {
  max-width: var(--measure);
  display: grid;
  gap: 18px;
  color: var(--text-muted);
  font-size: 1.08rem;
}

.prose strong {
  color: var(--text);
}

/* Texte justifié : bords gauche ET droit alignés sur la largeur commune (--measure).
   Appliqué à TOUS les textes de blocs, à toutes les largeurs — smartphone compris
   (le retour en fer à gauche sous 640 px a été levé : la césure française
   (html lang="fr") compense les lignes courtes et limite les écarts entre les
   mots, indispensable dans les colonnes étroites des cartes et en 390 px).
   Couverts : promesse, tagline, micro-réassurance et méta du
   hero, chapôs de section, paragraphes et listes de contenu (À propos, mentions
   légales), textes des cartes, questions et réponses de la FAQ (listes
   numérotées comprises), fer de page de la FAQ, aide et statut du formulaire,
   intro Contact, puis les textes du CV (titre, paragraphes et listes de
   section — le PDF, lui, garde son fer à gauche : voir le @media print de
   cv.html).
   Exclus volontairement : titres, métadonnées, labels et liens (lignes uniques,
   aucune ligne à étirer). La dernière ligne de chaque bloc reste en fer à gauche,
   comme l'exige la règle du justify. */
.hero-tagline,
.hero-promise,
.hero-reassurance,
.hero-meta,
.section-lead,
.prose p,
.prose li,
.card-text,
.faq-item summary,
.faq-answer p,
.faq-answer li,
.faq-cta,
.form-help,
.form-status,
.contact-lead,
.cv-titre,
.cv-section p,
.cv-section li {
  text-align: justify;
  text-justify: inter-word;
  -webkit-hyphens: auto;
  hyphens: auto;
}

/* Les cartes de « Prestations » et de « Réalisations » contiennent un vrai
   paragraphe : leurs grilles passent donc à deux colonnes (mesure ≈ 29 em) au
   lieu de trois (19 em), où les lignes seraient trop courtes et la césure trop
   fréquente. Les deux sections gardent ainsi le même rythme. La justification
   elle-même s'applique à toutes les largeurs (voir la règle ci-dessus), y
   compris sous 640 px, où la césure française limite les blancs entre les mots. */
#services .cards-grid,
#realisations .cards-grid {
  grid-template-columns: repeat(auto-fit, minmax(min(400px, 100%), 1fr));
}

/* ---------- Page annexe : confidentialité & mentions légales ---------- */
.legal .prose {
  max-width: 760px;
  gap: 14px;
}

.legal .prose h2 {
  margin-top: 18px;
  font-size: 1.15rem;
  font-weight: 700;
  letter-spacing: -0.01em;
  color: var(--text);
}

.legal .prose h3 {
  font-size: 1rem;
  font-weight: 700;
  color: var(--text);
}

.legal .prose ul {
  margin: 0;
  padding-left: 20px;
  display: grid;
  gap: 6px;
}

.legal .prose a {
  text-decoration: underline;
  text-underline-offset: 2px;
}

.legal .prose a.btn {
  text-decoration: none;
}

.legal-back {
  margin-top: 10px;
}

/* ---------- Section À propos ----------
   Récit à gauche sur la largeur de lecture commune (--measure), encadré de
   repères à droite. Les deux colonnes s'empilent au même palier que le hero. */
.about-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 320px);
  gap: 40px;
  align-items: start;
}

/* Renvoi interne dans le récit (ex. vers les réalisations) : souligné pour
   être identifiable au milieu du texte, l'accent seul ne suffisant pas. */
.about-grid .prose a {
  font-weight: 600;
  text-decoration: underline;
  text-underline-offset: 2px;
}

/* Encadré « Repères » : résumé factuel scannable (chiffres et repères clés),
   sur fond doux et barre d'accent à gauche, comme l'encadré du hero. */
.about-box {
  padding: 22px 24px;
  background: var(--bg-soft);
  border: 1px solid var(--border);
  border-left: 3px solid var(--accent);
  border-radius: var(--radius);
}

.about-box-title {
  margin-bottom: 14px;
  font-size: 0.78rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.14em;
  color: var(--accent);
}

.about-facts {
  margin: 0;
  display: grid;
  gap: 12px;
}

.about-facts dt {
  font-weight: 700;
  line-height: 1.3;
  color: var(--text);
}

.about-facts dd {
  margin: 2px 0 0;
  font-size: 0.95rem;
  line-height: 1.45;
  color: var(--text-muted);
}

/* ---------- Cartes ---------- */
.cards-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
  gap: 20px;
}

.card {
  background: #fff;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 26px;
  box-shadow: var(--shadow-sm);
  transition: transform 0.18s ease, box-shadow 0.18s ease,
    border-color 0.18s ease;
}

/* Survol des cartes : le « soulèvement » est réservé aux cartes cliquables
   (.card-link). Une carte statique qui se soulève laisse croire à un lien
   inexistant — les prestations ne gardent qu'un rappel de bordure. */
.card:not(.card-link):hover {
  border-color: #cbd5e1;
}

.card-icon {
  width: 46px;
  height: 46px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 11px;
  background: var(--accent-soft);
  color: var(--accent);
  margin-bottom: 18px;
}

.card-icon svg {
  width: 24px;
  height: 24px;
}

/* Logo du média, en tête des cartes « Réalisations » */
.card-logo {
  display: flex;
  align-items: center;
  height: 30px;
  margin-bottom: 14px;
}

.card-logo img {
  height: 100%;
  width: auto;
  max-width: 100%;
  object-fit: contain;
}

.card-title {
  font-size: 1.1rem;
  font-weight: 700;
  margin-bottom: 8px;
  letter-spacing: -0.01em;
}

.card-text {
  color: var(--text-muted);
  font-size: 0.98rem;
  /* Mots composés des cartes : coupure autorisée si le mot dépasse la
     colonne (taille de texte agrandie, WCAG 1.4.4). */
  overflow-wrap: anywhere;
}

.card-link {
  display: block;
  position: relative;
  color: inherit;
}

.card-link:hover {
  text-decoration: none;
  transform: translateY(-3px);
  box-shadow: var(--shadow-md);
  border-color: #cbd5e1;
}

.card-meta {
  font-size: 0.88rem;
  font-weight: 600;
  color: var(--accent);
  margin-bottom: 8px;
}

.card-arrow {
  display: inline-block;
  margin-top: 16px;
  font-weight: 700;
  color: var(--accent);
  transition: transform 0.18s ease;
}

.card-link:hover .card-arrow {
  transform: translateX(4px);
}

/* ---------- Carte d'appel à l'action ---------- */
/* Sixième carte de « Services » et de « Réalisations » : teintée d'accent pour
   se distinguer des cartes de contenu, et compléter la grille (6 cartes =
   aucune ligne incomplète, que la grille affiche 3, 2 ou 1 colonne). */
.card-cta {
  display: flex;
  flex-direction: column;
  background: var(--accent-soft);
  border-color: #bfdbfe;
}

/* Flèche calée en bas de carte : elle occupe le vide laissé par la hauteur
   de la ligne de grille, au lieu de flotter sous le texte. */
.card-cta .card-arrow {
  margin-top: auto;
  padding-top: 16px;
}

.card-cta .card-icon {
  background: #fff;
}

.card-cta .card-title {
  color: var(--accent-hover);
}

/* Bleu foncé : le gris atténué des cartes n'atteint pas le contraste AA
   sur ce fond teinté (4,3:1 au lieu des 4,5:1 exigés). */
.card-cta .card-text {
  color: #1e40af;
}

.card-cta:hover {
  border-color: var(--accent);
}

.note {
  margin-top: 26px;
  color: var(--text-muted);
  font-size: 0.95rem;
  max-width: 720px;
}

.more-pubs {
  margin-top: 40px;
}

.more-pubs-title {
  font-size: 1.05rem;
  font-weight: 700;
  margin-bottom: 6px;
}

.more-pubs-lead {
  margin-bottom: 16px;
  font-size: 0.95rem;
  color: var(--text-muted);
}

/* Grille des autres médias : une « pastille » cliquable par média */
/* Grille des autres médias : occupe la même largeur que .cards-grid (Réalisations)
   et place les pastilles sur une seule ligne dès qu'il y a la place. */
.media-grid {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
  gap: 20px;
}

.media-grid a {
  display: flex;
  flex-direction: row;
  align-items: center;
  gap: 10px;
  height: 100%;
  padding: 12px 14px;
  background: #fff;
  border: 1px solid var(--border);
  border-radius: 10px;
  color: var(--text);
  font-size: 0.98rem;
  font-weight: 600;
  line-height: 1.35;
  transition: transform 0.18s ease, border-color 0.18s ease,
    box-shadow 0.18s ease;
}

.media-logo {
  width: 22px;
  height: 22px;
  flex: none;
  object-fit: contain;
}

.media-text {
  display: flex;
  flex-direction: column;
  gap: 1px;
  min-width: 0;
  /* « Blog-United », « PIX GEEKS »… : à 200 % de texte, le jeton dépasse la
     pastille et fait défiler la page. On coupe le mot seulement si nécessaire
     (WCAG 1.4.4) — à taille normale, rien ne change. */
  overflow-wrap: anywhere;
}

.media-grid a:hover {
  text-decoration: none;
  border-color: var(--accent);
  box-shadow: var(--shadow-sm);
  transform: translateY(-2px);
}

.media-host {
  font-size: 0.78rem;
  font-weight: 500;
  color: var(--text-muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* ---------- FAQ ---------- */
.faq {
  display: grid;
  gap: 12px;
  max-width: 820px;
}

.faq-item {
  background: #fff;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  overflow: hidden;
  transition: box-shadow 0.18s ease, border-color 0.18s ease;
}

.faq-item[open] {
  border-color: #cbd5e1;
  box-shadow: var(--shadow-sm);
}

.faq-item summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 18px 22px;
  cursor: pointer;
  font-weight: 600;
  font-size: 1.02rem;
  list-style: none;
  color: var(--text);
}

.faq-item summary::-webkit-details-marker {
  display: none;
}

.faq-item summary:hover {
  color: var(--accent);
}

.faq-item summary:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: -2px;
}

/* Ouverture animée — progressive enhancement :
   sans support de ::details-content, l'ouverture reste instantanée. */
.faq-item::details-content {
  block-size: 0;
  overflow: hidden;
  transition: block-size 0.25s ease;
}

.faq-item[open]::details-content {
  block-size: auto;
}

@media (prefers-reduced-motion: reduce) {
  .faq-item::details-content {
    transition: none;
  }
}

.faq-item summary::after {
  content: "+";
  font-size: 1.4rem;
  font-weight: 400;
  line-height: 1;
  color: var(--accent);
  transition: transform 0.2s ease;
}

.faq-item[open] summary::after {
  transform: rotate(45deg);
}

.faq-answer {
  padding: 0 22px 20px;
  color: var(--text-muted);
  font-size: 0.99rem;
}

.faq-answer ol {
  margin: 0;
  padding-left: 20px;
  display: grid;
  gap: 6px;
}

.faq-answer a {
  font-weight: 600;
}

.faq-cta {
  margin-top: 20px;
  font-size: 0.98rem;
  color: var(--text-muted);
}

.faq-cta a {
  font-weight: 600;
}

/* ---------- Contact ---------- */
.contact-grid {
  display: grid;
  grid-template-columns: 1fr 1.2fr;
  gap: 44px;
  align-items: start;
}

/* Colonne d'infos : sans min-width:0, la largeur min-content de l'email non
   coupable (andy261mdg@gmail.com) élargit la piste de grille au-delà du
   conteneur quand la taille de texte double (WCAG 1.4.4). */
.contact-info {
  min-width: 0;
  overflow-wrap: anywhere;
}

.contact-lead {
  font-size: 1.1rem;
  color: var(--text-muted);
  margin-bottom: 26px;
  /* Même mesure que les autres blocs de texte (--measure, et non un plafond
     arbitraire à 380 px). En colonne empilée (≤ 860 px), l'intro rejoint la
     largeur des chapôs et des récits ; en desktop, la colonne (≈ 464-576 px)
     est déjà sous la mesure : l'intro prend toute la largeur de la colonne,
     alignée sur les coordonnées juste en dessous. */
  max-width: var(--measure);
}

.contact-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 16px;
}

.contact-list li {
  display: grid;
  gap: 2px;
}

.contact-label {
  font-size: 0.8rem;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  font-weight: 700;
  color: var(--text-muted);
}

.contact-list a,
.contact-value {
  font-weight: 600;
  font-size: 1.02rem;
}

.copy-btn {
  justify-self: start;
  margin-top: 6px;
  padding: 6px 12px;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: #fff;
  color: var(--text-muted);
  font-family: inherit;
  font-size: 0.82rem;
  font-weight: 600;
  cursor: pointer;
  transition: color 0.15s ease, border-color 0.15s ease, background-color 0.15s ease;
}

.copy-btn:hover {
  color: var(--accent);
  border-color: var(--accent);
  background: var(--accent-soft);
}

/* Sur écran tactile, le bouton « Copier l'adresse » atteint la cible
   confortable de 44 px (il mesure 30 px à la souris, ce qui suffit au pointeur
   fin mais pas au doigt). */
@media (pointer: coarse) {
  .copy-btn {
    min-height: 44px;
    padding: 10px 16px;
  }
}

.contact-form {
  background: #fff;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 28px;
  box-shadow: var(--shadow-sm);
  display: grid;
  gap: 16px;
  /* Élément de grille : sans cela, la largeur intrinsèque du <select> (options
     × 200 % de texte) fait déborder le formulaire hors de sa piste. */
  min-width: 0;
}

.form-row {
  display: grid;
  gap: 6px;
  min-width: 0;
}

.form-row label {
  font-size: 0.9rem;
  font-weight: 600;
  color: var(--text);
}

.contact-form input,
.contact-form textarea,
.contact-form select {
  width: 100%;
  /* le <select> a une largeur intrinsèque (options) : on l'autorise à
     rétrécir sous sa taille minimale dans une colonne étroite */
  min-width: 0;
  padding: 12px 14px;
  border: 1px solid var(--border);
  border-radius: 10px;
  font-family: inherit;
  font-size: 1rem;
  color: var(--text);
  background: #fff;
  transition: border-color 0.15s ease, box-shadow 0.15s ease;
}

.contact-form input:focus,
.contact-form textarea:focus,
.contact-form select:focus {
  border-color: var(--accent);
}

/* Champ invalide : bordure rouge, doublée du message texte — la couleur n'est
   jamais le seul indicateur. L'anneau de focus du site reste visible par-dessus
   (outline `:focus-visible`), si bien que les deux états restent distincts. */
.contact-form [aria-invalid="true"],
.contact-form [aria-invalid="true"]:focus,
.contact-form [aria-invalid="true"]:focus-visible {
  border-color: #b91c1c;
}

/* Message d'erreur rattaché au champ (RGAA 11.10) */
.form-error {
  margin: 0;
  font-size: 0.85rem;
  font-weight: 600;
  line-height: 1.4;
  color: #b91c1c;
}

.form-error:empty {
  display: none;
}

/* Aide à la saisie sous un champ */
.form-help {
  margin: 0;
  font-size: 0.85rem;
  color: var(--text-muted);
}

.contact-form textarea {
  resize: vertical;
  min-height: 120px;
}

.contact-form .btn {
  width: 100%;
}

.form-hint {
  font-size: 0.85rem;
  color: var(--text-muted);
  text-align: center;
}

.form-hint a {
  font-weight: 600;
}

/* Mention « (facultatif) » dans les libellés de formulaire */
.label-optional {
  font-weight: 500;
  font-size: 0.85em;
  color: var(--text-muted);
}

.form-status {
  margin: 0;
  font-size: 0.88rem;
  font-weight: 600;
  line-height: 1.5;
  color: var(--accent);
}

.form-status:empty {
  display: none;
}

.form-status a {
  color: inherit;
  text-decoration: underline;
  text-underline-offset: 2px;
}

.form-status[data-state="success"] {
  color: #15803d;
}

.form-status[data-state="error"] {
  color: #b91c1c;
}

/* Champ leurre anti-robots : hors écran, jamais visible ni focusable */
.form-honeypot {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

.contact-form .btn:disabled {
  opacity: 0.7;
  cursor: progress;
}

/* ---------- Pied de page ---------- */
.site-footer {
  border-top: 1px solid var(--border);
  padding: 32px 0;
  background: #fff;
}

.footer-inner {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}

.footer-copy {
  font-size: 0.9rem;
  color: var(--text-muted);
}

.footer-links {
  display: flex;
  /* Les liens passent sur plusieurs lignes à 200 % de texte plutôt que de
     faire défiler la page horizontalement (WCAG 1.4.4). */
  flex-wrap: wrap;
  gap: 20px;
  font-size: 0.9rem;
  font-weight: 600;
}

/* ---------- Responsive ---------- */
/* Le hero passe sur une seule colonne dès que sa colonne de texte deviendrait
   plus étroite que --measure : le bloc de texte conserve ainsi exactement la
   même largeur que ceux des sections (hero / À propos alignés partout). */
@media (max-width: 1048px) {
  .hero-inner {
    grid-template-columns: 1fr;
    gap: 30px;
  }

  /* L'encadré de repères passe sous le récit, aligné sur la colonne de texte
     (et non sur toute la largeur du conteneur). */
  .about-grid {
    grid-template-columns: 1fr;
    gap: 28px;
  }

  .about-box {
    max-width: var(--measure);
  }

  .hero-photo {
    order: -1;
    /* Centrée sur l'écran en empilement (smartphone ET tablette) : la photo
       du hero reste au milieu, quelle que soit la largeur empilée. La règle
       « hero / À propos alignés partout » concerne les blocs de texte. */
    justify-self: center;
  }

  .hero-photo img {
    width: 190px;
    height: auto;
  }
}

@media (max-width: 860px) {
  .contact-grid {
    grid-template-columns: 1fr;
    gap: 34px;
  }
}

/* Sous 640 px, seule la barre d'accent de la promesse se rapproche du bord du
   bloc. Les blocs de texte restent justifiés : bords gauche et droit alignés. */
@media (max-width: 640px) {
  .hero-promise::before {
    left: -12px;
  }
}

@media (max-width: 768px) {
  .nav-toggle {
    display: inline-flex;
  }

  .nav-list {
    position: absolute;
    /* 100 % de la hauteur réelle de l'en-tête (et non --header-h) : le panneau
       suit l'en-tête quand le texte est agrandi */
    top: 100%;
    left: 0;
    right: 0;
    flex-direction: column;
    align-items: stretch;
    gap: 4px;
    padding: 14px 24px 22px;
    background: #fff;
    border-bottom: 1px solid var(--border);
    box-shadow: var(--shadow-md);
    display: none;
  }

  .nav-list.open {
    display: flex;
  }

  .nav-list a {
    padding: 12px 14px;
  }

  .nav-list a.nav-cta {
    margin: 8px 0 0;
    text-align: center;
  }

  .hero {
    padding: 64px 0 56px;
  }

  .section {
    padding: 60px 0;
  }
}

/* ---------- Mouvement réduit (accessibilité) ---------- */
@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;
    scroll-behavior: auto !important;
  }

  .btn:hover {
    transform: none;
  }

  /* Halo de la pastille de disponibilité : statique, pas de pulsation. */
  .hero-availability::before {
    animation: none;
  }

  .media-grid a:hover {
    transform: none;
  }

  .card-link:hover {
    transform: none;
  }
}
