/* ==========================================================
   PORTFOLIO - JÉRÔME DORION
   Feuille de style principale
   Structure :
   1. Variables & reset
   2. Typographie
   3. Navigation
   4. Hero (accueil)
   5. Section projets
   6. Section à propos
   7. Pied de page
   8. Pages projets
   9. Animations & responsive
   ========================================================== */

/* ----- 1. Variables & reset ----- */
:root {
  --papier: #fafafa;        /* fond principal, blanc très légèrement cassé */
  --encre: #111111;         /* texte principal, noir */
  --encre-douce: #666666;   /* texte secondaire, gris neutre */
  --accent: #111111;        /* accent : noir (palette noir et blanc) */
  --ligne: #e6e6e6;         /* bordures fines, gris pâle */
  --carte: #fafafa;         /* fond des cartes, même ton que le fond */

  --police-titre: "Manrope", sans-serif;
  --police-display: "Anton", sans-serif; /* gros titre display (nom de l'accueil) */
  --police-texte: "Manrope", sans-serif;
  --police-accent: "Manrope", sans-serif; /* TEST : Manrope partout (au lieu d'IBM Plex Mono) - remettre la valeur mono pour annuler */

  --largeur-max: none; /* aucun plafond : le contenu prend toute la largeur */
  --rayon: 0; /* coins carrés partout, style droit et neutre */
}

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

html {
  scroll-behavior: smooth;
  /* noir derrière le body : l'instant de bascule entre deux pages est donc
     noir (comme le rideau) au lieu d'un flash blanc. */
  background: var(--encre);
}

/* Typographie fluide : sur grand écran, la taille de base (donc tout ce qui
   est en rem) suit la largeur de l'écran, pour garder la MÊME composition
   d'une résolution à l'autre (ex. 1920 vs 2K). Sous 1000px (tablette/mobile),
   on garde la taille par défaut pour ne pas y rapetisser le texte.
   Repères : ~14px à 1920, ~16px à 2560. */
@media (min-width: 1000px) {
  html {
    font-size: clamp(14px, 0.23vw + 10px, 16px);
  }
}

body {
  background: var(--papier);
  min-height: 100vh; /* couvre toujours l'écran : pas de noir visible hors transition */
  color: var(--encre);
  font-family: var(--police-texte);
  font-size: 1.05rem;
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
  overflow-x: clip; /* le fond pleine largeur du contenu ne crée pas de scroll horizontal */
}

img, video {
  max-width: 100%;
  display: block;
  border-radius: var(--rayon);
}

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

.conteneur {
  max-width: var(--largeur-max);
  margin: 0 auto;
  padding: 0 clamp(64px, 8vw, 160px);
}

/* ----- 2. Typographie ----- */
h1, h2, h3 {
  font-family: var(--police-titre);
  line-height: 1.1;
}

h1, h2 {
  text-transform: uppercase;
  letter-spacing: -0.01em;
}

/* Sous-titres (h3) : casse normale et crénage légèrement ouvert
   pour une meilleure lisibilité */
h3 {
  letter-spacing: 0.01em;
}

.titre-section {
  font-size: clamp(1.6rem, 3.5vw, 2.4rem);
  margin-bottom: 2.5rem;
  display: flex;
  align-items: center;
  gap: 1rem;
  /* reste en majuscules même en h3 (ex. : « Voir un autre projet ») */
  text-transform: uppercase;
  letter-spacing: -0.01em;
}

.titre-section::after {
  content: "";
  flex: 1;
  height: 1px;
  background: var(--ligne);
}

/* Classe neutralisée : les mots marqués suivent maintenant
   le texte courant (aucune mise en évidence typographique). */
.accent-serif {
  font: inherit;
  color: inherit;
}

/* ----- 3. Navigation ----- */
.nav {
  position: sticky;
  top: 0;
  z-index: 50;
  background: color-mix(in srgb, var(--papier) 85%, transparent);
  backdrop-filter: blur(10px);
  border-bottom: 1px solid var(--ligne);
}

.nav-inner {
  max-width: var(--largeur-max);
  margin: 0 auto;
  padding: 28px clamp(64px, 8vw, 160px); /* navigation plus aérée verticalement */
  display: flex;
  align-items: center;
  gap: 0.75rem; /* JD et le rôle rapprochés */
}

.nav-logo {
  font-family: var(--police-titre);
  font-weight: 800;
  font-size: 1.2rem;
}

.nav-role {
  color: var(--encre); /* même couleur (noir) que « Jérôme Dorion » et les liens de nav */
  font-size: 0.82rem; /* même taille que les mots de la nav */
  text-transform: uppercase;
  letter-spacing: 0.04em;
  border-left: 1px solid var(--ligne);
  padding-left: 0.75rem;
  display: inline-flex;      /* centre le rôle verticalement avec « JD » */
  align-items: center;
}

/* Survol de « Designer d'interaction » : il glisse vers la droite et laisse
   entrer « Jérôme Dorion » par la gauche ; tout revient au départ à la sortie. */
.role-piste {
  position: relative;
  display: inline-block;
  overflow: hidden;
  vertical-align: middle;
  white-space: nowrap;
}

.role-txt {
  display: inline-block;
  white-space: nowrap;
  /* Courbe symétrique (ease-in-out) : l'aller (Jérôme entre) et le retour
     (Designer revient) glissent avec la même douceur aux deux extrémités. */
  transition: transform 0.5s cubic-bezier(0.65, 0, 0.35, 1),
              opacity 0.45s cubic-bezier(0.65, 0, 0.35, 1);
}

.role-nom {
  position: absolute;
  left: 0;
  top: 0;
  color: var(--encre);
  transform: translateY(110%); /* caché juste en dessous */
  opacity: 0;
}

.nav-role:hover .role-defaut {
  transform: translateY(-110%); /* monte et sort par le haut */
  opacity: 0;
}

.nav-role:hover .role-nom {
  transform: translateY(0); /* monte depuis le bas jusqu'en place */
  opacity: 1;
}

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

.nav-liens {
  margin-left: auto;
  margin-right: 3rem; /* décalé un peu vers la gauche (English reste à droite) */
  display: flex;
  gap: 2.75rem; /* liens de navigation plus aérés */
  font-size: 0.82rem; /* réduit car en majuscules (sinon trop gros) */
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

.nav-liens a {
  position: relative;
}

/* Survol de la navigation : des crochets [ ] apparaissent de chaque côté du
   mot (au lieu d'une barre qui s'allonge). En absolu = aucun décalage de la
   mise en page ; ils glissent vers le mot en apparaissant. */
.nav-liens > a::before,
.nav-liens > a::after,
.nav-langue::before,
.nav-langue::after,
.nav-contact-bouton::before,
.nav-contact-bouton::after {
  position: absolute;
  top: 0;
  bottom: 0;
  display: flex;
  align-items: center;
  opacity: 0;
  pointer-events: none;
  color: var(--encre);
  transition: opacity 0.2s ease, transform 0.25s cubic-bezier(0.33, 1, 0.68, 1);
}

.nav-liens > a::before,
.nav-langue::before,
.nav-contact-bouton::before {
  content: "[";
  right: calc(100% + 0.12em);
  transform: translateX(0.3em);
}

.nav-liens > a::after,
.nav-langue::after,
.nav-contact-bouton::after {
  content: "]";
  left: calc(100% + 0.12em);
  transform: translateX(-0.3em);
}

.nav-liens > a:hover::before,
.nav-liens > a:hover::after,
.nav-liens > a.actif::before,
.nav-liens > a.actif::after,
.nav-langue:hover::before,
.nav-langue:hover::after,
.nav-contact:hover .nav-contact-bouton::before,
.nav-contact:hover .nav-contact-bouton::after,
.nav-contact:focus-within .nav-contact-bouton::before,
.nav-contact:focus-within .nav-contact-bouton::after {
  opacity: 1;
  transform: translateX(0);
}

/* ----- « Me contacter » : volet déroulant (Courriel + LinkedIn) ----- */
.nav-contact {
  position: relative;
}

/* Le bouton se fond avec les autres liens de la nav. */
.nav-contact-bouton {
  font: inherit;
  color: inherit;
  background: none;
  border: none;
  padding: 0;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  position: relative;
}

/* Chevron de « Me contacter » : caché sur grand écran (le survol suffit),
   visible dans le menu replié pour indiquer qu'on peut déplier. */
.nav-contact-chevron {
  display: none;
  width: 0.45rem;
  height: 0.45rem;
  border-right: 1.6px solid currentColor;
  border-bottom: 1.6px solid currentColor;
  transform: translateY(-1px) rotate(45deg);
  transition: transform 0.3s ease;
}

/* Le volet : petit panneau net, noir et blanc, coins carrés. */
.nav-contact-volet {
  position: absolute;
  top: calc(100% + 0.85rem);
  left: 0;
  width: max-content; /* le panneau épouse la largeur des mots */
  display: flex;
  flex-direction: column;
  background: var(--papier);
  border: 1px solid var(--ligne);
  box-shadow: 0 14px 30px rgba(17, 17, 17, 0.08);
  padding: 0.4rem;
  opacity: 0;
  transform: translateY(-6px);
  pointer-events: none;
  transition: opacity 0.3s ease, transform 0.3s cubic-bezier(0.33, 1, 0.68, 1);
  z-index: 60;
}

/* Ouverture au survol (souris) ou au focus clavier - aucun clic requis. */
.nav-contact:hover .nav-contact-volet,
.nav-contact:focus-within .nav-contact-volet {
  opacity: 1;
  transform: translateY(0);
  pointer-events: auto;
}

/* Pont transparent : comble l'écart bouton↔volet pour ne pas perdre le survol. */
.nav-contact-volet::before {
  content: "";
  position: absolute;
  top: -0.85rem;
  left: 0;
  right: 0;
  height: 0.85rem;
}

.nav-contact-volet a {
  display: flex;
  align-items: center;
  padding: 0.55rem 0.75rem;
  font-size: 0.82rem; /* même taille que les mots de la navigation */
  color: var(--encre);
}

/* Courriel / LinkedIn : crochets [ ] au survol (comme la nav), ni flèche ni
   carré gris. Le mot est encapsulé dans .volet-mot pour cadrer les crochets. */
.volet-mot {
  position: relative;
}

.volet-mot::before,
.volet-mot::after {
  position: absolute;
  top: 0;
  bottom: 0;
  display: flex;
  align-items: center;
  opacity: 0;
  pointer-events: none;
  color: var(--encre);
  transition: opacity 0.2s ease, transform 0.25s cubic-bezier(0.33, 1, 0.68, 1);
}

.volet-mot::before {
  content: "[";
  right: calc(100% + 0.12em);
  transform: translateX(0.3em);
}

.volet-mot::after {
  content: "]";
  left: calc(100% + 0.12em);
  transform: translateX(-0.3em);
}

.nav-contact-volet a:hover .volet-mot::before,
.nav-contact-volet a:hover .volet-mot::after,
.nav-contact-volet a:focus-visible .volet-mot::before,
.nav-contact-volet a:focus-visible .volet-mot::after {
  opacity: 1;
  transform: translateX(0);
}

/* Sur petit écran (dans le menu déroulant), le volet se déplie sur place. */
@media (max-width: 900px) {
  .nav-contact { width: 100%; }
  .nav-contact-volet {
    position: static;
    min-width: 0;
    border: none;
    border-left: 1px solid var(--ligne);
    box-shadow: none;
    padding: 0.25rem 0 0.25rem 0.85rem;
    margin: 0.5rem 0 0 0.25rem;
    transform: none;
    opacity: 1;
    pointer-events: auto;
    display: none; /* fermé par défaut, déplié au tap */
  }
  .nav-contact-volet.ouvert { display: flex; }
  .nav-contact-volet::before { display: none; } /* pas de pont sur mobile */
  .nav-contact-volet a { padding: 0.45rem 0; }
  /* Aucun effet de survol dans le menu replié (tactile) : pas de crochets. */
  .nav-liens > a::before, .nav-liens > a::after,
  .nav-langue::before, .nav-langue::after,
  .nav-contact-bouton::before, .nav-contact-bouton::after,
  .volet-mot::before, .volet-mot::after {
    display: none;
  }
  .nav-contact-volet a:hover {
    background: none;
  }
  /* le chevron apparaît et pivote quand c'est ouvert */
  .nav-contact-chevron { display: inline-block; }
  .nav-contact-bouton[aria-expanded="true"] .nav-contact-chevron {
    transform: translateY(2px) rotate(-135deg);
  }
}

/* ----- « EN » détaché à droite de la navigation ----- */
/* Contact vit dans .nav-liens (juste après CV) ; « EN » est le dernier
   élément de .nav-inner, poussé tout au bord droit, près du coin. */
.nav-langue {
  margin-left: 6rem; /* nettement détaché du groupe de liens, vers le coin droit */
  font-size: 0.82rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  position: relative;
  /* Bouton encadré, coins carrés, qui s'inverse au survol (pas de crochets). */
  border: 1px solid var(--encre);
  border-radius: var(--rayon);
  padding: 0.45rem 0.7rem;
  overflow: hidden; /* clippe le panneau de remplissage */
  isolation: isolate; /* le ::before (z-index -1) reste derrière le seul texte */
  transition: color 0.3s ease;
}

/* « English » : pas de crochets. Au survol, un panneau noir monte du bas
   jusqu'à remplir tout le rectangle, en douceur (easing). */
.nav-langue::after {
  content: none;
}
.nav-langue::before {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  top: 0;
  bottom: 0;
  opacity: 1;
  background: var(--encre);
  transform: scaleY(0);
  transform-origin: bottom; /* le remplissage démarre par le bas */
  transition: transform 0.5s cubic-bezier(0.7, 0, 0.2, 1); /* fluide */
  z-index: -1; /* derrière le texte */
}
.nav-langue:hover,
.nav-langue:focus-visible {
  color: var(--papier);
}
.nav-langue:hover::before,
.nav-langue:focus-visible::before {
  transform: scaleY(1); /* rempli en entier */
}

/* Bouton hamburger : caché sur grand écran, affiché quand la nav se replie. */
.nav-bascule {
  display: none;
  flex-direction: column;
  justify-content: center;
  gap: 5px;
  width: 2.4rem;
  height: 2.4rem;
  margin-left: 1.25rem;
  padding: 0;
  background: none;
  border: none;
  cursor: pointer;
}

.nav-bascule span {
  display: block;
  width: 24px;
  height: 2px;
  background: var(--encre);
  transition: transform 0.3s ease, opacity 0.2s ease;
}

/* En croix quand le menu est ouvert */
.nav-bascule.ouvert span:nth-child(1) { transform: translateY(7px) rotate(45deg); }
.nav-bascule.ouvert span:nth-child(2) { opacity: 0; }
.nav-bascule.ouvert span:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }

/* ----- Navigation repliée en menu déroulant (petit écran) ----- */
/* Sous 900px, les liens passent dans un menu ouvrable par le bouton
   hamburger. EN reste visible à part (jamais dans le menu), poussé à droite
   juste avant le bouton. */
@media (max-width: 900px) {
  .nav-role { display: none; }      /* libère de la place */
  .nav-bascule { display: flex; }   /* le bouton apparaît */
  .nav-langue { margin-left: auto; } /* EN collé à droite, avant le bouton */

  .nav-liens {
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    flex-direction: column;
    align-items: flex-start;
    gap: 1.5rem;
    background: var(--papier);
    border-bottom: 1px solid var(--ligne);
    padding: 1.5rem 24px 2rem;
    box-shadow: 0 12px 24px rgba(17, 17, 17, 0.06);
    display: none; /* fermé par défaut */
  }

  .nav-liens.ouvert { display: flex; } /* ouvert via js/main.js */
  .nav-liens a,
  .nav-contact-bouton { font-size: 1.05rem; } /* Contact à la même taille que les autres liens du menu replié */
}

/* ----- 4. Hero ----- */
/* Dans le hero (flex en colonne), .conteneur a margin:0 auto qui annule
   l'étirement → il faut forcer la pleine largeur pour que le nom s'aligne
   exactement sur la nav (même padding) et la remplisse. */
.hero > .conteneur {
  width: 100%;
  align-self: stretch;
}

.hero {
  /* Le hero laisse dépasser un petit morceau de la section Projets en bas
     (le titre « Projets » et le début de la première carte) pour inviter au
     défilement. On retranche la nav + un dépassement FIXE (en rem, donc
     proportionnel au texte) pour que ce dépassement reste à peu près constant
     d'une résolution à l'autre. */
  min-height: calc(100dvh - var(--nav-h, 80px) - 11rem);
  display: flex;
  flex-direction: column;
  justify-content: flex-start; /* nom en haut */
  padding: 1.75rem 0 2rem; /* petit espace sous la nav (le dégagement des accents est géré par le padding-top em du h1) */
  text-align: left; /* nom et phrase alignés à gauche, pleine largeur */
}

.hero h1 {
  /* Nom en Manrope, graisse la plus forte (800 = ExtraBold) */
  font-family: "Manrope", sans-serif;
  font-weight: 800;
  text-transform: uppercase;
  line-height: 0.95;
  letter-spacing: 0;
  white-space: nowrap;
  width: 100%;
  /* espace haut PROPORTIONNEL à la taille : dégage les accents (é, ô) de la nav
     quelle que soit la grosseur du nom */
  padding-top: 0.22em;
  /* taille de repli avant js/main.js ; ajustée ensuite pour remplir la largeur */
  font-size: clamp(3rem, 15vw, 16rem);
}

/* --- Onglets « À propos » du hero (sous le nom) --- */
/* Barre segmentée façon Arestov : 4 cellules égales, bordures fines.
   L'astuce grille + gap de 1px sur fond gris dessine les séparations
   sans doubler les bordures, et tient toute seule en 2x2 sur mobile. */
.apropos-hero {
  /* respire davantage sous le nom (fluide : suit la hauteur d'écran) */
  margin-top: clamp(2.25rem, 4.5vh, 3.5rem);
}

.apropos-onglets {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 1px;
  /* noir, comme le contour du bouton « English » de la nav */
  background: var(--encre);       /* visible seulement dans les interstices */
  border: 1px solid var(--encre);
}

.apropos-onglet {
  /* reset du bouton natif */
  appearance: none;
  border: none;
  border-radius: var(--rayon);
  background: #fff;
  font-family: var(--police-accent);
  font-size: 0.85rem;
  letter-spacing: 0.02em;
  color: var(--encre); /* étiquettes en noir */
  padding: 0.85rem 1rem;
  cursor: pointer;
  /* même mécanique que le bouton « English » : un panneau noir (::before)
     monte du bas au survol et le texte s'inverse */
  position: relative;
  overflow: hidden;   /* clippe le panneau de remplissage */
  isolation: isolate; /* le ::before (z-index -1) reste derrière le seul texte */
  transition: color 0.3s ease;
}

.apropos-onglet::before {
  content: "";
  position: absolute;
  inset: 0;
  background: var(--encre);
  transform: scaleY(0);
  transform-origin: bottom; /* le remplissage démarre par le bas */
  transition: transform 0.5s cubic-bezier(0.7, 0, 0.2, 1); /* fluide */
  z-index: -1; /* derrière le texte */
}

/* Survol = panneau NOIR qui monte du bas et texte inversé en blanc,
   exactement comme le bouton English. */
.apropos-onglet:hover,
.apropos-onglet:focus-visible {
  color: var(--papier);
}

.apropos-onglet:hover::before,
.apropos-onglet:focus-visible::before {
  transform: scaleY(1);
}

/* Onglet SÉLECTIONNÉ : rempli de noir en permanence, mot en blanc.
   (Les crochets [ ] essayés ici ont été retirés pour l'instant ; le
   span .onglet-mot reste dans le HTML si on veut les remettre.) */
.apropos-onglet.actif {
  color: var(--papier);
}

.apropos-onglet.actif::before {
  transform: scaleY(1); /* le panneau noir reste monté */
}

.apropos-onglet:focus-visible {
  outline: 2px solid var(--encre);
  outline-offset: -2px;
}

/* Panneaux : un seul visible, apparition en fondu + légère montée */
.apropos-panneau[hidden] {
  display: none;
}

.apropos-panneau.actif {
  animation: panneau-fondu 0.45s cubic-bezier(0.33, 1, 0.68, 1);
}

/* Texte des panneaux : gros texte d'intro (près du double du corps
   normal), légèrement gras, bien détaché des onglets, sans traverser
   l'écran. Tailles et espaces fluides (clamp) pour que le hero complet
   (nom + onglets + texte le plus long) reste dans l'écran initial. */
.apropos-panneau p {
  max-width: min(1080px, 100%);
  margin: clamp(1.75rem, 3.5vh, 3rem) 0 0;
  /* 16px -> 22px, en suivant la LARGEUR (vw) et la HAUTEUR (vh) d'écran :
     le plus contraignant des deux gagne, donc les longs textes (Parcours,
     Intérêts) rapetissent aussi sur les écrans peu hauts et restent
     dans la vue initiale. */
  font-size: clamp(1rem, min(0.8rem + 0.55vw, 0.9rem + 0.9vh), 1.4rem);
  font-weight: 500;
  line-height: 1.5;
  color: var(--encre-douce);
}

/* Sur les écrans jusqu'à ~2100px (typiquement 1920), on réduit un peu les
   textes des onglets pour qu'ils prennent moins de place. Le 2K et plus
   gardent la taille ci-dessus. */
@media (min-width: 1000px) and (max-width: 2100px) {
  .apropos-panneau p {
    font-size: clamp(1rem, min(0.8rem + 0.4vw, 0.9rem + 0.9vh), 1.25rem);
  }
}

@keyframes panneau-fondu {
  from {
    opacity: 0;
    transform: translateY(10px);
  }
  to {
    opacity: 1;
    transform: none;
  }
}

@media (max-width: 640px) {
  /* petits écrans : la barre passe en 2x2 (la grille + gap gère les traits) */
  .apropos-onglets {
    grid-template-columns: repeat(2, 1fr);
  }
}

@media (prefers-reduced-motion: reduce) {
  .apropos-panneau.actif {
    animation: none;
  }
}

/* ----- 5. Section projets ----- */
.section {
  padding: clamp(3.5rem, 8vw, 6rem) 0;
}

/* La section projets remonte sous le hero : son haut est réduit pour
   que la première carte (Radio-Canada) apparaisse dès le chargement,
   juste en bas de l'écran. Limité à #projets pour ne pas toucher les
   pages d'études de cas. */
#projets {
  padding-top: clamp(1.5rem, 4vw, 2.5rem);
}

#projets .titre-section {
  margin-bottom: 1.75rem;
}

/* Pas de trait à droite des titres « Mes projets » et « À propos » de
   l'accueil (le trait reste sur les autres .titre-section, ex. pages projet). */
#projets .titre-section::after,
#a-propos .titre-section::after {
  display: none;
}

.grille-projets {
  display: grid;
  gap: 1.5rem;
}

.carte-projet {
  background: var(--carte);
  /* contour noir, comme le bouton « English » de la nav */
  border: 1px solid var(--encre);
  border-radius: var(--rayon);
  overflow: hidden; /* la photo épouse les coins arrondis */
  display: grid;
  grid-template-columns: minmax(260px, 42%) 1fr; /* photo à gauche, texte à droite */
  transition: transform 0.25s ease, box-shadow 0.25s ease, border-color 0.25s ease;
  cursor: none; /* remplacé par le curseur personnalisé « Voir » au survol */
}

.carte-projet:hover {
  /* la carte ne monte plus au survol ; on garde le contour et l'ombre */
  border-color: var(--accent);
  box-shadow: 0 12px 30px rgba(17, 17, 17, 0.08);
}

.carte-projet .vignette {
  width: 100%;
  height: 100%;
  object-fit: cover;
  border-radius: 0;
  transition: transform 0.4s ease;
}

.carte-projet:hover .vignette {
  transform: scale(1.03);
}

.carte-contenu {
  padding: 2rem;
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
  position: relative; /* ancre la flèche en haut à droite */
}

/* Flèche en haut à droite de chaque carte : pointe vers la droite,
   36px, trait de 1.5. Au survol de la carte, elle pivote de 45°
   pour filer en diagonale vers le haut à droite. */
.fleche-carte {
  position: absolute;
  top: 2rem;
  right: 2rem;
  color: var(--encre);
  line-height: 0;
  transition: transform 0.3s ease;
}

.carte-projet:hover .fleche-carte {
  transform: rotate(-45deg); /* vers le haut à droite */
}

/* Nom du projet : l'élément le plus gros de la carte */
.carte-projet .client {
  font-family: var(--police-titre);
  font-weight: 800;
  text-transform: uppercase;
  font-size: clamp(1.6rem, 3vw, 2.2rem);
  letter-spacing: 0.02em;
  line-height: 1.1;
}

/* Question : plus petite, en gris */
.carte-projet .question {
  font-size: 1.05rem;
  color: var(--encre-douce);
}

.carte-projet .tags {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin-top: 0.5rem;
}

.tag {
  font-family: var(--police-accent);
  font-size: 0.78rem;
  border: 1px solid var(--ligne);
  padding: 4px 12px;
  color: var(--encre-douce);
}

.carte-projet .duree-lecture {
  margin-top: auto; /* poussée au bas de la carte */
  padding-top: 1rem;
  font-family: var(--police-accent);
  font-size: 0.9rem;
  color: var(--encre-douce);
  display: flex;
  align-items: center;
  gap: 0.5rem; /* espace entre l'icône de livre et le texte */
}

.carte-projet .duree-lecture svg {
  flex-shrink: 0;
}

/* ============================================================
   Optimisation mobile / tablette de la page d'accueil.
   Le desktop (au-dessus de 900px) reste identique.
   ============================================================ */

/* Tablette et moins : marges latérales resserrées (le clamp desktop est trop
   large sur petit écran). */
@media (max-width: 900px) {
  .conteneur,
  .nav-inner,
  .footer-inner {
    padding-left: clamp(24px, 5vw, 48px);
    padding-right: clamp(24px, 5vw, 48px);
  }
}

/* Téléphone : cartes empilées (photo en haut) et marges encore plus serrées. */
@media (max-width: 680px) {
  .conteneur,
  .nav-inner,
  .footer-inner {
    padding-left: 20px;
    padding-right: 20px;
  }

  /* Cartes de projets : une seule colonne, la photo passe en haut. */
  .carte-projet {
    grid-template-columns: 1fr;
  }
  .carte-projet .vignette {
    height: auto;
    aspect-ratio: 16 / 10;   /* hauteur cohérente pour la photo pleine largeur */
  }
  .carte-contenu {
    padding: 1.5rem;
  }
  .fleche-carte {
    top: 1.5rem;
    right: 1.5rem;
  }
  .carte-projet .question {
    font-size: 1rem;
  }
}

/* ----- 6. À propos ----- */
.a-propos p {
  max-width: 720px;
  font-size: 1.15rem;
}

/* ----- 7. Pied de page ----- */
.footer {
  padding: 3.5rem 0 5rem; /* plus d'air sous le pied de page */
  display: grid;
  gap: 2rem;
  /* opaque et au-dessus de l'image épinglée (pages projet) : sinon la photo
     du hero repasse par-dessus le bas de page. Sans effet sur l'accueil. */
  position: relative;
  z-index: 2;
  background: var(--papier);
}

.footer h5 {
  font-family: var(--police-accent);
  text-transform: uppercase;
  font-size: 0.8rem;
  letter-spacing: 0.08em;
  color: var(--encre-douce);
  margin-bottom: 0.4rem;
}

.footer a:hover {
  color: var(--accent);
}

/* Adresse courriel du pied de page : en bleu et soulignée pour
   signaler clairement qu'il s'agit d'un lien cliquable (ouvre un
   courriel). Seule touche de couleur du site, assumée, au service
   de l'affordance du lien. Cible uniquement le lien mailto du footer
   (pas le « Contact » de la barre latérale). */
.footer a[href^="mailto:"] {
  color: #1a5fd0;
  text-decoration: underline;
  text-underline-offset: 3px;
}

.footer a[href^="mailto:"]:hover {
  color: #14409a; /* bleu plus foncé au survol */
}

.footer-inner {
  max-width: var(--largeur-max);
  margin: 0 auto;
  padding: 0 clamp(64px, 8vw, 160px);
  width: 100%;
  display: flex;
  flex-wrap: wrap;
  gap: 3rem;
  justify-content: space-between; /* premier bloc collé à gauche, dernier à droite */
  align-items: flex-start;
}

/* Le bloc de droite s'aligne sur la marge droite */
.footer-inner > div:last-child {
  text-align: right;
}

/* ----- 8. Pages projets ----- */
/* En-tête plein écran : la photo commence sous la navigation,
   prend toute la largeur (la barre noire reste à droite),
   et le titre blanc est posé sur l'image. */
.projet-hero {
  /* Épinglée : l'image reste en place pendant que le contenu défile
     par-dessus. Aucun mouvement propre de l'image. */
  position: sticky;
  top: var(--nav-h, 0px); /* épinglée juste sous la barre : aucun mouvement */
  z-index: 1;
  overflow: hidden; /* l'image qui zoome au défilement reste clippée au cadre */
}

.projet-hero img {
  width: 100%;
  /* Hauteur calée sur l'écran : l'image reste grande et immersive, mais
     on réserve ~14rem dessous (navigation + début du titre de la section
     suivante) pour que le titre apparaisse déjà en bas du viewport et
     invite à défiler. Le compromis se règle avec « 14rem » :
     l'augmenter montre plus de contenu (image plus courte), la diminuer
     agrandit l'image. Les bornes clamp évitent les extrêmes. */
  height: clamp(380px, calc(100svh - 14rem), 880px);
  object-fit: cover;
}

/* Tout le contenu sous l'image remonte par-dessus elle au défilement (l'image
   étant épinglée). Le fond blanc s'étend sur TOUTE la largeur de l'écran pour
   recouvrir l'image quel que soit le format. */
main.conteneur {
  position: relative;
  z-index: 2;
  /* L'espace au-dessus du titre fait partie du contenu (fond blanc) : il
     passe donc lui aussi par-dessus l'image au défilement. */
  padding-top: clamp(2.5rem, 6vw, 4rem);
}

main.conteneur::before {
  content: "";
  position: absolute;
  top: 0;
  bottom: 0;
  left: 50%;
  right: 50%;
  margin-left: -50vw;
  margin-right: -50vw;
  background: var(--papier);
  z-index: -1; /* derrière le texte, mais devant l'image épinglée */
}

/* Le nom du projet et sa phrase de résumé sont placés SOUS l'image
   (plus aucun texte ni voile sur la photo), juste avant le bloc
   métadonnées, alignés avec le contenu de la page. */
.projet-intro {
  margin: 0;
}

/* Nom du projet en casse normale (« Rémi », « Radio-Canada »…), avec la
   phrase de résumé en sous-titre dessous. */
.projet-titre {
  font-size: clamp(2.2rem, 6vw, 4rem);
  font-weight: 800; /* graisse maximale de Manrope, titre plus appuyé */
  color: var(--encre);
  margin: 0;
  max-width: 20ch;
  line-height: 1.15;
  text-transform: uppercase; /* titre du projet tout en majuscules (le sous-titre, lui, reste tel quel) */
}

.projet-sous-titre {
  margin: 0.75rem 0 0;
  max-width: 40ch;
  color: var(--encre-douce);
  font-size: clamp(1.1rem, 2.4vw, 1.6rem);
  font-weight: 500;
  line-height: 1.35;
}

/* Apparition du contenu d'arrivée : il monte et apparaît en fondu, dans la
   continuité du rideau qui se lève. Joué une fois au chargement, avec un
   léger décalage pour émerger pendant que le rideau quitte l'écran. */
@keyframes apparition-montee {
  from { opacity: 0; transform: translateY(64px); }
  to   { opacity: 1; transform: translateY(0); }
}

/* L'image d'en-tête reste fixe : c'est le contenu (titre, sous-titre puis
   métadonnées) qui monte en fondu, dans la continuité du rideau qui se lève. */
.projet-intro {
  animation: apparition-montee 0.85s cubic-bezier(0.33, 1, 0.68, 1) 0.5s both;
}

.meta-grille {
  animation: apparition-montee 0.85s cubic-bezier(0.33, 1, 0.68, 1) 0.62s both;
}

/* Page d'accueil : le nom et les onglets montent en fondu au chargement,
   synchronisés avec le rideau (premier accès comme retour à l'accueil). */
.hero h1 {
  animation: apparition-montee 0.9s cubic-bezier(0.33, 1, 0.68, 1) 0.6s backwards;
}

/* Les onglets « À propos » montent juste après le nom */
.apropos-hero {
  animation: apparition-montee 0.6s cubic-bezier(0.33, 1, 0.68, 1) 0.68s backwards;
}

/* Le titre « Mes projets » monte avec le hero (il depasse deja en bas
   du viewport au chargement), juste apres la phrase de description. */
#projets .titre-section {
  animation: apparition-montee 0.9s cubic-bezier(0.33, 1, 0.68, 1) 0.9s both;
}

/* Les trois cartes montent en cascade juste apres le titre, dans le meme
   mouvement que le rideau. Fill "backwards" : l'etat de depart (cache, decale)
   s'applique pendant le delai, mais on revient aux styles normaux a la fin
   pour ne pas bloquer le translateY du survol. */
.grille-projets .carte-projet {
  animation: apparition-montee 0.9s cubic-bezier(0.33, 1, 0.68, 1) backwards;
}
.grille-projets .carte-projet:nth-child(1) { animation-delay: 1s; }
.grille-projets .carte-projet:nth-child(2) { animation-delay: 1.12s; }
.grille-projets .carte-projet:nth-child(3) { animation-delay: 1.24s; }

@media (prefers-reduced-motion: reduce) {
  .projet-intro,
  .meta-grille,
  .hero h1,
  .apropos-hero,
  #projets .titre-section,
  .grille-projets .carte-projet {
    animation: none;
  }
}

.meta-grille {
  margin-top: 3rem;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
  gap: 1.5rem;
  padding: 2rem 0;
  border-top: 1px solid var(--ligne);
  border-bottom: 1px solid var(--ligne);
  margin-bottom: 3rem;
}

.meta-grille h4 {
  font-family: var(--police-accent);
  text-transform: uppercase;
  font-size: 0.78rem;
  letter-spacing: 0.08em;
  color: var(--accent);
  margin-bottom: 0.4rem;
}

.meta-grille p {
  font-size: 0.95rem;
  color: var(--encre-douce);
}

.bloc {
  margin-bottom: 3.5rem;
  /* l'ancre s'arrête sous la navigation collante */
  scroll-margin-top: 110px;
}

/* ----- Sommaire collant des pages projets ----- */
/* Colonne de raccourcis à gauche, contenu à droite */
.corps-projet {
  display: grid;
  grid-template-columns: 210px minmax(0, 1fr);
  gap: 3.5rem;
  align-items: start;
}

.sommaire {
  position: sticky;
  top: 110px; /* reste visible sous la navigation pendant le défilement */
  display: flex;
  flex-direction: column;
  gap: 0.7rem;
  font-family: var(--police-accent);
  font-size: 0.8rem;
}

.sommaire a {
  color: var(--encre-douce);
  transition: color 0.2s ease;
}

.sommaire a:hover {
  color: var(--encre);
}

/* Section actuellement visible */
.sommaire a.actif {
  color: var(--encre);
  font-weight: 600;
}

@media (max-width: 1000px) {
  /* Pas de place pour le sommaire sur petit écran */
  .corps-projet {
    grid-template-columns: 1fr;
  }

  .sommaire {
    display: none;
  }
}

.bloc h2 {
  font-size: clamp(1.4rem, 3vw, 2rem);
  margin-bottom: 1.25rem;
  display: flex;
  align-items: center; /* numéro centré verticalement avec le titre */
  gap: 1.5rem;
}

/* Numérotation automatique des grandes étapes : (01), (02)…
   Le compteur repart à zéro sur chaque page (reset sur <main>). */
main {
  counter-reset: etape;
}

.bloc h2::before {
  counter-increment: etape;
  content: "(" counter(etape, decimal-leading-zero) ")";
  font-family: var(--police-accent);
  font-size: 0.95rem;
  font-weight: 600; /* légèrement plus gras */
  color: var(--encre-douce);
  flex: 0 0 2.4rem; /* largeur fixe : le titre commence toujours au même endroit */
}

/* Le contenu des sections s'aligne avec le titre (après le numéro) :
   2.4rem de numéro + 1.5rem d'espacement = 3.9rem.
   Le retrait est porté par la section elle-même (padding), donc
   images et grilles partagent exactement les mêmes limites gauche
   et droite, à toutes les tailles d'écran. Seul le titre ressort
   à gauche pour que son numéro reste dans la marge. */
.bloc {
  padding-left: 3.9rem;
}

.bloc > h2 {
  margin-left: -3.9rem;
}

.bloc h3 {
  font-size: 1.1rem;
  margin-bottom: 0.5rem;
}

.bloc p + p {
  margin-top: 1rem;
}

/* Confort de lecture : le texte courant ne s'étire jamais sur toute
   la largeur (~60 % de la page au maximum, et s'adapte aux petits écrans) */
.bloc p,
.bloc ul {
  max-width: 70ch;
}

.bloc ul {
  padding-left: 1.25rem;
}

.bloc li + li {
  margin-top: 0.5rem;
}

.grille-cartes {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: 1.25rem;
}

/* ----- Accordéon des méthodes de recherche -----
   Chaque méthode : titre + chevron, séparées par des lignes ; clic pour
   dérouler le texte. <details> natif (accessible, fonctionne sans JS). */
.methodes-accordeon {
  margin-top: 2rem;
  border-top: 1px solid var(--ligne);
}

.methode {
  border-bottom: 1px solid var(--ligne);
}

.methode summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1.5rem;
  padding: 1.4rem 0;
  cursor: pointer;
  list-style: none; /* retire le triangle par défaut */
}

.methode summary::-webkit-details-marker {
  display: none; /* idem sur Safari/Chrome */
}

.methode-titre {
  font-size: clamp(1.1rem, 2.2vw, 1.4rem);
  font-weight: 600;
  color: var(--encre);
}

.methode-chevron {
  flex: 0 0 auto;
  line-height: 0;
  color: var(--encre);
  transition: transform 0.3s ease;
}

.methode[open] .methode-chevron {
  transform: rotate(180deg); /* le chevron pointe vers le haut une fois ouvert */
}

.methode-corps {
  padding: 0 0 1.4rem;
  max-width: 62ch;
}

.methode-corps p {
  margin: 0;
  color: var(--encre-douce);
}

/* Apparition douce du texte à l'ouverture */
.methode[open] .methode-corps {
  animation: methode-ouvre 0.3s ease;
}

@keyframes methode-ouvre {
  from { opacity: 0; transform: translateY(-6px); }
  to   { opacity: 1; transform: translateY(0); }
}

@media (prefers-reduced-motion: reduce) {
  .methode-chevron { transition: none; }
  .methode[open] .methode-corps { animation: none; }
}

/* Variante : exactement 3 colonnes (ex. : 6 cartes = 2 rangées de 3) */
.grille-cartes.trois-colonnes {
  grid-template-columns: repeat(3, 1fr);
}

@media (max-width: 900px) {
  .grille-cartes.trois-colonnes {
    grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  }
}

.mini-carte {
  background: var(--carte);
  border: 1px solid var(--ligne);
  border-radius: var(--rayon);
  padding: 1.5rem;
  /* ombre très discrète, juste assez pour décoller du fond */
  box-shadow: 0 1px 3px rgba(17, 17, 17, 0.04), 0 4px 14px rgba(17, 17, 17, 0.05);
}

.mini-carte .numero {
  font-family: var(--police-accent);
  font-size: 2rem;
  color: var(--accent);
  line-height: 1;
  margin-bottom: 0.75rem;
}

/* Statistiques : même style que les mini-cartes,
   fond blanc et contour gris très pâle */
.stat {
  background: var(--carte);
  border: 1px solid var(--ligne);
  border-radius: var(--rayon);
  padding: 1.5rem;
  /* même ombre discrète que les mini-cartes */
  box-shadow: 0 1px 3px rgba(17, 17, 17, 0.04), 0 4px 14px rgba(17, 17, 17, 0.05);
}

.stat .chiffre {
  font-family: var(--police-accent);
  font-weight: 600;
  font-size: 2.4rem;
}

.stat p {
  font-size: 0.9rem;
  margin-top: 0.5rem;
  color: var(--encre-douce);
}

.grille-images {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 1.25rem;
}

/* Vidéos empilées : pleine largeur, l'une au-dessus de l'autre */
.videos-empilees {
  display: grid;
  grid-template-columns: 1fr;
  gap: 1.25rem;
}

.videos-empilees video {
  width: 100%;
}

.bloc img + img,
.bloc figure + figure {
  margin-top: 1.25rem;
}

/* …mais pas dans les grilles d'images, où l'espacement
   est déjà géré par la grille (sinon la 2e image se décale) */
.grille-images img + img,
.mosaique img + img,
.grille-telephones img + img {
  margin-top: 0;
}

/* Mosaïque de 5 photos sans espaces vides :
   la 1re photo (portrait) occupe 2 rangées à gauche,
   les 4 autres remplissent une grille 2×2 à droite.
   object-fit: cover recadre chaque photo pour remplir sa case. */
.mosaique {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-template-rows: repeat(2, clamp(220px, 24vw, 330px));
  gap: 1.25rem;
}

.mosaique img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.mosaique img:first-child {
  grid-row: span 2; /* la grande photo verticale à gauche */
}

@media (max-width: 720px) {
  /* Sur mobile : 2 colonnes, la grande photo reste sur 2 rangées */
  .mosaique {
    grid-template-columns: repeat(2, 1fr);
    grid-template-rows: repeat(3, 180px);
  }
}

.note {
  font-size: 0.9rem;
  color: var(--encre-douce);
}

/* ----- Comparaison Avant / Après (recommandations) -----
   Deux maquettes côte à côte, annotation en vrai texte à droite,
   reliée par une ligne à l'élément pointé sur la maquette.
   Le bloc est aligné sur la marge droite du contenu. */
.comparaison {
  display: grid;
  grid-template-columns: 1fr 1fr 1.3fr;
  gap: 2rem;
  align-items: start;
  max-width: 920px;   /* maquettes de taille intermédiaire */
  margin-left: auto;   /* bloc centré dans la page */
  margin-right: auto;
  margin-top: 2.5rem;
}

.comparaison figure {
  margin: 0;
}

/* annule l'espacement des figures empilées : ici elles sont côte à côte */
.comparaison figure + figure {
  margin-top: 0;
}

.comparaison figcaption {
  font-family: var(--police-accent);
  font-size: 0.85rem;
  margin-bottom: 1rem;
}

.comparaison img {
  width: 100%;
}

.comparaison .annotation {
  position: relative;
}

/* La ligne de liaison : point côté téléphone, flèche côté texte.
   Sa position verticale est calculée en % de la largeur de colonne,
   donc elle reste calée sur la bulle blanche quand l'écran change.
   Le texte qui suit occupe sa vraie place : pas de chevauchement
   avec la section suivante. */
.comparaison .annotation .ligne {
  display: block;
  position: relative;
  margin-top: calc(96.9% + 33px); /* hauteur de la bulle blanche */
  margin-left: -2rem;             /* part du bord du téléphone */
  width: clamp(3rem, 9vw, 7rem);  /* la ligne raccourcit avec l'écran */
  height: 1px;
  background: var(--encre);
}

/* Le point, côté téléphone */
.comparaison .annotation .ligne::before {
  content: "";
  position: absolute;
  left: -3px;
  top: 50%;
  transform: translateY(-50%);
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--encre);
}

/* La flèche, vers le titre */
.comparaison .annotation .ligne::after {
  content: "";
  position: absolute;
  right: 0;
  top: 50%;
  width: 7px;
  height: 7px;
  border-top: 1px solid var(--encre);
  border-right: 1px solid var(--encre);
  transform: translateY(-50%) rotate(45deg);
  transform-origin: center;
}

/* Le texte commence après la flèche, première ligne du titre
   centrée sur la ligne de liaison */
.comparaison .annotation .texte {
  margin-left: calc(clamp(3rem, 9vw, 7rem) - 1rem);
  transform: translateY(-0.7em);
}

.comparaison .annotation h4 {
  font-family: var(--police-titre);
  font-size: 1.05rem;
  margin-bottom: 0.5rem;
}

.comparaison .annotation p {
  font-size: 0.95rem;
  color: var(--encre-douce);
}

@media (max-width: 720px) {
  /* Sur mobile : les deux téléphones côte à côte, l'annotation dessous */
  .comparaison {
    grid-template-columns: 1fr 1fr;
    gap: 1.5rem;
  }

  .comparaison .annotation {
    grid-column: 1 / -1;
    height: auto;
  }

  .comparaison .annotation .ligne {
    display: none;
  }

  .comparaison .annotation .texte {
    margin-left: 0;
    transform: none;
  }
}

/* ----- Parcours utilisateurs : texte codé à gauche, schéma à droite ----- */
.parcours {
  display: grid;
  /* schéma limité à 500px : toute la section tient à l'écran */
  grid-template-columns: minmax(300px, 1fr) minmax(0, 500px);
  gap: 3rem;
  /* les deux colonnes ont la même hauteur : les constats,
     poussés en bas, s'alignent avec le bas du schéma */
  align-items: stretch;
}

/* Bon espace entre les parcours successifs */
.parcours + .parcours {
  margin-top: 11rem;
}

/* Variante pour les schémas horizontaux (parcours 2 et 3) :
   le schéma prend environ la moitié de l'écran */
.parcours-large {
  grid-template-columns: minmax(260px, 1fr) minmax(0, 800px);
}

.parcours-texte {
  display: flex;
  flex-direction: column;
  height: 100%; /* permet de pousser les constats vers le bas */
}

.parcours-texte .surtitre {
  font-family: var(--police-accent);
  font-size: 0.85rem;
  color: var(--encre-douce);
  margin-bottom: 0.5rem;
}

.parcours-texte h3 {
  font-size: 1.5rem;
  margin-bottom: 0.75rem;
}

.parcours-constats {
  margin-top: auto; /* collé au bas de la colonne, comme sur la maquette */
  padding-top: 2rem;
}

.parcours-constats h4 {
  font-family: var(--police-titre);
  font-size: 1rem;
  margin-bottom: 1rem;
}

/* Liste numérotée : pastilles noires, chiffres blancs */
.parcours-constats ol {
  list-style: none;
  padding: 0;
  counter-reset: constat;
}

.parcours-constats li {
  counter-increment: constat;
  display: flex;
  gap: 0.85rem;
  align-items: flex-start;
  font-size: 0.95rem;
  max-width: 60ch;
}

.parcours-constats li + li {
  margin-top: 0.85rem;
}

.parcours-constats li::before {
  content: counter(constat);
  flex: 0 0 22px;
  height: 22px;
  border-radius: 50%;
  background: #e45a4b; /* même rouge que les points du schéma */
  color: #ffffff;
  font-family: var(--police-accent);
  font-size: 0.75rem;
  display: grid;
  place-items: center;
  margin-top: 0.1em;
}

.parcours img {
  width: 100%;
  align-self: start; /* l'image garde ses proportions, alignée en haut */
}

@media (max-width: 900px) {
  /* Sur écran étroit : texte au-dessus, schéma dessous */
  .parcours {
    grid-template-columns: 1fr;
    gap: 2rem;
  }

  .parcours-texte {
    height: auto;
  }

  .parcours-constats {
    margin-top: 1.5rem;
  }
}

/* Sous-sections de recommandations : espacement identique
   entre chacune, peu importe le contenu qui précède */
.titre-reco {
  margin-top: 5.5rem;
}

/* ----- Comparaisons annotées (Connexion, Indicateurs, Mode audio) -----
   Maquettes en colonnes + annotations ancrées en hauteur (--pos, en %
   de la hauteur des téléphones). La ligne touche la maquette d'un côté
   et pointe le texte de l'autre ; elle raccourcit avec l'écran. */
.comparaison-annotee {
  display: grid;
  gap: 2rem;
  align-items: start;
  margin-top: 2rem;
  /* Largeur unique des maquettes, partagée par .trois-col et .quatre-col
     pour que chaque section affiche la même grandeur de téléphone.
     S'adapte à l'écran via clamp. */
  --maquette: clamp(140px, 16vw, 210px);
  /* Hauteur du téléphone, déduite de sa largeur (ratio des maquettes
     = largeur / hauteur = 0.483). Sert à ancrer les annotations sur la
     hauteur réelle du téléphone : elles le suivent quoi qu'il arrive. */
  --maquette-h: calc(var(--maquette) / 0.483);
}

.trois-col {
  grid-template-columns: var(--maquette) var(--maquette) 1.25fr;
  max-width: 980px;
  margin-left: 0; /* aligné à gauche, au même bord que le titre et le texte */
  margin-right: auto;
}

/* Variante avec textes annotés des deux côtés de la maquette Après */
.quatre-col {
  grid-template-columns: var(--maquette) 1.05fr var(--maquette) 1.2fr;
  max-width: 1150px;
  margin-left: 0; /* aligné à gauche, au même bord que le titre et le texte */
  margin-right: auto;
}

/* Variante à trois maquettes (barres de navigation) : « Avant » + deux
   « Recommandation » côte à côte, annotations à droite de la 3e maquette. */
.trois-maquettes {
  grid-template-columns: repeat(3, var(--maquette)) 1fr;
  margin-left: 0; /* aligné à gauche, comme le titre et le texte */
  margin-right: auto;
}

/* Une maquette centrée avec des annotations des DEUX côtés (Safeway,
   solution finale) : colonne texte à gauche, maquette au centre, colonne
   texte à droite. */
.solo-deux-cotes {
  grid-template-columns: 1fr var(--maquette) 1fr;
  align-items: start;
  margin-block: clamp(3.5rem, 8vw, 6rem); /* bon espace entre chaque bloc maquette + texte */
}

/* Sous-titres de groupe dans « Solution finale » (Navigation, Prévention) :
   bien détachés du contenu précédent, mais proches de leur 1re maquette. */
.titre-groupe {
  margin: clamp(3rem, 7vw, 5rem) 0 0.75rem;
  font-size: 1.1rem; /* même grosseur que les titres de recommandation (Radio-Canada) */
}
.intro-groupe {
  max-width: 65ch;
  margin: 0 0 clamp(1.75rem, 3.5vw, 2.75rem);
  color: var(--encre-douce);
}
.intro-groupe + .solo-deux-cotes {
  margin-top: 0; /* la 1re maquette reste proche de son texte d'intro */
}

/* Annotation détachée du flux (.ancre-bas) : son point se fixe à une
   hauteur donnée de la maquette (--pos × hauteur du téléphone) au lieu
   d'être empilée. Résultat : elle ne bouge plus, même si le texte d'une
   autre annotation au-dessus s'allonge sur plusieurs lignes. */
.annotation-point.ancre-bas {
  position: absolute;
  left: 0;
  right: 0;
  top: calc(var(--pos, 0) * var(--maquette-h));
}

/* Flèche en coude : part du titre, descend le long de la maquette
   et pointe sa cible plus bas. Sa hauteur suit les proportions de
   la maquette grâce à aspect-ratio (--ar = largeur / descente). */
.annotation-point .coude {
  position: relative;
  flex: 0 0 22%; /* segment horizontal plus court */
  aspect-ratio: var(--ar, 1);
  margin-top: 0.8em;
  border-top: 1px solid var(--encre);
}

.annotation-point.miroir .coude {
  border-right: 1px solid var(--encre);
  /* la descente reste décollée du téléphone, dans l'espacement,
     pour qu'on voie bien qu'elle longe la maquette */
  margin-right: -0.75rem;
}

/* Flèches droites plus courtes du côté gauche */
.quatre-col .miroir .ligne {
  flex-basis: clamp(1.2rem, 2vw, 2rem);
}

/* Bas de la descente : second angle droit, segment horizontal continu
   qui rejoint le téléphone */
.annotation-point.miroir .coude::before {
  content: "";
  position: absolute;
  right: -1.25rem;
  bottom: -1px;
  width: 1.25rem;
  height: 1px;
  background: var(--encre);
}

/* Le point, collé à la maquette comme ceux des autres annotations */
.annotation-point.miroir .coude .pied {
  position: absolute;
  right: calc(-1.25rem - 3px);
  bottom: -4px;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--encre);
}

/* Flèche vers le titre, à l'extrémité du segment horizontal */
.annotation-point.miroir .coude::after {
  content: "";
  position: absolute;
  left: 0;
  top: -4px;
  width: 7px;
  height: 7px;
  border-top: 1px solid var(--encre);
  border-right: 1px solid var(--encre);
  transform: rotate(-135deg);
}

/* Coude côté DROIT (texte à droite, maquette à gauche) : la descente est
   sur le bord gauche du coude, le point en bas à gauche contre la maquette,
   la flèche pointe le titre à droite. Permet de remonter le texte tout en
   gardant le point collé à la maquette plus bas (--ar = largeur / descente). */
.annotation-point:not(.miroir) .coude {
  flex: 0 0 clamp(1.8rem, 4vw, 4rem); /* même largeur que .ligne → texte aligné à gauche */
  aspect-ratio: auto;
  height: var(--descente, 7rem);      /* longueur de la descente jusqu'au point */
  border-left: 1px solid var(--encre);
  margin-left: -0.75rem;
}

.annotation-point:not(.miroir) .coude::before {
  content: "";
  position: absolute;
  left: -1.25rem;
  bottom: -1px;
  width: 1.25rem;
  height: 1px;
  background: var(--encre);
}

.annotation-point:not(.miroir) .coude .pied {
  position: absolute;
  left: calc(-1.25rem - 3px);
  bottom: -4px;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--encre);
}

.annotation-point:not(.miroir) .coude::after {
  content: "";
  position: absolute;
  right: 0;
  top: -4px;
  width: 7px;
  height: 7px;
  border-top: 1px solid var(--encre);
  border-right: 1px solid var(--encre);
  transform: rotate(45deg);
}

/* Points d'annotation : un simple rond collé à la maquette,
   sans ligne ni flèche */
.annotation-point.numerote {
  align-items: center;
}

.annotation-point.numerote .point-survol {
  margin-left: -1rem; /* rapproché de la maquette (colonne de droite) */
}

.annotation-point.numerote.miroir .point-survol {
  margin-left: 0;
  margin-right: -1rem; /* rapproché de la maquette (colonne de gauche) */
}

.pastille {
  flex: 0 0 22px;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  background: var(--encre);
  color: var(--papier);
  font-family: var(--police-accent);
  font-size: 0.75rem;
  display: grid;
  place-items: center;
}

/* Point survolable sur la maquette : un simple indicateur rond
   qui, au survol, met en évidence sa description dans la légende */
.point-survol {
  flex: 0 0 22px;
  width: 22px;
  height: 22px;
  border: none;
  background: none;
  padding: 0;
  cursor: pointer;
  position: relative;
}

.point-survol::before {
  content: "";
  position: absolute;
  top: 50%;
  left: 50%;
  width: 9px;
  height: 9px;
  transform: translate(-50%, -50%);
  border-radius: 50%;
  background: var(--encre);
  transition: transform 0.2s ease;
}

.point-survol:hover::before,
.point-survol:focus-visible::before,
.point-survol.surligne::before {
  transform: translate(-50%, -50%) scale(1.7);
}

/* Pendant un survol, la légende estompe tout sauf l'élément visé */
.legende-annotations .item {
  transition: opacity 0.2s ease;
}

.legende-annotations.survol-actif .item {
  opacity: 0.25;
}

.legende-annotations.survol-actif .item.surligne {
  opacity: 1;
}

.legende-annotations .item.surligne p {
  color: var(--encre);
}

/* Légende sous la comparaison : textes des pastilles */
.legende-annotations {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 1.75rem 2.5rem;
  margin: 2.5rem auto 0;
  max-width: 980px;
}

.legende-annotations .item {
  display: flex;
  gap: 0.85rem;
  align-items: flex-start;
}

/* Indique que les items de légende sont survolables */
.legende-annotations .item {
  cursor: pointer;
}

.legende-annotations .item .pastille {
  margin-top: 0.1em;
}

.legende-annotations h4 {
  font-family: var(--police-titre);
  font-size: 1rem;
  margin-bottom: 0.3rem;
}

.legende-annotations p {
  font-size: 0.9rem;
  color: var(--encre-douce);
}

.comparaison-annotee figure,
.comparaison-annotee figure + figure {
  margin: 0;
}

.comparaison-annotee figcaption {
  font-family: var(--police-accent);
  font-size: 0.85rem;
  margin-bottom: 1rem;
}

.comparaison-annotee img {
  width: 100%;
}

/* Colonne d'annotations : même hauteur que la rangée,
   pour que les % d'ancrage suivent la hauteur des téléphones */
.col-annotations {
  position: relative;
  align-self: stretch;
}

/* Les annotations restent dans le flux normal (pas d'absolu) :
   elles occupent leur vraie hauteur, donc le contenu suivant ne
   peut jamais être recouvert. L'ancrage vertical suit la HAUTEUR du
   téléphone : --pos est une fraction (0 = haut du téléphone, 1 = bas),
   multipliée par --maquette-h. Ainsi l'annotation suit la maquette,
   qu'elle rapetisse ou grossisse. --ajust = petit décalage fin en px
   ou em ; --marge-min = marge minimale (pour les annotations empilées). */
.annotation-point {
  display: flex;
  align-items: flex-start;
  gap: 1rem;
  margin-top: max(var(--marge-min, 0px), calc(var(--pos, 0) * var(--maquette-h) + var(--ajust, 0px)));
}

.annotation-point .ligne {
  position: relative;
  flex: 0 0 clamp(1.8rem, 4vw, 4rem); /* raccourcit avec l'écran */
  height: 1px;
  background: var(--encre);
  margin-top: 0.8em; /* centrée sur la première ligne du titre */
  margin-left: -2rem; /* touche la maquette */
}

/* Point côté maquette */
.annotation-point .ligne::before {
  content: "";
  position: absolute;
  left: -3px;
  top: 50%;
  transform: translateY(-50%);
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--encre);
}

/* Flèche côté texte */
.annotation-point .ligne::after {
  content: "";
  position: absolute;
  right: 0;
  top: 50%;
  width: 7px;
  height: 7px;
  border-top: 1px solid var(--encre);
  border-right: 1px solid var(--encre);
  transform: translateY(-50%) rotate(45deg);
}

/* Version miroir : texte à gauche de la maquette,
   le point est à droite (sur la maquette) et la flèche à gauche */
.annotation-point.miroir {
  flex-direction: row-reverse;
}

.annotation-point.miroir .ligne {
  margin-left: 0;
  margin-right: -2rem;
}

.annotation-point.miroir .ligne::before {
  left: auto;
  right: -3px;
}

.annotation-point.miroir .ligne::after {
  right: auto;
  left: 0;
  transform: translateY(-50%) rotate(-135deg);
}

.annotation-point .texte {
  transform: none; /* le titre reste à sa place naturelle,
                      la ligne vient se centrer sur lui */
}

.annotation-point h4 {
  font-family: var(--police-titre);
  font-size: 1rem;
  margin-bottom: 0.4rem;
}

.annotation-point p {
  font-size: clamp(0.78rem, 1vw, 0.9rem);
  color: var(--encre-douce);
}

@media (max-width: 920px) {
  /* Maquettes côte à côte, annotations empilées dessous */
  .trois-col,
  .quatre-col {
    grid-template-columns: 1fr 1fr;
    max-width: none;
  }

  /* Les pastilles ancrées disparaissent : la légende suffit */
  .annotation-point.numerote {
    display: none;
  }

  .legende-annotations {
    grid-template-columns: 1fr;
    gap: 1.25rem;
  }

  .col-annotations {
    position: static;
    align-self: auto;
    grid-column: 1 / -1;
  }

  .annotation-point {
    position: static;
    margin-top: 1.5rem;
  }

  .annotation-point .ligne,
  .annotation-point .coude {
    display: none;
  }

  .annotation-point .texte {
    transform: none;
  }

  .annotation-point p {
    font-size: 0.9rem;
  }
}

/* La section « Ajout d'indicateurs » (.quatre-col) a du texte des DEUX
   côtés de la maquette : il se condense beaucoup plus vite que les
   sections à un seul côté. Elle bascule donc plus tôt (dès 1200px) en
   format empilé : les deux maquettes côte à côte sur une rangée, puis
   tout le texte en dessous, pleine largeur, pour qu'il reste lisible. */
@media (max-width: 1400px) {
  .quatre-col {
    /* maquettes à la MÊME taille que dans les autres sections (--maquette),
       côte à côte ; la 3e colonne (1fr) absorbe l'espace restant pour que
       le texte en dessous prenne quand même toute la largeur. */
    grid-template-columns: var(--maquette) var(--maquette) 1fr;
    max-width: none;
    /* on annule l'écart vertical de la grille : tout l'espacement entre
       les textes vient alors de la seule marge des annotations (1,5rem),
       donc les quatre paragraphes sont espacés exactement pareil. */
    row-gap: 0;
  }

  /* les deux maquettes occupent la première rangée, côte à côte */
  .quatre-col > figure:nth-of-type(1) { grid-column: 1; grid-row: 1; }
  .quatre-col > figure:nth-of-type(2) { grid-column: 2; grid-row: 1; }

  /* les colonnes de texte passent pleine largeur, empilées sous les maquettes */
  .quatre-col .col-annotations {
    position: static;
    align-self: auto;
    grid-column: 1 / -1;
  }

  .quatre-col .annotation-point {
    position: static;
    margin-top: 1.5rem;
  }

  /* En empilé, les annotations « miroir » (texte à gauche de la maquette
     en grand écran, donc en sens inversé) repassent en sens normal pour
     être alignées à gauche, au même bord que les maquettes et les autres
     textes. */
  .quatre-col .annotation-point.miroir {
    flex-direction: row;
  }

  /* plus de flèches ni de coudes en format empilé : le texte se suffit */
  .quatre-col .annotation-point .ligne,
  .quatre-col .annotation-point .coude {
    display: none;
  }

  .quatre-col .annotation-point .texte {
    transform: none;
  }

  .quatre-col .annotation-point p {
    font-size: 0.9rem;
  }
}

/* En dessous de 920px (tablette/téléphone), la section indicateurs rejoint
   le comportement des autres sections : maquettes en demi-largeur. */
@media (max-width: 920px) {
  .quatre-col {
    grid-template-columns: 1fr 1fr;
  }
}

/* La section « Ajustement des barres de navigation » (.trois-maquettes)
   bascule en empilé sous 1280px : les trois maquettes restent côte à côte
   (et rétrécissent pour tenir grâce à minmax), le texte passe pleine
   largeur en dessous. */
@media (max-width: 1280px) {
  .trois-maquettes {
    grid-template-columns: repeat(3, minmax(0, var(--maquette)));
  }
  .trois-maquettes > figure:nth-of-type(1) { grid-column: 1; grid-row: 1; }
  .trois-maquettes > figure:nth-of-type(2) { grid-column: 2; grid-row: 1; }
  .trois-maquettes > figure:nth-of-type(3) { grid-column: 3; grid-row: 1; }

  .trois-maquettes .col-annotations {
    position: static;
    align-self: auto;
    grid-column: 1 / -1;
  }

  .trois-maquettes .annotation-point {
    position: static;
    margin-top: 1.5rem;
  }

  /* en empilé, l'annotation détachée revient dans le flux normal */
  .trois-maquettes .annotation-point.ancre-bas {
    position: static;
    top: auto;
  }

  .trois-maquettes .annotation-point .ligne,
  .trois-maquettes .annotation-point .coude {
    display: none;
  }

  .trois-maquettes .annotation-point .texte {
    transform: none;
  }

  .trois-maquettes .annotation-point p {
    font-size: 0.9rem;
  }
}

/* La maquette-explication (.solo-deux-cotes) bascule en empilé dès 1400px :
   la maquette en haut, puis les textes pleine largeur dessous. Ça évite que
   les annotations latérales se décalent entre elles quand l'écran rétrécit. */
@media (max-width: 1400px) {
  .solo-deux-cotes {
    grid-template-columns: 1fr;
    row-gap: 0; /* espacement uniforme : il ne vient que des marges des textes */
    counter-reset: point-annot; /* numérotation des annotations, par maquette */
  }

  /* En empilé, chaque annotation est numérotée (1, 2, 3…) pour distinguer
     la hiérarchie maintenant que les flèches ont disparu. */
  .solo-deux-cotes .annotation-point {
    counter-increment: point-annot;
  }
  .solo-deux-cotes .annotation-point h4::before {
    content: counter(point-annot) ". ";
    font-family: var(--police-accent);
    color: var(--encre-douce);
  }

  .solo-deux-cotes > figure {
    order: -1; /* la maquette passe en premier */
    width: var(--maquette);
    max-width: 100%;
    justify-self: start; /* maquette alignée à gauche */
  }
  .solo-deux-cotes .col-annotations {
    position: static;
    align-self: auto;
  }
  .solo-deux-cotes .annotation-point {
    position: static;
    margin-top: 1.5rem;
  }
  .solo-deux-cotes .annotation-point.miroir {
    flex-direction: row; /* aligné à gauche comme les autres en empilé */
  }
  .solo-deux-cotes .annotation-point .ligne,
  .solo-deux-cotes .annotation-point .coude {
    display: none;
  }
  .solo-deux-cotes .annotation-point .texte {
    transform: none;
  }
  .solo-deux-cotes .annotation-point p {
    font-size: 0.9rem;
  }
}

/* ----- Linktrees : exemples actuels + template annoté ----- */
.linktree-exemples {
  margin: 2rem 0 0;
}

.linktree-exemples figcaption {
  font-family: var(--police-accent);
  font-size: 0.85rem;
  margin-bottom: 1rem;
}

.grille-telephones {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 1.5rem;
}

.grille-telephones img {
  width: 100%;
}

/* Template annoté : téléphone à gauche, annotations à droite,
   chacune calée en hauteur (--pos) sur la section qu'elle décrit.
   Les positions sont en % de la hauteur du téléphone : elles
   restent alignées à toutes les tailles d'écran. */
.schema-annote {
  display: grid;
  /* le téléphone peut rétrécir jusqu'à 180px, la colonne de texte
     peut se compresser (minmax(0, 1fr)) sans déborder */
  grid-template-columns: minmax(180px, 320px) minmax(0, 1fr);
  gap: 2.5rem;
  margin-top: 3rem;
  /* aligné à gauche, comme le texte et les autres maquettes */
  max-width: 860px;
  margin-left: 0;
  margin-right: auto;
}

.schema-annote .schema-image {
  width: 100%;
  align-self: start;
}

.schema-annotations {
  position: relative;
}

/* L'annotation occupe exactement la hauteur de sa zone (--debut à --fin) */
.annotation-flottante {
  position: absolute;
  top: var(--debut);
  height: calc(var(--fin) - var(--debut));
  left: 0;
  right: 0;
  display: flex;
  align-items: center; /* texte centré sur la hauteur du bracket */
  gap: 2rem;
}

/* Le bracket : embrasse verticalement la zone décrite,
   ouvert vers le téléphone */
.annotation-flottante .bracket {
  flex: 0 0 10px;
  align-self: stretch;
  border: 1px solid var(--encre);
  border-left: none;
}

/* La flèche part du bracket et pointe vers le titre */
.annotation-flottante h4 {
  font-family: var(--police-titre);
  font-size: 1rem;
  margin-bottom: 0.4rem;
  display: flex;
  align-items: center;
}

.annotation-flottante h4 {
  position: relative;
}

.annotation-flottante h4 .ligne {
  /* la flèche part exactement du bracket et rejoint le titre :
     sa largeur = l'espacement (2rem) moins le retrait avant le titre */
  position: absolute;
  right: calc(100% + 0.4rem);
  top: 50%;
  width: 1.6rem;
  height: 1px;
  background: var(--encre);
}

.annotation-flottante h4 .ligne::after {
  content: "";
  position: absolute;
  right: 0;
  top: 50%;
  width: 7px;
  height: 7px;
  border-top: 1px solid var(--encre);
  border-right: 1px solid var(--encre);
  transform: translateY(-50%) rotate(45deg);
}

.annotation-flottante p,
.annotation-flottante li {
  /* le texte se resserre légèrement quand l'écran rétrécit,
     pour rester dans sa zone */
  font-size: clamp(0.78rem, 1vw, 0.9rem);
  color: var(--encre-douce);
}

.annotation-flottante ul {
  list-style: none;
  padding: 0;
}

.annotation-flottante li + li {
  margin-top: 0.3rem;
}

@media (max-width: 920px) {
  /* Dès que l'espace manque pour les brackets, les annotations
     s'empilent sous le template : lisible et sans chevauchement */
  .schema-annote {
    grid-template-columns: 1fr;
  }

  .schema-annote .schema-image {
    max-width: 320px;
  }

  .schema-annotations {
    position: static;
  }

  .annotation-flottante {
    position: static;
    height: auto;
    margin-top: 1.5rem;
  }

  .annotation-flottante .ligne,
  .annotation-flottante .bracket {
    display: none;
  }

  .annotation-flottante p,
  .annotation-flottante li {
    font-size: 0.9rem; /* taille de lecture normale une fois empilé */
  }
}

@media (max-width: 720px) {
  /* Exemples de linktrees sur 2 colonnes */
  .grille-telephones {
    grid-template-columns: repeat(2, 1fr);
  }
}

/* ----- Personas (Radio-Canada) : un par rangée, sans contour ----- */
.personas {
  display: grid;
  grid-template-columns: 1fr;
  gap: 3.5rem; /* bon espace entre chaque persona */
}

.persona {
  display: grid;
  grid-template-columns: 180px 1fr; /* illustration à gauche, texte à droite */
  gap: 2rem;
  align-items: center;
}

.persona img {
  width: 100%;
}

.persona h3 {
  font-size: 1.35rem;
  margin-bottom: 0.4rem;
}

.persona .trait {
  font-family: var(--police-accent);
  font-size: 0.82rem;
  color: var(--encre-douce);
  margin-bottom: 1rem;
}

@media (max-width: 900px) {
  /* Sur petit écran : un persona par rangée */
  .personas {
    grid-template-columns: 1fr;
  }
}

/* Navigation entre projets */
.autres-projets {
  /* plus d'espace au-dessus pour bien détacher des projets du contenu */
  padding: clamp(4rem, 10vw, 7rem) 0 3rem;
  /* opaque et au-dessus de l'image épinglée pour la recouvrir en bas de page */
  position: relative;
  z-index: 2;
  background: var(--papier);
}

/* Titre « Autres projets » aligné à gauche, plus petit, sans trait. */
.autres-projets .titre-section::after {
  display: none;
}
.autres-projets .titre-section {
  font-size: clamp(1rem, 2vw, 1.25rem);
  margin-bottom: 1.5rem;
}

/* Nom + phrase de résumé du projet, empilés à gauche du lien */
.autres-projets .lien-texte {
  display: flex;
  flex-direction: column;
}
.autres-projets .lien-sous-titre {
  margin-top: 0.35rem;
  font-family: var(--police-texte);
  font-weight: 400;
  text-transform: none;
  letter-spacing: 0;
  font-size: clamp(0.85rem, 1.5vw, 1rem);
  color: var(--encre-douce);
}

/* Au survol d'une option, le texte et la flèche glissent vers la droite
   pour bien montrer laquelle est sélectionnée. */
.autres-projets .lien-texte,
.autres-projets .fleche {
  transition: transform 0.3s ease;
}
/* Le texte garde son glissement horizontal ; la flèche, elle, pivote seulement. */
.autres-projets .liens a:hover .lien-texte {
  transform: translateX(0.75rem);
}
.autres-projets .liens a:hover .fleche {
  transform: rotate(-45deg); /* pointe vers le haut-droite, comme les cartes */
}

/* Les deux projets empilés en pleine largeur : nom à gauche, flèche tout à
   droite, séparés par un fin trait. */
.autres-projets .liens {
  display: flex;
  flex-direction: column;
}

.autres-projets .liens a {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 1rem;
  width: 100%;
  font-family: var(--police-titre);
  font-weight: 700;
  text-transform: uppercase;
  font-size: clamp(1.5rem, 3.5vw, 2.6rem);
  padding: clamp(1rem, 2.5vw, 1.75rem) 0;
  border-top: 1px solid var(--ligne);
  cursor: none; /* remplacé par le curseur personnalisé « Voir » */
}

.autres-projets .liens a:last-child {
  border-bottom: 1px solid var(--ligne);
}

.autres-projets .fleche {
  flex: 0 0 auto;
  line-height: 0;
  color: var(--encre);
}

.autres-projets .fleche svg {
  width: clamp(28px, 4vw, 40px);
  height: auto;
}

/* ----- Curseur personnalisé « Voir » au survol des liens « autre projet » -----
   Un rond noir avec « Voir », qui suit la souris (positionné par js/main.js). */
.curseur-voir {
  position: fixed;
  top: 0;
  left: 0;
  z-index: 9998;
  width: 4.1rem;
  height: 4.1rem;
  border-radius: 50%;
  background: var(--encre);
  color: var(--papier);
  display: grid;
  place-items: center;
  font-family: var(--police-titre);
  font-weight: 600;
  font-size: 0.85rem;
  letter-spacing: 0.01em;
  pointer-events: none;
  opacity: 0;
  transform: translate(-50%, -50%) scale(0.3);
  transition: opacity 0.45s cubic-bezier(0.33, 1, 0.68, 1),
              transform 0.45s cubic-bezier(0.33, 1, 0.68, 1);
}

.curseur-voir.actif {
  opacity: 1;
  transform: translate(-50%, -50%) scale(1);
}

/* ----- Rideau de transition entre les pages ----- */
/* Au clic sur un lien interne, un panneau noir monte depuis le bas pour
   couvrir l'écran (avec le nom de la destination), puis la navigation a
   lieu. À l'arrivée sur la nouvelle page, le panneau continue de monter
   et se retire pour révéler le contenu. Tout est piloté par js/main.js. */
.rideau {
  position: fixed;
  inset: 0;
  z-index: 9999;
  background: var(--encre);
  display: flex;
  align-items: center;
  justify-content: center;
  transform: translateY(calc(-100% - 100px)); /* au repos : hors écran, au-dessus */
  pointer-events: none;
  /* Joué dès le 1er rendu (CSS pur) : le panneau couvre l'écran puis se retire
     pour révéler la page. Pas de dépendance JS = pas de rejeu ni de flash. */
  animation: rideau-revele 0.9s cubic-bezier(0.65, 0, 0.35, 1) both;
}

.rideau-nom {
  font-family: var(--police-titre); /* même typo que les h1 (Manrope) */
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: -0.01em; /* crénage serré comme les h1 */
  /* Taille SANS unité de viewport : sinon l'apparition de la barre de
     défilement (quand la page s'allonge) change la largeur du viewport, donc
     la taille du texte se recalcule et le nom "clignote" pendant la transition. */
  font-size: 3rem;
  color: var(--papier);
}

@media (max-width: 600px) {
  .rideau-nom {
    font-size: 2rem;
  }
}

/* Coiffes arrondies en débord, du même noir, au-dessus et en dessous du
   panneau. Hors écran quand le panneau couvre tout ; pendant le mouvement,
   c'est ce bord courbe qui traverse l'écran : un dôme arrondi en haut quand
   le panneau monte pour couvrir (sortie), et une courbe en bas quand il se
   retire pour révéler la page (arrivée). Rend le balayage plus fluide
   qu'un bord droit. La hauteur (--coiffe) règle la profondeur de la courbe. */
/* La profondeur de la coiffe (--coiffe-h) est animée pour l'effet de rebond :
   le bord arrondi s'étire en pleine course puis se résorbe. Enregistrée via
   @property pour qu'elle s'interpole en douceur (sinon elle sauterait). */
@property --etire {
  syntax: "<number>";
  inherits: true;
  initial-value: 1;
}

.rideau {
  --coiffe-h: 70px; /* profondeur de la courbe au repos */
  --etire: 1;       /* étirement vertical des coiffes (animé pour le rebond, via transform) */
}

.rideau::before,
.rideau::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  height: var(--coiffe-h);
  background: var(--encre);
  transform: scaleY(var(--etire)); /* coiffes arrondies, statiques */
}

.rideau::before {            /* coiffe du haut - bord d'attaque à la sortie */
  bottom: calc(100% - 2px); /* chevauche le panneau de 2px pour éviter une couture grise */
  border-radius: 50% 50% 0 0 / 100% 100% 0 0;
  transform-origin: bottom;  /* s'étire vers le haut, depuis le bord du panneau */
}

.rideau::after {             /* coiffe du bas - bord d'attaque à l'arrivée */
  top: calc(100% - 2px); /* chevauche le panneau de 2px pour éviter une couture grise */
  border-radius: 0 0 50% 50% / 0 0 100% 100%;
  transform-origin: top;     /* s'étire vers le bas, depuis le bord du panneau */
}

@keyframes rideau-revele {
  0%   { transform: translateY(0); }                      /* couvre (nom visible) */
  20%  { transform: translateY(0); }                      /* court arrêt : on lit le nom */
  100% { transform: translateY(calc(-100% - 100px)); }    /* glisse hors de l'écran, en douceur */
}

/* Sortie : le panneau monte depuis le bas pour couvrir, avec le même
   étirement de coiffe (du haut cette fois) puis rebond. Déclenchée par la
   classe .rideau--sortie ajoutée au clic (voir js/main.js). */
@keyframes rideau-sortie {
  0%   { transform: translateY(calc(100% + 100px)); } /* part d'en dessous */
  100% { transform: translateY(0); }                  /* monte couvrir, en douceur */
}

.rideau.rideau--sortie {
  /* monte puis ralentit en douceur jusqu'à couvrir (on lit le nom),
     avant la navigation */
  animation: rideau-sortie 0.75s cubic-bezier(0.16, 1, 0.3, 1) forwards;
}

/* Première arrivée (« Bonjour ») : le rideau reste couvert un peu plus
   longtemps pour qu'on lise le mot, puis tout le ballet (rideau + contenu)
   est décalé du même délai pour garder exactement la même synchro. */
html.bonjour .rideau { animation-delay: 0.4s; }
/* Première arrivée : le nom se révèle au CENTRE de l'écran derrière un
   masque (de bas en haut), marque une courte pause, puis monte se caler
   à sa place. Les onglets « À propos » apparaissent pendant la montée.
   --nom-decale (distance position finale -> centre) est mesuré par
   js/main.js ; le 28vh est un simple repli si le JS n'a pas pu mesurer. */
html.bonjour .hero h1 {
  animation: hero-nom-intro 2.1s cubic-bezier(0.22, 1, 0.36, 1) 1s backwards;
}
/* Les onglets et le texte n'apparaissent qu'en toute FIN de montée du
   nom (il se cale à 1s + 2.1s = 3.1s) : fondu de 2.85s à 3.35s, avec un
   départ d'opacité progressif (ease-in-out) pour ne pas surgir d'un
   coup pendant que le nom bouge encore. */
html.bonjour .apropos-hero {
  animation-delay: 2.85s;
  animation-duration: 0.5s;
  animation-timing-function: cubic-bezier(0.45, 0, 0.25, 1);
}

@keyframes hero-nom-intro {
  0% {
    /* masqué : la fenêtre de découpe est vide, le nom est un peu plus bas */
    clip-path: inset(100% -2% -12% -2%);
    transform: translateY(calc(var(--nom-decale, 28vh) + 0.4em));
    animation-timing-function: cubic-bezier(0.22, 1, 0.36, 1);
  }
  45%, 66% {
    /* révélé au centre, courte pause (marges négatives : accents intacts) */
    clip-path: inset(-12% -2% -12% -2%);
    transform: translateY(var(--nom-decale, 28vh));
    animation-timing-function: cubic-bezier(0.65, 0, 0.35, 1);
  }
  100% {
    clip-path: inset(-12% -2% -12% -2%);
    transform: none;
  }
}
html.bonjour #projets .titre-section { animation-delay: 1.3s; }
html.bonjour .grille-projets .carte-projet:nth-child(1) { animation-delay: 1.4s; }
html.bonjour .grille-projets .carte-projet:nth-child(2) { animation-delay: 1.52s; }
html.bonjour .grille-projets .carte-projet:nth-child(3) { animation-delay: 1.64s; }

/* Respect des préférences système : aucun rideau si l'utilisateur a
   demandé de réduire les animations. */
@media (prefers-reduced-motion: reduce) {
  .rideau {
    animation: none;
  }
}

/* ----- 9. Animations & responsive ----- */
/* L'animation ne s'active que si le JS a pu marquer <html> avec .js :
   sans JavaScript, tout le contenu reste visible (sécurité). */

html.js .reveler {
  opacity: 0;
  transform: translateY(24px);
  transition: opacity 0.6s ease, transform 0.6s ease;
}

html.js .reveler.visible {
  opacity: 1;
  transform: none;
}

/* ============================================================
   Menu « Projets » : overlay sombre + panneau à droite
   Ouvert par le lien « Projets » de la nav (depuis n'importe quelle page).
   ============================================================ */
.menu-projets {
  position: fixed;
  inset: 0;
  z-index: 500;
  visibility: hidden;
  pointer-events: none; /* conteneur transparent : ne bloque jamais la nav */
}

.menu-projets.ouvert {
  visibility: visible;
}

/* Seuls le voile et le panneau captent la souris (pas la zone vide au-dessus
   de la nav) - sinon le survol de « Projets » serait interrompu (flash). */
.menu-projets-fond,
.menu-projets-panneau {
  pointer-events: auto;
}

/* Voile sombre qui atténue la page pour mettre l'emphase sur le panneau */
.menu-projets-fond {
  position: absolute;
  top: var(--nav-h, 80px); /* sous la barre de navigation */
  right: 0;
  bottom: 0;
  left: 0;
  background: rgba(17, 17, 17, 0.55);
  opacity: 0;
  transition: opacity 0.4s ease;
}
.menu-projets.ouvert .menu-projets-fond {
  opacity: 1;
}

/* Panneau collé à droite, pleine hauteur, jusqu'au bord de l'écran */
.menu-projets-panneau {
  position: absolute;
  top: var(--nav-h, 80px); /* s'ouvre sous la barre de navigation */
  right: 0;
  left: 38vw; /* défaut ; aligné sur le mot « Projets » par js/main.js */
  height: auto; /* la hauteur s'arrête au dernier projet */
  max-height: calc(100dvh - var(--nav-h, 80px) - 1rem);
  background: var(--papier);
  display: flex;
  flex-direction: column;
  overflow-y: auto;
  transform: translateY(-14px);
  opacity: 0;
  transition: transform 0.4s cubic-bezier(0.33, 1, 0.68, 1), opacity 0.35s ease;
  box-shadow: 0 26px 70px rgba(17, 17, 17, 0.18);
}
.menu-projets.ouvert .menu-projets-panneau {
  transform: translateY(0);
  opacity: 1;
}

.menu-projets-entete {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 1.1rem clamp(0.75rem, 2vw, 1.1rem);
  border-bottom: 1px solid var(--ligne);
}
.menu-projets-entete .titre {
  text-transform: uppercase;
  letter-spacing: 0.08em;
  font-size: 0.8rem;
  color: var(--encre-douce);
}
.menu-projets-fermer {
  background: none;
  border: none;
  font-size: 1.6rem;
  line-height: 1;
  cursor: pointer;
  color: var(--encre);
  padding: 0;
}

.menu-projets-liste {
  display: flex;
  flex-direction: column;
}

/* Une ligne projet : photo carrée | titre + phrase | flèche */
.menu-projet {
  display: grid;
  grid-template-columns: auto 7.5rem minmax(0, 1fr) auto; /* photo | titre | contenu | flèche */
  align-items: stretch; /* le contenu prend la hauteur de l'image */
  gap: clamp(0.85rem, 2.5vw, 1.5rem);
  padding: clamp(0.85rem, 2vw, 1.25rem) clamp(0.75rem, 2vw, 1.1rem);
  border-bottom: 1px solid var(--ligne);
  color: var(--encre);
  transition: background 0.25s ease;
}
.menu-projet:hover {
  background: color-mix(in srgb, var(--encre) 4%, transparent);
}

.menu-projet-media {
  width: clamp(100px, 13vw, 132px);
  align-self: stretch;          /* hauteur = hauteur de la ligne */
  min-height: clamp(100px, 13vw, 132px);
  overflow: hidden;             /* clippe le zoom de l'image */
  border-radius: var(--rayon);
  line-height: 0;
}
.menu-projet-photo {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform 0.4s ease; /* zoom doux comme les cartes d'accueil */
}
.menu-projet:hover .menu-projet-photo {
  transform: scale(1.12);
}

/* Titre et phrase : exactement le même style, petit et uniforme. */
.menu-projet-titre,
.menu-projet-phrase {
  font-family: var(--police-titre);
  font-weight: 500;
  font-size: 0.78rem;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  line-height: 1.35;
  color: var(--encre);
}
.menu-projet-titre {
  white-space: nowrap;
  align-self: start; /* aligné en haut, au niveau de la phrase */
}

/* Colonne de contenu : titre/phrase + tags en haut, durée collée en bas. */
/* Phrase + tags + durée empilés et alignés ensemble (tout sous la phrase). */
.menu-projet-contenu {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  min-width: 0;
}

/* Carrés (tags) repris des cartes, sous le titre et la phrase. */
.menu-projet-tags {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
}

/* Temps de lecture (icône livre), aligné en bas - au niveau du bas de l'image. */
.menu-projet-duree {
  margin-top: auto;
  display: flex;
  align-items: center;
  gap: 0.5rem;
  font-family: var(--police-accent);
  font-size: 0.8rem;
  color: var(--encre-douce);
}
.menu-projet-duree svg {
  flex-shrink: 0;
}

.menu-projet-fleche {
  flex: 0 0 auto;
  align-self: start; /* flèche en haut */
  line-height: 0;
  color: var(--encre);
  transition: transform 0.3s ease;
}
.menu-projet-fleche svg {
  width: 20px;
  height: 20px;
}
.menu-projet:hover .menu-projet-fleche {
  transform: rotate(-45deg); /* pointe vers le haut-droite au survol */
}

@media (prefers-reduced-motion: reduce) {
  .menu-projets-fond,
  .menu-projets-panneau,
  .menu-projet-photo,
  .menu-projet-fleche { transition: none; }
}

/* Sur petit écran, le panneau prend toute la largeur. */
@media (max-width: 900px) {
  .menu-projets-panneau { left: 0; }
}

/* ============================================================
   Pages projets - optimisation téléphone (<= 600px).
   Le desktop et la tablette (gérés plus haut) ne changent pas.
   ============================================================ */
@media (max-width: 600px) {
  /* En-tête projet : bannière plus courte sur téléphone (au lieu de presque
     tout l'écran), tout en gardant l'effet épinglé. */
  .projet-hero img {
    height: clamp(220px, 45svh, 360px);
  }

  /* Blocs numérotés : plus de retrait en marge, le numéro passe en ligne
     « (01) Titre » et le contenu prend toute la largeur. */
  .bloc {
    padding-left: 0;
  }
  .bloc > h2 {
    margin-left: 0;
  }
  .bloc h2 {
    gap: 0.6rem;
  }
  .bloc h2::before {
    flex: 0 0 auto;
  }

  /* Infos projet et statistiques : tout empilé sur une seule colonne. */
  .meta-grille {
    grid-template-columns: 1fr;
  }
  .grille-cartes,
  .grille-cartes.trois-colonnes {
    grid-template-columns: 1fr;
  }

  /* Comparaisons Avant/Après : une maquette par rangée, centrée ; les
     annotations (déjà sans flèches sous 920px) suivent en dessous. */
  .trois-col,
  .quatre-col,
  .trois-maquettes {
    grid-template-columns: 1fr;
  }
  .comparaison-annotee img {
    max-width: 240px;
    margin: 0;               /* maquette alignée à gauche */
  }
  .comparaison-annotee figcaption {
    text-align: left;
  }

  /* Maquettes seules (ex. Safeway, solution finale) : bien plus grandes sur
     téléphone, pour qu'on voie bien l'écran (elles n'ont qu'une maquette). */
  .solo-deux-cotes figure img {
    max-width: min(88vw, 420px);
  }
  /* on annule les placements de grille prévus pour l'affichage 2 colonnes */
  .quatre-col > figure:nth-of-type(1),
  .quatre-col > figure:nth-of-type(2),
  .trois-maquettes > figure:nth-of-type(1),
  .trois-maquettes > figure:nth-of-type(2),
  .trois-maquettes > figure:nth-of-type(3) {
    grid-column: auto;
    grid-row: auto;
  }

  /* « Ajout d'indicateurs » (quatre-col) : les deux maquettes d'abord, puis
     les quatre annotations regroupées sous la maquette Recommandation
     (Résumé enrichi + Temps de lecture rejoignent Indicateur de lecture +
     Audio intégré). */
  .quatre-col > figure:nth-of-type(1) { order: 1; }
  .quatre-col > figure:nth-of-type(2) { order: 2; }
  .quatre-col > .col-annotations:nth-of-type(1) { order: 3; }
  .quatre-col > .col-annotations:nth-of-type(2) { order: 4; }
}

/* Téléphone : le pied de page s'empile et s'aligne à gauche, comme le reste. */
@media (max-width: 680px) {
  .footer-inner {
    flex-direction: column;
    gap: 2rem;
    justify-content: flex-start;
    align-items: flex-start;
  }
  .footer-inner > div:last-child {
    text-align: left;
  }
}

/* Menu « Projets » ouvert sur mobile (via le clic dans le hamburger) : lignes
   compactes photo + nom + question, sans tags/durée/flèche, pour tenir à
   l'écran et permettre d'aller directement à un autre projet. */
@media (max-width: 900px) {
  .menu-projet {
    grid-template-columns: 72px minmax(0, 1fr);
    align-items: center;
    gap: 0.2rem 0.9rem;
  }
  .menu-projet-media {
    grid-column: 1;
    grid-row: 1 / span 2;
    width: 72px;
    min-height: 72px;
    align-self: center;
  }
  .menu-projet-titre { grid-column: 2; grid-row: 1; }
  .menu-projet-contenu { grid-column: 2; grid-row: 2; }
  .menu-projet-tags,
  .menu-projet-duree,
  .menu-projet-fleche { display: none; }
}

/* « Projets » repliable dans le menu hamburger (mobile), calqué sur Contact
   (mêmes classes .nav-contact-*). Caché sur grand écran, où « Projets » reste
   un lien qui ouvre le grand popup au survol. */
.nav-projets-mobile { display: none; }
@media (max-width: 900px) {
  .nav-projets-mobile { display: block; }
  /* le lien « Projets » du desktop est masqué sur mobile (remplacé par le
     volet repliable ci-dessus) */
  .nav-liens > a[href$="#projets"] { display: none; }
}

/* Personas sur téléphone : image en haut, texte en dessous. Image à taille
   modérée, calée à gauche (Jérôme ajustera peut-être la taille plus tard). */
@media (max-width: 680px) {
  .persona {
    grid-template-columns: 1fr;
    gap: 1rem;
    align-items: start;
  }
  .persona img {
    width: clamp(150px, 48vw, 200px);
    justify-self: start;
  }
}
