/* ==========================================================================
   AMPIL — feuille de style du site

   Sommaire
     1. Polices
     2. Couleurs et mesures (jetons)
     3. Thèmes de section
     4. Base
     5. Outils (conteneur, libellé, titres, boutons, liens…)
     6. Décor (fond en dégradé, grain, cercles)
     7. En-tête, menu et pied de page
     8. Sections de l'accueil
     9. Autres pages
    10. Espace membre (discussions, messagerie, mode sombre)
    11. Animations

   Charte : trois couleurs plus le blanc, rien d'autre (beurre, miel, bleu canard).
   Contrastes : bleu canard sur beurre ou miel ; beurre ou miel sur
   bleu canard ; jamais de miel sur beurre.
   ========================================================================== */

/* ==========================================================================
   1. POLICES
   Servies par le site lui-même. Les polices « de repli » sont un Arial
   redimensionné : en attendant le chargement, le texte occupe la même place
   et la page ne saute pas.
   ========================================================================== */

@font-face {
  font-family: "Syne";
  src: url("../fonts/syne.woff2") format("woff2");
  font-weight: 400 800;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: "Montserrat";
  src: url("../fonts/montserrat.woff2") format("woff2");
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: "Syne repli";
  src: local("Arial");
  ascent-override: 93.93%;
  descent-override: 27.93%;
  line-gap-override: 0%;
  size-adjust: 98.47%;
}

@font-face {
  font-family: "Montserrat repli";
  src: local("Arial");
  ascent-override: 85.79%;
  descent-override: 22.25%;
  line-gap-override: 0%;
  size-adjust: 112.83%;
}

/* ==========================================================================
   2. COULEURS ET MESURES
   Les variantes 50 → 900 sont dérivées de chaque couleur en gardant sa teinte
   (500 = la couleur de base, 50–400 = éclaircies, 600–900 = assombries).

   Beurre et miel viennent de la palette « Honey / Butter » donnée par Noé le
   2026-10-11 (Mesures Physiques est jaune). Le jaune du logo du département
   (#fcc42c) est plus chaud : pour l'adopter, changer --ampil-miel et ses variantes.
   Le bleu canard reste l'encre : c'est lui qui garantit le contraste du texte.
   ========================================================================== */

:root {
  /* Blanc : ajouté à la demande de Noé pour un site plus clair (fonds de page et panneaux). */
  --ampil-blanc: #ffffff;

  --ampil-beurre: #fff9c7;
  --ampil-beurre-50: #fffde9;
  --ampil-beurre-100: #fffce4;
  --ampil-beurre-200: #fffbdc;
  --ampil-beurre-300: #fffbd6;
  --ampil-beurre-400: #fffacf;
  --ampil-beurre-500: #fff9c7;
  --ampil-beurre-600: #c7c29b;
  --ampil-beurre-700: #999577;
  --ampil-beurre-800: #73705a;
  --ampil-beurre-900: #4a483a;

  --ampil-miel: #f6d110;
  --ampil-miel-50: #fef8db;
  --ampil-miel-100: #fdf4c8;
  --ampil-miel-200: #fceea7;
  --ampil-miel-300: #fae67e;
  --ampil-miel-400: #f9df58;
  --ampil-miel-500: #f6d110;
  --ampil-miel-600: #caab0d;
  --ampil-miel-700: #9d860a;
  --ampil-miel-800: #766408;
  --ampil-miel-900: #4f4305;

  --ampil-teal: #00545f;
  --ampil-teal-50: #d0eef4;
  --ampil-teal-100: #b1d5db;
  --ampil-teal-200: #87b1b9;
  --ampil-teal-300: #5f9099;
  --ampil-teal-400: #36717b;
  --ampil-teal-500: #00545f;
  --ampil-teal-600: #02434c;
  --ampil-teal-700: #00333a;
  --ampil-teal-800: #002429;
  --ampil-teal-900: #00151a;

  --police-titre: "Syne", "Syne repli", "Arial Black", sans-serif;
  --police-texte: "Montserrat", "Montserrat repli", system-ui, sans-serif;

  /* Tailles fluides (mobile → grand écran). Syne ExtraBold est très large :
     ces bornes garantissent qu'un mot long tient sur un petit écran. */
  --taille-h2: clamp(1.75rem, 7.2vw, 4.75rem);
  --taille-h3: clamp(1.25rem, 2.6vw, 1.875rem);
  --taille-chapo: clamp(1.0625rem, 1.55vw, 1.375rem);

  --rayon-panneau: clamp(1.75rem, 4.5vw, 3.5rem);
  --rayon-carte: 1.75rem;
  --courbe: cubic-bezier(0.16, 1, 0.3, 1);
  /* Courbe des écrans de l'application : démarre vite et se pose en douceur, comme une feuille d'iPhone. */
  --courbe-app: cubic-bezier(0.32, 0.72, 0, 1);
}

/* ==========================================================================
   3. THÈMES DE SECTION
   Une section choisit son thème avec l'attribut data-theme. Les couleurs
   « de rôle » ci-dessous changent en conséquence : un même composant
   (bouton, titre, carte) fonctionne ainsi sur tous les fonds.
   ========================================================================== */

/* Le site est clair par défaut ; le thème sombre sert aux cartes, à l'en-tête et au pied de page. */
[data-theme="dark"] {
  --fg: var(--ampil-beurre);
  /* 84 % d'opacité : 6:1 sur le bleu canard uni, et encore plus de 4,5:1 sur
     les zones un peu plus claires du dégradé. */
  --fg-muted: color-mix(in srgb, var(--ampil-beurre) 84%, transparent);
  --line: color-mix(in srgb, var(--ampil-beurre) 20%, transparent);
  --accent: var(--ampil-miel);
  --on-accent: var(--ampil-teal);
  --surface: color-mix(in srgb, var(--ampil-teal-800) 62%, transparent);
  --focus: var(--ampil-miel);
  --btn-survol: var(--ampil-beurre);
}

:root,
[data-theme="light"] {
  --fg: var(--ampil-teal);
  --fg-muted: var(--ampil-teal-400);
  --line: color-mix(in srgb, var(--ampil-teal) 22%, transparent);
  /* Sur fond clair, l'accent devient bleu canard : le miel y serait illisible. */
  --accent: var(--ampil-teal);
  --on-accent: var(--ampil-miel);
  --surface: color-mix(in srgb, var(--ampil-teal) 7%, transparent);
  --focus: var(--ampil-teal);
  --btn-survol: var(--ampil-teal-700);
}

[data-theme="miel"] {
  --fg: var(--ampil-teal);
  --fg-muted: var(--ampil-teal);
  --line: color-mix(in srgb, var(--ampil-teal) 28%, transparent);
  --accent: var(--ampil-teal);
  --on-accent: var(--ampil-miel);
  --surface: color-mix(in srgb, var(--ampil-teal) 9%, transparent);
  --focus: var(--ampil-teal);
  --btn-survol: var(--ampil-teal-700);
}

[data-theme] {
  color: var(--fg);
}

/* ==========================================================================
   4. BASE
   ========================================================================== */

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

* {
  margin: 0;
}

html {
  background-color: var(--ampil-blanc);
  color: var(--fg);
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
  /* Marge laissée à l'en-tête flottant quand on arrive sur une ancre. */
  scroll-padding-top: 5.5rem;
}

body {
  min-height: 100svh;
  font-family: var(--police-texte);
  font-size: 1rem;
  font-weight: 450;
  line-height: 1.65;
  overflow-x: clip;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

h1,
h2,
h3 {
  font-size: inherit;
  font-weight: inherit;
  text-wrap: balance;
}

p {
  text-wrap: pretty;
}

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

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

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

button,
input {
  padding: 0;
  border: 0;
  background: none;
  color: inherit;
  font: inherit;
  letter-spacing: inherit;
}

button {
  cursor: pointer;
}

address {
  font-style: normal;
}

::selection {
  background-color: var(--ampil-miel);
  color: var(--ampil-teal);
}

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

/* « hidden » doit toujours cacher, même sur un élément dont une classe règle l'affichage. */
[hidden] {
  display: none !important;
}

/* Une section atteinte par un lien d'ancre reçoit le focus sans cadre visible. */
section:focus {
  outline: none;
}

/* ==========================================================================
   5. OUTILS
   ========================================================================== */

/* Texte réservé aux lecteurs d'écran. */
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* Lien « Aller au contenu », visible seulement quand on y arrive au clavier. */
.evitement {
  position: fixed;
  top: 1rem;
  left: 1rem;
  z-index: 90;
  padding: 0.75rem 1.25rem;
  border-radius: 9999px;
  background-color: var(--ampil-miel);
  color: var(--ampil-teal);
  font-size: 0.875rem;
  font-weight: 600;
  transform: translateY(-6rem);
}

.evitement:focus-visible {
  transform: none;
}

/* Conteneur centré avec marges fluides. */
.wrap {
  width: 100%;
  max-width: 88rem;
  margin-inline: auto;
  padding-inline: clamp(1.25rem, 4.5vw, 3.5rem);
}

/* Petit libellé en capitales très espacées (01 — LE CONCEPT). */
.label {
  font-size: 0.6875rem;
  font-weight: 600;
  line-height: 1.5;
  letter-spacing: 0.28em;
  text-transform: uppercase;
}

/* Titre « affiche » : Syne ExtraBold, très large. */
.display {
  font-family: var(--police-titre);
  font-weight: 800;
  letter-spacing: -0.015em;
  overflow-wrap: break-word;
}

.titre-3 {
  font-size: var(--taille-h3);
  line-height: 1.12;
}

/* Texte d'introduction, un peu plus grand que le texte courant. */
.chapo {
  font-size: var(--taille-chapo);
  line-height: 1.5;
}

.chapo--attenue {
  color: var(--fg-muted);
}

.texte-contour {
  color: transparent;
  -webkit-text-stroke: 1px var(--fg);
}

.icone {
  flex: none;
  width: 1rem;
  height: 1rem;
}

.icone--petite {
  width: 0.875rem;
  height: 0.875rem;
}

.logo {
  width: auto;
  height: 1.5rem;
}

.logo--grand {
  height: 2rem;
}

@media (min-width: 48rem) {
  .entete .logo {
    height: 1.75rem;
  }
}

/* --- En-tête de section -------------------------------------------------- */
.titre-section {
  display: flex;
  flex-direction: column;
  gap: 1.5rem;
}

.titre-section__label {
  display: flex;
  align-items: center;
  gap: 1rem;
}

.titre-section__numero {
  color: var(--accent);
}

.titre-section__trait {
  width: 2.5rem;
  height: 1px;
  background-color: var(--line);
}

.titre-section__titre {
  font-size: var(--taille-h2);
  line-height: 0.98;
}

/* Titre plus petit, pour les sections où il partage la largeur avec une autre colonne. */
.titre-section__titre--compact {
  font-size: clamp(1.75rem, 4.6vw, 3.5rem);
}

@media (min-width: 48rem) {
  .titre-section {
    gap: 2rem;
  }
}

/* --- Bouton : un disque de couleur s'étend au survol ---------------------- */
.btn {
  position: relative;
  isolation: isolate;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.75rem;
  max-width: 100%;
  overflow: hidden;
  padding: 1.05rem 1.6rem;
  border-radius: 9999px;
  font-size: 0.9375rem;
  font-weight: 650;
  /* Un libellé trop long passe sur deux lignes au lieu de faire déborder la page. */
  line-height: 1.15;
  text-wrap: balance;
  transition: color 0.45s var(--courbe);
}

.btn::before {
  content: "";
  position: absolute;
  top: 50%;
  left: 50%;
  z-index: -1;
  width: 130%;
  aspect-ratio: 1;
  border-radius: 9999px;
  background-color: var(--btn-fond-survol);
  transform: translate(-50%, -50%) scale(0);
  transition: transform 0.6s var(--courbe);
}

.btn--primary {
  --btn-fond-survol: var(--btn-survol);
  background-color: var(--accent);
  color: var(--on-accent);
}

.btn--ghost {
  --btn-fond-survol: var(--accent);
  box-shadow: inset 0 0 0 1.5px var(--line);
  color: var(--fg);
}

.btn--compact {
  padding-block: 0.875rem;
}

.btn__arrow {
  transition: transform 0.45s var(--courbe);
}

@media (hover: hover) {
  .btn:hover::before {
    transform: translate(-50%, -50%) scale(1);
  }

  .btn--ghost:hover {
    color: var(--on-accent);
  }

  .btn:hover .btn__arrow {
    transform: translateX(0.3rem);
  }
}

/* --- Liens ---------------------------------------------------------------- */
/* Lien souligné : le trait se retire au survol. */
.link-line {
  background-image: linear-gradient(currentColor, currentColor);
  background-repeat: no-repeat;
  background-position: 0 100%;
  background-size: 100% 1px;
  transition: background-size 0.45s var(--courbe);
}

@media (hover: hover) {
  .link-line:hover,
  a:hover > .link-line {
    background-position: 100% 100%;
    background-size: 0 1px;
  }
}

.lien-fleche {
  display: inline-flex;
  align-items: center;
  gap: 0.625rem;
  font-size: 0.875rem;
  font-weight: 600;
}

.lien-externe {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
}

/* --- Carte, liste à coches ------------------------------------------------- */
.carte {
  padding: 1.5rem;
  border: 1px solid var(--line);
  border-radius: var(--rayon-carte);
  background-color: var(--surface);
}

@media (min-width: 48rem) {
  .carte {
    padding: 2rem;
  }

  .carte--large {
    padding: 2.5rem;
  }
}

.liste-coches {
  display: flex;
  flex-direction: column;
  gap: 1rem;
}

.liste-coches li {
  display: flex;
  align-items: flex-start;
  gap: 1rem;
}

.coche {
  display: grid;
  flex: none;
  place-items: center;
  width: 1.5rem;
  height: 1.5rem;
  margin-top: 0.125rem;
  border-radius: 9999px;
  background-color: var(--accent);
  color: var(--on-accent);
}

/* --- Formulaires -------------------------------------------------------------
   Un champ = un libellé, une saisie, une aide, un message d'erreur. Le contour
   des saisies est en bleu canard clair : au moins 3:1 sur le blanc (WCAG 1.4.11). */
.formulaire {
  display: grid;
  gap: 1.25rem;
  margin-top: 1.5rem;
}

.formulaire__ligne {
  display: grid;
  gap: 1.25rem;
}

@media (min-width: 40rem) {
  .formulaire__ligne {
    grid-template-columns: 1fr 1fr;
  }
}

.champ {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  min-width: 0;
}

.champ__label {
  font-size: 0.875rem;
  font-weight: 600;
  line-height: 1.4;
}

.champ__saisie {
  width: 100%;
  min-height: 3.25rem;
  padding: 0.8rem 1.1rem;
  border-radius: 1rem;
  background-color: var(--ampil-blanc);
  box-shadow: inset 0 0 0 1.5px var(--ampil-teal-300);
  color: var(--fg);
  font: inherit;
  line-height: 1.4;
  transition: box-shadow 0.25s;
}

.champ__saisie:focus-visible {
  outline: 2px solid var(--focus);
  outline-offset: 2px;
  box-shadow: none;
}

/* Mot de passe avec son œil : le bouton est posé sur la droite de la saisie, qui
   lui laisse la place. Cible de 44 px, comme le demande l'usage au doigt. */
.champ__secret {
  position: relative;
}

.champ__secret .champ__saisie {
  padding-right: 3.5rem;
}

.champ__oeil {
  position: absolute;
  top: 50%;
  right: 0.25rem;
  display: grid;
  place-items: center;
  width: 2.75rem;
  height: 2.75rem;
  border-radius: 0.75rem;
  color: var(--fg);
  transform: translateY(-50%);
}

/* display: grid l'emporterait sur l'attribut hidden, posé tant que le script n'a pas démarré. */
.champ__oeil[hidden] {
  display: none;
}

.champ__oeil:focus-visible {
  outline: 2px solid var(--focus);
  outline-offset: 0;
}

.champ__oeil-barre,
.champ__oeil[aria-pressed="true"] .champ__oeil-ouvert {
  display: none;
}

.champ__oeil[aria-pressed="true"] .champ__oeil-barre {
  display: block;
}

.champ__aide {
  color: var(--fg-muted);
  font-size: 0.8125rem;
}

/* Message d'erreur : texte bleu canard sur aplat miel (5,8:1). Le message est écrit en toutes lettres, la couleur n'est jamais seule à porter le sens. */
.champ__erreur,
.formulaire__alerte {
  padding: 0.5rem 0.875rem;
  border-radius: 0.75rem;
  background-color: var(--ampil-miel);
  color: var(--ampil-teal);
  font-size: 0.875rem;
  font-weight: 650;
}

/* Confirmation (« Profil enregistré ») : beurre et bleu canard, 8,1:1. */
.formulaire__succes {
  padding: 0.5rem 0.875rem;
  border-radius: 0.75rem;
  background-color: var(--ampil-beurre);
  box-shadow: inset 0 0 0 1px var(--line);
  color: var(--ampil-teal);
  font-size: 0.875rem;
  font-weight: 650;
}

.champ__saisie--zone {
  min-height: 6rem;
  resize: vertical;
  line-height: 1.5;
}

.champ--erreur .champ__saisie {
  box-shadow: inset 0 0 0 2.5px var(--ampil-teal);
}

.champ--case {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 0.5rem 0.875rem;
  align-items: start;
}

.champ--case .champ__label {
  font-size: 0.9375rem;
  font-weight: 450;
}

.champ--case .champ__aide,
.champ--case .champ__erreur {
  grid-column: 2;
}

.champ__case {
  width: 1.5rem;
  height: 1.5rem;
  margin: 0.0625rem 0 0;
  accent-color: var(--ampil-teal);
}

.formulaire__actions {
  display: flex;
  flex-wrap: wrap;
  gap: 1rem;
  margin-top: 0.5rem;
}

.formulaire__alternative {
  margin-top: 1.5rem;
  color: var(--fg-muted);
}

/* « Mot de passe oublié ? », collé au champ qu'il concerne. Zone de toucher d'au moins 44 px. */
.formulaire__oubli {
  margin-top: -0.5rem;
  font-size: 0.875rem;
}

.formulaire__oubli a {
  display: inline-block;
  padding-block: 0.75rem;
}

/* Lien d'action sous un message d'alerte (« Recevoir un nouveau lien ») : sur sa propre ligne. */
.formulaire__alerte a {
  display: inline-block;
  margin-top: 0.25rem;
}

/* Page d'une seule étape (e-mail envoyé, adresse confirmée…) : texte et action, sans formulaire long. */
.etape-seule > * + * {
  margin-top: 1rem;
}

/* Champ piège à robots : hors de l'écran, et non display:none (certains robots l'ignorent alors). */
.formulaire__piege {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

/* --- Zone de photo ---------------------------------------------------------- */
.photo {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  border-radius: 1.75rem;
  background-color: var(--ampil-teal-600);
}

.photo--paysage {
  aspect-ratio: 4 / 3;
}

.photo--carree {
  aspect-ratio: 1;
}

.photo--portrait {
  aspect-ratio: 4 / 5;
}

.photo--bandeau {
  aspect-ratio: 16 / 10;
}

.photo--detouree {
  outline: 6px solid var(--ampil-blanc);
}

.photo img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.photo__decor {
  position: absolute;
  inset: 0;
}

/* Trois compositions de cercles pour les emplacements vides. Les cercles
   occupent le bas et la droite : le libellé est affiché en haut à gauche. */
.photo--vide-0 .orb:nth-child(1) { right: -14%; bottom: -24%; width: 62%; background: linear-gradient(150deg, var(--ampil-miel) 52%, var(--ampil-teal) 100%); }
.photo--vide-0 .orb:nth-child(2) { bottom: 10%; left: 6%; width: 40%; background: radial-gradient(circle at 32% 26%, rgb(255 249 199 / 0.5), rgb(255 249 199 / 0.05) 64%); box-shadow: inset 0 0 0 1px rgb(255 249 199 / 0.3); }
.photo--vide-0 .orb:nth-child(3) { right: 30%; bottom: 30%; width: 26%; box-shadow: inset 0 0 0 1.5px rgb(255 249 199 / 0.55); }

.photo--vide-1 .orb:nth-child(1) { right: 10%; bottom: 12%; width: 34%; background: linear-gradient(205deg, var(--ampil-beurre) 4%, var(--ampil-miel) 66%, var(--ampil-teal-400) 108%); }
.photo--vide-1 .orb:nth-child(2) { right: 24%; bottom: 4%; width: 54%; box-shadow: inset 0 0 0 1.5px rgb(255 249 199 / 0.55); }
.photo--vide-1 .orb:nth-child(3) { bottom: -22%; left: -14%; width: 56%; background: linear-gradient(160deg, var(--ampil-teal), var(--ampil-teal-900)); }

.photo--vide-2 .orb:nth-child(1) { right: -12%; bottom: -18%; width: 60%; background: radial-gradient(circle at 32% 26%, rgb(255 249 199 / 0.5), rgb(255 249 199 / 0.05) 64%); box-shadow: inset 0 0 0 1px rgb(255 249 199 / 0.3); }
.photo--vide-2 .orb:nth-child(2) { bottom: 10%; left: 10%; width: 34%; background: linear-gradient(150deg, var(--ampil-miel) 52%, var(--ampil-teal) 100%); }
.photo--vide-2 .orb:nth-child(3) { bottom: 26%; left: 30%; width: 30%; box-shadow: inset 0 0 0 1.5px rgb(255 249 199 / 0.55); }

/* Cartouche sombre : le libellé reste lisible quels que soient les cercles derrière. */
.photo__cartouche {
  position: absolute;
  top: 0.75rem;
  left: 0.75rem;
  display: flex;
  flex-direction: column;
  gap: 0.125rem;
  max-width: calc(100% - 1.5rem);
  padding: 0.75rem 1rem;
  border-radius: 1rem;
  background-color: color-mix(in srgb, var(--ampil-teal-900) 85%, transparent);
  color: var(--ampil-beurre);
}

.photo__legende,
.photo__fichier {
  color: var(--fg-muted);
  font-size: 0.875rem;
}

/* Nom du fichier attendu, affiché seulement sur la machine de développement. */
.photo__fichier {
  font-family: ui-monospace, Menlo, Consolas, monospace;
  font-size: 0.6875rem;
  word-break: break-all;
}

@media (min-width: 48rem) {
  .photo {
    border-radius: 2.5rem;
  }

  .photo__cartouche {
    top: 1rem;
    left: 1rem;
  }
}

/* Photo de fond d'un panneau, sous les cercles et le texte. Placée après la
   requête média ci-dessus pour que son angle droit l'emporte : c'est le panneau qui arrondit. */
.photo--fond {
  position: absolute;
  inset: 0;
  z-index: -2;
  border-radius: 0;
}

/* Le voile qui garde le texte lisible est choisi par la section (--voile). */
.photo--fond::after {
  content: "";
  position: absolute;
  inset: 0;
  background: var(--voile);
}

/* ==========================================================================
   6. DÉCOR
   ========================================================================== */

/* --- Fond en dégradé flou --------------------------------------------------
   Version statique en CSS, visible avant le démarrage du script ; le canvas
   animé (Assets/js/modules/fond.js) vient se poser dessus. Chaque dégradé
   reprend une tache de l'ambiance correspondante, avec le même profil en
   cloche, pour que le passage au canvas ne se voie pas.
   Sans JavaScript, le fond reste en haut de page et défile avec elle :
   le reste du site garde un fond bleu canard uni, toujours lisible. */
.mesh {
  position: absolute;
  top: 0;
  left: 0;
  z-index: -1;
  width: 100%;
  height: 100lvh;
  background-color: var(--ampil-blanc);
  pointer-events: none;
}

/* Ambiance « calme » : pages de lecture. */
.mesh {
  background-image:
    radial-gradient(40vmax 40vmax at 16% 6%, rgb(252 238 167 / 0.42), rgb(252 238 167 / 0.24) 40%, rgb(252 238 167 / 0.04) 80%, transparent),
    radial-gradient(62vmax 62vmax at 42% 46%, rgb(255 249 199 / 0.5), rgb(255 249 199 / 0.29) 40%, rgb(255 249 199 / 0.05) 80%, transparent),
    radial-gradient(28vmax 28vmax at -14% 100%, rgb(255 249 199 / 0.14), rgb(255 249 199 / 0.08) 40%, rgb(255 249 199 / 0.01) 80%, transparent),
    radial-gradient(34vmax 34vmax at 116% -4%, rgb(246 209 16 / 0.24), rgb(246 209 16 / 0.14) 40%, rgb(246 209 16 / 0.02) 80%, transparent);
}

/* Ambiance « hero » : l'accueil, avec le miel qui éclate en haut à droite. */
body[data-ambiance="hero"] .mesh {
  background-image:
    radial-gradient(40vmax 40vmax at 18% 30%, rgb(252 238 167 / 0.35), rgb(252 238 167 / 0.2) 40%, rgb(252 238 167 / 0.04) 80%, transparent),
    radial-gradient(50vmax 50vmax at 74% 80%, rgb(255 249 199 / 0.6), rgb(255 249 199 / 0.35) 40%, rgb(255 249 199 / 0.06) 80%, transparent),
    radial-gradient(24vmax 24vmax at -4% 92%, rgb(246 209 16 / 0.3), rgb(246 209 16 / 0.17) 40%, rgb(246 209 16 / 0.03) 80%, transparent),
    radial-gradient(22vmax 22vmax at 60% 28%, rgb(255 249 199 / 0.36), rgb(255 249 199 / 0.21) 40%, rgb(255 249 199 / 0.04) 80%, transparent),
    radial-gradient(40vmax 40vmax at 92% 4%, rgb(246 209 16 / 0.9), rgb(246 209 16 / 0.52) 40%, rgb(246 209 16 / 0.09) 80%, transparent);
}

@media (scripting: enabled) {
  .mesh {
    position: fixed;
    width: 100vw;
  }
}

.mesh canvas {
  width: 100%;
  height: 100%;
}

/* --- Grain ------------------------------------------------------------------
   Bruit SVG (feTurbulence) en deux tons de la charte : des points bleu canard
   très sombres et des points beurre, à opacité variable. Les points sombres
   sont deux fois plus discrets (feFuncA « .5 0 1 »), sinon le grain salit les
   fonds clairs. Pas de mode de fusion : la couche reste légère, même sur mobile. */
.grain {
  position: fixed;
  inset: 0;
  z-index: 70;
  opacity: 0.36;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='240' height='240'%3E%3Cfilter id='g' x='0' y='0' width='100%25' height='100%25' color-interpolation-filters='sRGB'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='2' seed='7' stitchTiles='stitch'/%3E%3CfeColorMatrix values='1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0'/%3E%3CfeComponentTransfer%3E%3CfeFuncR type='discrete' tableValues='0 .925'/%3E%3CfeFuncG type='discrete' tableValues='.08 1'/%3E%3CfeFuncB type='discrete' tableValues='.1 .71'/%3E%3CfeFuncA type='table' tableValues='.5 0 1'/%3E%3C/feComponentTransfer%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23g)'/%3E%3C/svg%3E");
  background-size: 240px 240px;
  pointer-events: none;
}

/* --- Cercles (motif signature : un cercle = une promo) ---------------------
   Règle : un cercle plein ne passe jamais derrière un texte. Seuls les
   anneaux (.orb--ring), simples traits, le peuvent. */
.orb {
  position: absolute;
  aspect-ratio: 1;
  border-radius: 9999px;
}

.orb--miel {
  background: linear-gradient(150deg, var(--ampil-miel) 52%, var(--ampil-teal) 100%);
}

.orb--beurre {
  background: linear-gradient(205deg, var(--ampil-beurre) 4%, var(--ampil-miel) 66%, var(--ampil-teal-400) 108%);
}

.orb--teal {
  background: linear-gradient(160deg, var(--ampil-teal-400), var(--ampil-teal-800));
}

.orb--deep {
  background: linear-gradient(160deg, var(--ampil-teal), var(--ampil-teal-900));
}

.orb--glass {
  background: radial-gradient(circle at 32% 26%, rgb(255 249 199 / 0.5), rgb(255 249 199 / 0.05) 64%);
  box-shadow: inset 0 0 0 1px rgb(255 249 199 / 0.3);
}

.orb--ring {
  box-shadow: inset 0 0 0 1.5px color-mix(in srgb, var(--fg) 55%, transparent);
}

/* Sur fond clair, le cercle « verre » se teinte de bleu canard, sinon il serait invisible. */
[data-theme="light"] > .orb--glass,
[data-theme="light"] :not([data-theme]) > .orb--glass {
  background: radial-gradient(circle at 32% 26%, rgb(0 84 95 / 0.2), rgb(0 84 95 / 0.04) 64%);
  box-shadow: inset 0 0 0 1px rgb(0 84 95 / 0.25);
}

/* Halo miel très flou, posé dans les panneaux clairs. C'est du fond, jamais du texte. */
.halo {
  position: absolute;
  z-index: -1;
  aspect-ratio: 1;
  border-radius: 9999px;
  background: radial-gradient(closest-side, var(--ampil-miel), transparent);
  pointer-events: none;
}

.halo--haut-droite {
  top: -20vmax;
  right: -30vmax;
  width: 80vmax;
  opacity: 0.8;
}

.halo--bas-gauche {
  bottom: -26vmax;
  left: -24vmax;
  width: 60vmax;
  background: radial-gradient(closest-side, var(--ampil-miel-300), transparent);
  opacity: 0.7;
}

.halo--haut-gauche {
  top: -18vmax;
  left: -26vmax;
  width: 70vmax;
  opacity: 0.75;
}

.halo--droite {
  top: 20%;
  right: -28vmax;
  width: 70vmax;
  opacity: 0.75;
}

/* ==========================================================================
   7. EN-TÊTE, MENU ET PIED DE PAGE
   ========================================================================== */

/* Barre repliée en haut de page, déployée dès qu'on défile.
   Une seule variable pilote tout : --etendu, de 0 (pastille centrée qui ne garde
   que le logo et les boutons) à 1 (barre complète, avec les liens). entete.js
   pose l'attribut data-etendu quand on quitte le haut de la page, et data-survol
   quand le pointeur s'arrête sur la partie sombre de la pastille ; le focus du
   clavier déploie aussi la barre. Un bouton de la pastille, lui, ne la déploie
   jamais : sans cela il glisse sous le pointeur avant qu'on ait pu cliquer.
   Déclarée avec @property, la variable peut être animée : logo, boutons, liens et
   forme de la barre suivent alors d'un seul mouvement (transform, opacity et
   clip-path). Sans JavaScript, ou si le navigateur ne connaît pas @property ou
   les unités « cqw », la barre reste simplement complète. */
@property --etendu {
  syntax: "<number>";
  inherits: true;
  initial-value: 1;
}

.entete {
  position: fixed;
  inset: 0 0 auto;
  z-index: 50;
  padding: 0.75rem 0.75rem 0;
  /* Les unités « cqw » ci-dessous se mesurent sur la largeur de ce bloc. */
  container-type: inline-size;
  /* Largeur de la barre déployée, largeur de la pastille, et moitié de la différence :
     la distance dont le logo et les boutons se rapprochent du centre quand la barre est repliée. */
  --barre: min(100cqw, 88rem);
  --pilule: min(36rem, var(--barre));
  --decalage: calc((var(--barre) - var(--pilule)) / 2);
}

.entete__barre {
  --etendu: 1;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  max-width: 88rem;
  margin-inline: auto;
  padding: 0.5rem 0.5rem 0.5rem 1.25rem;
  border: 1px solid var(--line);
  border-radius: 9999px;
  background-color: color-mix(in srgb, var(--ampil-teal-900) 95%, transparent);
  /* Replié : la barre est rognée de chaque côté jusqu'à la pastille. */
  clip-path: inset(0 calc((1 - var(--etendu)) * var(--decalage)) round 9999px);
  /* Un peu plus posée que la courbe du site : on doit voir la barre grandir, pas la voir claquer. */
  transition: --etendu 0.7s cubic-bezier(0.33, 1, 0.68, 1);
}

/* Le cadre de focus reste à l'intérieur de la barre, qui rogne tout ce qui dépasse. */
.entete__barre :focus-visible {
  outline-offset: 2px;
}

.entete__logo {
  padding-block: 0.5rem;
  border-radius: 9999px;
  transform: translateX(calc((1 - var(--etendu)) * var(--decalage)));
}

.entete__nav {
  display: none;
  /* Les liens n'apparaissent que sur la fin du mouvement (à partir de 88 %), quand le logo et
     les boutons ont fini de s'écarter : plus tôt, ils passeraient dessous ou dessus. */
  opacity: clamp(0, calc((var(--etendu) - 0.88) * 9), 1);
}

.entete__nav ul {
  display: flex;
  align-items: center;
  gap: 0.25rem;
}

.entete__lien {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  /* Sept liens doivent tenir dans la barre dès 1280 px : padding serré, jamais de libellé coupé en deux lignes. */
  padding: 0.625rem 0.5rem;
  border-radius: 9999px;
  font-size: 0.875rem;
  font-weight: 500;
  white-space: nowrap;
  transition: color 0.3s;
}

@media (min-width: 90rem) {
  .entete__lien {
    padding-inline: 0.875rem;
  }
}

.entete__lien:hover,
.entete__lien[aria-current] {
  color: var(--accent);
}

/* Pastille miel du lien dont la section est à l'écran. */
.entete__pastille {
  width: 0.375rem;
  height: 0.375rem;
  border-radius: 9999px;
  background-color: var(--accent);
  transform: scale(0);
  transition: transform 0.5s var(--courbe);
}

.entete__lien[aria-current] .entete__pastille {
  transform: scale(1);
}

.entete__actions {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  transform: translateX(calc((var(--etendu) - 1) * var(--decalage)));
}

.entete__cta {
  display: none;
}

.bouton-menu {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  padding: 0.875rem 1rem 0.875rem 1.25rem;
  border-radius: 9999px;
  background-color: color-mix(in srgb, var(--ampil-beurre) 10%, transparent);
  font-size: 0.875rem;
  font-weight: 600;
  line-height: 1.25rem;
  transition:
    background-color 0.3s,
    color 0.3s;
}

@media (hover: hover) {
  .bouton-menu:hover {
    background-color: var(--accent);
    color: var(--on-accent);
  }
}

.bouton-menu__traits {
  display: flex;
  flex-direction: column;
  gap: 5px;
  width: 1.25rem;
}

.bouton-menu__traits span,
.bouton-menu__croix span {
  height: 1.5px;
  border-radius: 9999px;
  background-color: currentColor;
}

.bouton-menu__croix {
  position: relative;
  width: 1.25rem;
  height: 1.25rem;
}

.bouton-menu__croix span {
  position: absolute;
  top: 50%;
  left: 0;
  width: 100%;
  rotate: 45deg;
}

.bouton-menu__croix span + span {
  rotate: -45deg;
}

.entete__connexion {
  display: none;
  margin-right: 0.75rem;
  font-size: 0.875rem;
  font-weight: 600;
  opacity: clamp(0, calc((var(--etendu) - 0.88) * 9), 1);
}

@media (min-width: 40rem) {
  .entete__cta {
    display: block;
  }

  .entete__connexion {
    display: inline;
  }
}

@media (min-width: 48rem) {
  .entete {
    padding: 1.25rem 1.25rem 0;
  }

  .entete__barre {
    padding-left: 1.75rem;
  }
}

/* À partir de 1280 px, les liens tiennent dans la barre : plus besoin du menu. */
@media (min-width: 80rem) {
  .entete {
    /* Sans bouton « Menu », la pastille n'a besoin que du logo et du bouton principal. */
    --pilule: min(28rem, var(--barre));
  }

  .entete__nav {
    display: block;
  }

  .entete__ouvrir {
    display: none;
  }
}

/* États de la barre. Repliée tant que le script n'a pas vu la page défiler ; déployée au
   défilement, quand le pointeur s'arrête sur sa partie sombre (data-survol) ou quand le clavier
   y met le focus. Le focus de la souris ne compte pas (:focus-visible, et non :focus-within) :
   cliquer sur un bouton donne le focus au bouton, la barre se déployait et le bouton s'enfuyait
   entre l'appui et le relâchement, si bien que le clic était perdu. */
@media (scripting: enabled) {
  .entete:not([data-etendu]) .entete__barre {
    --etendu: 0;
  }

  .entete[data-survol] .entete__barre,
  .entete .entete__barre:has(:focus-visible) {
    --etendu: 1;
  }

  /* Repliée, la barre garde ses liens cachés (transparents) : ils ne doivent ni se survoler ni se
     cliquer. Le pointeur tombe alors sur la partie sombre, qui déploie la barre. */
  .entete:not([data-etendu], [data-survol]) .entete__barre:not(:has(:focus-visible)) :is(.entete__nav, .entete__connexion) {
    pointer-events: none;
  }

  /* Filet de sécurité : si le script n'a pas démarré au bout de 4 s (voir entete.js),
     la barre se déploie d'elle-même et ne reste pas repliée. */
  .entete:not([data-pret]) .entete__barre {
    animation: ampil-entete-secours 0.01s linear 4s forwards;
  }
}

@keyframes ampil-entete-secours {
  to {
    --etendu: 1;
  }
}

/* --- Menu plein écran -------------------------------------------------------- */
.menu {
  position: fixed;
  inset: 0;
  width: 100%;
  max-width: none;
  height: 100dvh;
  max-height: none;
  margin: 0;
  padding: 0;
  overflow-y: auto;
  overscroll-behavior: contain;
  border: 0;
  background-color: var(--ampil-teal-900);
}

.menu::backdrop {
  background: transparent;
}

.menu__contenu {
  position: relative;
  isolation: isolate;
  display: flex;
  flex-direction: column;
  min-height: 100%;
  overflow: clip;
  padding: 1.25rem 1.25rem 2rem;
}

/* Décor placé dans l'angle bas droit, à l'écart du bouton et du texte. */
.menu__orb-1 {
  right: -30vw;
  bottom: -24vw;
  z-index: -1;
  width: 64vw;
  max-width: 26rem;
  opacity: 0.8;
}

.menu__orb-2 {
  right: 8vw;
  bottom: 42vw;
  z-index: -1;
  width: 34vw;
  max-width: 14rem;
}

.menu__haut {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
}

.menu__nav {
  flex: 1;
  margin-top: 2.5rem;
}

.menu__nav li {
  border-bottom: 1px solid var(--line);
}

.menu__lien {
  display: flex;
  align-items: baseline;
  gap: 1rem;
  padding-block: 1rem;
}

.menu__numero {
  width: 1.5rem;
  color: var(--accent);
}

.menu__texte {
  font-size: clamp(1.5rem, 7vw, 2.75rem);
  line-height: 1;
}

.menu__bas {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 1.5rem;
  margin-top: 2.5rem;
}

.menu__signature {
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
  max-width: 13rem;
  color: var(--fg-muted);
}

/* --- Pied de page ------------------------------------------------------------ */
.pied {
  position: relative;
  isolation: isolate;
  margin-top: 0.75rem;
  overflow: clip;
  border-radius: var(--rayon-panneau) var(--rayon-panneau) 0 0;
  background-color: var(--ampil-teal-900);
}

.pied__echo {
  position: absolute;
  bottom: -0.14em;
  left: 50%;
  z-index: -1;
  color: color-mix(in srgb, var(--ampil-beurre) 5%, transparent);
  font-size: 23vw;
  line-height: 0.8;
  white-space: nowrap;
  pointer-events: none;
  user-select: none;
  transform: translateX(-50%);
}

.pied__contenu {
  padding-block: 4rem 2.5rem;
}

.pied__colonnes {
  display: grid;
  gap: 3rem;
}

.pied__marque {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 1.5rem;
}

.pied__marque p {
  max-width: 20rem;
  color: var(--fg-muted);
}

.pied__titre {
  color: var(--accent);
}

.pied__liens {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
  margin-top: 1.25rem;
}

/* Icône d'un réseau social, devant son nom : couleur d'accent, comme les autres repères du pied. */
.pied__reseau {
  width: 1.25rem;
  height: 1.25rem;
  color: var(--accent);
}

/* Logo du département, au-dessus de son adresse. Il garde son jaune et ses coins : on ne le recolore pas. */
.pied__logo-departement {
  display: block;
  width: 4rem;
  height: 4rem;
  margin-top: 1.25rem;
}

.pied__logo-departement + .pied__adresse {
  margin-top: 1rem;
}

.pied__adresse {
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
  margin-top: 1.25rem;
  color: var(--fg-muted);
}

.pied__adresse span:first-child {
  color: var(--fg);
}

.pied__liens-bas {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem 1.5rem;
}

.pied__bas {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem 2rem;
  margin-top: 4rem;
  padding-top: 1.5rem;
  border-top: 1px solid var(--line);
  color: var(--fg-muted);
  font-size: 0.875rem;
}

@media (min-width: 48rem) {
  .pied__contenu {
    padding-block: 6rem 3rem;
  }

  .pied__colonnes {
    grid-template-columns: 1.5fr 1fr 1fr;
    gap: 2.5rem;
  }

  /* Avec la colonne « Nous soutenir » : deux rangées de deux, puis quatre de front à partir de 64 rem. */
  .pied__colonnes--quatre {
    grid-template-columns: 1fr 1fr;
  }

  .pied__bas {
    margin-top: 6rem;
  }
}

@media (min-width: 64rem) {
  .pied__colonnes--quatre {
    grid-template-columns: 1.5fr 1fr 1fr 1fr;
  }
}

/* ==========================================================================
   8. SECTIONS DE L'ACCUEIL
   ========================================================================== */

/* --- Gabarit commun ---------------------------------------------------------- */
.section {
  position: relative;
  padding-block: 6rem;
}

/* Grand bloc arrondi posé sur le dégradé (sections claires, appel final). */
.section--panneau {
  isolation: isolate;
  margin-inline: clamp(0.5rem, 1.6vw, 1.5rem);
  padding-block: 5rem;
  overflow: clip;
  border-radius: var(--rayon-panneau);
  background-color: var(--ampil-blanc);
  box-shadow: inset 0 0 0 1px var(--line);
}

.section__intro {
  max-width: 42rem;
  margin-top: 2rem;
}

.section__intro--etroite {
  max-width: 36rem;
}

.section__cta {
  margin-top: 3.5rem;
}

@media (min-width: 48rem) {
  .section {
    padding-block: 9rem;
  }

  .section--panneau {
    padding-block: 8rem;
  }

  .section__intro {
    margin-top: 3rem;
  }

  .section__cta {
    margin-top: 5rem;
  }
}

/* --- Hero ---------------------------------------------------------------------
   Photo en fond. En haut, un espace libre où la photo se voit franchement ;
   en bas, le titre et le texte. La première rangée de la grille réserve cet
   espace (36 % de l'écran au moins), où remonte l'écho du titre. */
.hero {
  /* Voile blanc en dégradé : absent en haut, où il n'y a pas de texte (la photo
     y garde ses teintes), il s'épaissit vite juste au-dessus du texte pour que
     le bleu canard reste lisible. Le texte commence vers 50 % de la hauteur. */
  --voile: linear-gradient(
    to bottom,
    transparent,
    color-mix(in srgb, var(--ampil-blanc) 20%, transparent) 30%,
    color-mix(in srgb, var(--ampil-blanc) 80%, transparent) 55%,
    color-mix(in srgb, var(--ampil-blanc) 90%, transparent) 75%
  );
  position: relative;
  isolation: isolate;
  display: grid;
  grid-template-rows: minmax(36svh, 1fr) auto;
  min-height: 100svh;
  padding-top: 6rem;
  overflow: clip;
}

/* La photo s'efface vers le bas dans le fond animé : pas de bord net avec la
   section suivante. Seule l'opacité compte dans un masque, pas la couleur. */
.hero .photo--fond {
  mask-image: linear-gradient(to bottom, #000 25%, transparent 100%);
}

.hero__bas {
  position: relative;
  grid-row: 2;
  display: grid;
  gap: 1.75rem;
  padding-bottom: 2rem;
}

/* Le sigle en petit, le nom complet en gros (demande de l'association, 2026-11-11).
   La taille du nom se règle sur la largeur de sa zone (unités cqi), les mots passant
   à la ligne d'eux-mêmes. Mesures en Syne ExtraBold : « Physiques » fait 8 fois le
   corps, « Alumni Mesures » 12,4 fois, « Physiques IUT Lannion » 16,4 fois.
   - téléphone : 12cqi, un mot par ligne, « Physiques » tient dès 320 px ;
   - tablette : 8cqi, trois lignes ;
   - grand écran : le titre prend toute la largeur, en deux lignes (5,9cqi).
   Plus gros, il remonterait sur le haut de la photo, où le voile blanc est trop léger
   pour le texte. */
.hero-title-zone {
  position: relative;
  container-type: inline-size;
}

.hero__titre {
  display: flex;
  flex-direction: column;
  gap: 1rem;
}

.hero__sigle {
  color: var(--accent);
}

.hero-title {
  display: block;
  font-size: 12cqi;
  line-height: 0.92;
  letter-spacing: -0.02em;
}

/* inline-block : un mot entre en glissant (transform), ce qu'un élément en ligne ne permet pas. */
.hero__mot {
  display: inline-block;
}

.hero__texte {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 1.5rem;
}

.hero__accroche {
  max-width: 28rem;
}

.hero__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 1rem 1.75rem;
}

@media (min-width: 48rem) {
  .hero {
    padding-top: 7rem;
  }
}

@media (min-width: 40rem) {
  .hero-title {
    font-size: 8cqi;
  }
}

/* Grand écran : le titre sur toute la largeur, l'accroche et les boutons en dessous, côte à côte. */
@media (min-width: 64rem) {
  .hero__bas {
    gap: 2.5rem;
    padding-bottom: 3rem;
  }

  .hero-title {
    font-size: min(5.9cqi, 7.5rem);
  }

  .hero__texte {
    flex-direction: row;
    align-items: flex-end;
    justify-content: space-between;
    gap: 4rem;
  }
}

/* --- Bandeaux défilants -------------------------------------------------------- */
.marquee {
  overflow: clip;
}

.marquee__bande {
  display: flex;
  width: max-content;
  will-change: transform;
}

.marquee__copie {
  display: flex;
  flex: none;
  align-items: center;
}

.bandeau {
  border-block: 1px solid var(--line);
}

.bandeau__element {
  display: flex;
  align-items: center;
  line-height: 1;
}

.bandeau__point {
  flex: none;
  border-radius: 9999px;
  background-color: var(--accent);
}

.bandeau--promos {
  padding-block: 1rem;
}

.bandeau--promos .bandeau__element {
  gap: 1.25rem;
  padding-right: 1.25rem;
  font-size: clamp(1.125rem, 2.6vw, 1.75rem);
}

.bandeau--promos .bandeau__point {
  width: 0.5rem;
  height: 0.5rem;
}

.bandeau--secteurs {
  margin-top: 2.5rem;
  padding-block: 1.25rem;
}

.bandeau--secteurs .bandeau__element {
  gap: 1.5rem;
  padding-right: 1.5rem;
  font-size: clamp(1.5rem, 4.2vw, 3.25rem);
}

.bandeau--secteurs .bandeau__point {
  width: 0.75rem;
  height: 0.75rem;
}

@media (min-width: 48rem) {
  .bandeau--promos {
    padding-block: 1.25rem;
  }

  .bandeau--promos .bandeau__element {
    gap: 2rem;
    padding-right: 2rem;
  }

  .bandeau--secteurs {
    margin-top: 3.5rem;
    padding-block: 1.75rem;
  }

  .bandeau--secteurs .bandeau__element {
    gap: 2.5rem;
    padding-right: 2.5rem;
  }

  .bandeau--secteurs .bandeau__point {
    width: 1rem;
    height: 1rem;
  }
}

/* --- 01 Le concept --------------------------------------------------------------- */
.piliers {
  display: grid;
  gap: 1rem;
  margin-top: 3.5rem;
}

.pilier {
  display: flex;
  flex-direction: column;
  gap: 1.25rem;
}

.pilier p {
  color: var(--fg-muted);
}

/* Un cercle de plus à chaque pilier : la communauté qui s'empile. */
.pilier__cercles {
  display: flex;
}

.pilier__cercles span {
  width: 2.25rem;
  height: 2.25rem;
  margin-left: -0.875rem;
  border-radius: 9999px;
  box-shadow: inset 0 0 0 1.5px color-mix(in srgb, var(--fg) 60%, transparent);
}

.pilier__cercles span:first-child {
  margin-left: 0;
  background-color: var(--accent);
  box-shadow: none;
}

.pilier__titre {
  font-size: clamp(1.25rem, 1.7vw, 1.5rem);
  line-height: 1.25;
}

.chiffres {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 2.5rem 1.5rem;
  margin-top: 4rem;
  padding-top: 2.5rem;
  border-top: 1px solid var(--line);
}

.chiffre {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
}

/* Le libellé vient avant le nombre dans la page (ordre logique), après à l'écran. */
.chiffre dt {
  order: 2;
  max-width: 22ch;
  color: var(--fg-muted);
  font-size: 0.875rem;
  line-height: 1.43;
}

.chiffre dd {
  order: 1;
  color: var(--accent);
  font-size: clamp(1.75rem, 7.4vw, 3.5rem);
  font-variant-numeric: tabular-nums;
  line-height: 1;
  white-space: nowrap;
}

@media (min-width: 40rem) {
  .piliers {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@media (min-width: 48rem) {
  .piliers {
    margin-top: 5rem;
  }

  .chiffres {
    margin-top: 6rem;
    padding-top: 3.5rem;
  }
}

@media (min-width: 64rem) {
  .chiffres {
    grid-template-columns: repeat(4, minmax(0, 1fr));
  }
}

@media (min-width: 80rem) {
  .piliers {
    grid-template-columns: repeat(4, minmax(0, 1fr));
  }
}

/* --- 02 Les actualités ------------------------------------------------------------ */
.actualites {
  display: grid;
  gap: 1rem;
  margin-top: 3.5rem;
}

.actualite {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 1rem;
}

.actualite__date {
  color: var(--accent);
}

.actualite__texte {
  color: var(--fg-muted);
}

/* Le lien se cale en bas de la carte : des cartes de hauteurs égales gardent leurs liens alignés. */
.actualite__lien {
  margin-top: auto;
  padding-top: 0.5rem;
}

.actualites__vide {
  margin-top: 3.5rem;
}

@media (min-width: 48rem) {
  .actualites {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    margin-top: 5rem;
  }
}

@media (min-width: 64rem) {
  .actualites {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
}

/* --- 03 La formation ---------------------------------------------------------------- */
.formation__colonnes {
  display: grid;
  gap: 3rem;
  margin-top: 2.5rem;
}

/* Un contenu large (bouton, bandeau) ne doit jamais élargir sa colonne. */
.formation__colonnes > *,
.annuaire__colonnes > *,
.retrouvailles__colonnes > *,
.adhesion > * {
  min-width: 0;
}

.formation__texte {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 2.5rem;
}

.reperes {
  display: flex;
  flex-direction: column;
  width: 100%;
}

.repere {
  display: grid;
  gap: 0.25rem 1.5rem;
  padding-block: 1.25rem;
  border-top: 1px solid var(--line);
}

.repere:last-child {
  border-bottom: 1px solid var(--line);
}

.repere dt {
  font-size: clamp(1.25rem, 2.1vw, 1.625rem);
  line-height: 1.25;
  white-space: nowrap;
}

.repere dd {
  color: var(--fg-muted);
}

.formation__photos {
  display: grid;
  grid-template-columns: repeat(6, minmax(0, 1fr));
  align-items: start;
  gap: 0.75rem;
}

.formation__photo-1 {
  grid-column: span 6;
}

/* La seconde photo mord sur la première. */
.formation__photo-2 {
  grid-column: 3 / span 4;
  margin-top: -2.5rem;
}

.parcours {
  display: grid;
  gap: 1rem;
  margin-top: 4rem;
}

.parcours__carte {
  position: relative;
  isolation: isolate;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  gap: 3rem;
  min-height: 19rem;
  padding: 1.5rem;
  overflow: hidden;
  border-radius: var(--rayon-carte);
  background-color: var(--ampil-teal);
}

.parcours__orb-1 {
  top: -44%;
  right: -12%;
  z-index: -1;
  width: 46%;
}

.parcours__orb-2 {
  top: 8%;
  right: 24%;
  z-index: -1;
  width: 20%;
}

.parcours__sigle {
  color: var(--accent);
}

.parcours__texte {
  max-width: 28rem;
  margin-top: 1rem;
  color: var(--fg-muted);
}

.debouches {
  max-width: 42rem;
  margin-top: 4rem;
}

.debouches p {
  margin-top: 1rem;
}

@media (min-width: 40rem) {
  .repere {
    grid-template-columns: 14.5rem 1fr;
    align-items: baseline;
  }
}

@media (min-width: 48rem) {
  .formation__colonnes {
    margin-top: 4rem;
  }

  .formation__photos {
    gap: 1rem;
  }

  .formation__photo-2 {
    margin-top: -4rem;
  }

  .parcours {
    margin-top: 7rem;
  }

  .parcours__carte {
    min-height: 24rem;
    padding: 2.5rem;
    border-radius: 2.5rem;
  }

  .debouches {
    margin-top: 7rem;
  }
}

@media (min-width: 64rem) {
  .formation__colonnes {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 5rem;
  }

  .parcours {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

/* --- 04 La frise des promos ------------------------------------------------------- */
.section--frise {
  overflow-x: clip;
}

.frise {
  margin-top: 1.5rem;
}

.promos-piste {
  --taille: clamp(6.5rem, 26vw, 10.5rem);
  position: relative;
  display: flex;
  align-items: center;
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scroll-snap-type: x mandatory;
  scrollbar-width: none;
  padding-block: calc(var(--taille) * 0.5);
  /* Marges qui permettent de centrer le premier et le dernier cercle. */
  padding-inline: calc(50% - var(--taille) / 2);
  cursor: grab;
  user-select: none;
}

.promos-piste::-webkit-scrollbar {
  display: none;
}

/* Aimantation coupée pendant le « voyage dans le temps » et le glissement à la souris. */
.promos-piste[data-libre] {
  scroll-snap-type: none;
}

.promos-piste[data-libre]:active {
  cursor: grabbing;
}

.promo {
  --p: 0;
  position: relative;
  flex: none;
  width: var(--taille);
  aspect-ratio: 1;
  /* Marge négative : les cercles se chevauchent. */
  margin-inline: calc(var(--taille) * -0.2);
  scroll-snap-align: center;
  color: var(--ampil-beurre);
  font-size: calc(var(--taille) * 0.18);
  cursor: pointer;
  transition: color 0.35s;
}

/* Le cercle dessiné. Il est déformé, pas la boîte .promo : le navigateur
   aimante la frise sur les boîtes déformées. Comme frise.js recalcule la
   déformation à chaque mouvement, une boîte déformée déplaçait l'aimant, qui
   redéplaçait la frise : elle oscillait sans fin entre deux années.
   --p vaut 1 au centre de la frise et 0 loin du centre : il règle la taille.
   --x écarte les voisins du cercle central (calculé dans frise.js). */
.promo__corps {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  border-radius: 9999px;
  transform: translateX(var(--x, 0px)) scale(calc(0.74 + var(--p) * 0.76));
}

/* Sans marge négative aux deux bouts, le premier et le dernier cercle
   peuvent venir exactement au centre de la frise. */
.promo:first-child {
  margin-inline-start: 0;
}

.promo:last-child {
  margin-inline-end: 0;
}

.promo .orb {
  inset: 0;
}

/* Habillage du cercle sélectionné : miel franc au centre, pour que l'année
   en bleu canard reste bien lisible. */
.promo__actif {
  background-image: radial-gradient(circle at 34% 28%, var(--ampil-miel-300), var(--ampil-miel) 52%, var(--ampil-miel-600));
  opacity: 0;
  transition: opacity 0.35s;
}

/* Graisse 700 et non 800 : en ExtraBold, les années sont si larges qu'elles
   passeraient sous le cercle voisin. */
.promo__annee {
  position: relative;
  font-family: var(--police-titre);
  font-weight: 700;
  letter-spacing: -0.025em;
}

/* Cercles clairs (verre, anneau) : année en bleu canard. */
.promo:has(.orb--glass, .orb--ring),
.promo[data-actif] {
  color: var(--ampil-teal);
}

.promo[data-actif] .promo__actif {
  opacity: 1;
}

.frise__detail {
  display: grid;
  gap: 2rem;
}

.frise__annee {
  display: flex;
  align-items: flex-end;
  gap: 1rem;
}

.frise__annee .label {
  padding-bottom: 0.25rem;
  color: var(--fg-muted);
}

.frise__annee .display {
  color: var(--accent);
  font-size: clamp(3.5rem, 15vw, 8.5rem);
  font-variant-numeric: tabular-nums;
  line-height: 0.78;
}

.frise__diplome {
  display: flex;
  flex-direction: column;
  gap: 0.375rem;
}

.frise__diplome > span:last-child {
  color: var(--fg-muted);
}

.frise__fleches {
  display: flex;
  align-items: center;
  gap: 0.75rem;
}

.promos-fleche {
  display: grid;
  place-items: center;
  width: 3.25rem;
  height: 3.25rem;
  border-radius: 9999px;
  box-shadow: inset 0 0 0 1.5px var(--line);
  transition:
    background-color 0.3s,
    color 0.3s,
    opacity 0.3s;
}

.promos-fleche:disabled {
  opacity: 0.35;
  cursor: not-allowed;
}

@media (hover: hover) {
  .promos-fleche:not(:disabled):hover {
    background-color: var(--accent);
    color: var(--on-accent);
  }
}

.frise__curseur {
  position: relative;
  margin-top: 2rem;
  padding-bottom: 1.75rem;
}

/* Curseur de la frise : un champ « range » natif, donc utilisable au clavier
   et annoncé par les lecteurs d'écran, simplement habillé aux couleurs du site. */
.promos-curseur {
  display: block;
  width: 100%;
  height: 2.75rem;
  appearance: none;
  cursor: pointer;
}

.promos-curseur::-webkit-slider-runnable-track {
  height: 2px;
  border-radius: 2px;
  background: var(--line);
}

.promos-curseur::-moz-range-track {
  height: 2px;
  border-radius: 2px;
  background: var(--line);
}

.promos-curseur::-webkit-slider-thumb {
  width: 1.5rem;
  height: 1.5rem;
  margin-top: calc(1px - 0.75rem);
  appearance: none;
  border: none;
  border-radius: 9999px;
  background: var(--accent);
  box-shadow: 0 0 0 7px color-mix(in srgb, var(--accent) 20%, transparent);
}

.promos-curseur::-moz-range-thumb {
  width: 1.5rem;
  height: 1.5rem;
  border: none;
  border-radius: 9999px;
  background: var(--accent);
  box-shadow: 0 0 0 7px color-mix(in srgb, var(--accent) 20%, transparent);
}

.promos-curseur:focus-visible {
  outline: none;
}

.promos-curseur:focus-visible::-webkit-slider-thumb {
  box-shadow:
    0 0 0 3px var(--ampil-teal),
    0 0 0 5px var(--focus);
}

.promos-curseur:focus-visible::-moz-range-thumb {
  box-shadow:
    0 0 0 3px var(--ampil-teal),
    0 0 0 5px var(--focus);
}

/* Repères des décennies sous le curseur. Le pouce mesure 1,5rem : on décale
   les repères pour qu'ils tombent pile sous sa position réelle. */
.promos-decennies {
  position: absolute;
  inset-inline: 0.75rem;
  bottom: 0;
  height: 1.25rem;
}

.promos-decennies span {
  position: absolute;
  top: 0;
  color: var(--fg-muted);
  font-size: 0.6875rem;
  font-weight: 600;
  letter-spacing: 0.12em;
  transform: translateX(-50%);
}

.frise__cta {
  margin-top: 2rem;
}

@media (min-width: 48rem) {
  .frise {
    margin-top: 2.5rem;
  }

  .frise__detail {
    grid-template-columns: auto minmax(0, 1fr) auto;
    align-items: end;
    gap: 3rem;
  }

  .frise__diplome,
  .frise__fleches {
    padding-bottom: 0.25rem;
  }

  .frise__curseur {
    margin-top: 3rem;
  }
}

/* --- 05 L'annuaire -------------------------------------------------------------------- */
.annuaire__colonnes {
  display: grid;
  gap: 3.5rem;
}

.annuaire__texte {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
}

.annuaire__intro {
  max-width: 36rem;
  margin-top: 2rem;
}

.annuaire__texte .liste-coches {
  margin-top: 2rem;
}

.annuaire__cta {
  margin-top: 2.5rem;
}

/* Maquette de l'annuaire : des formes vides, aucune donnée réelle. */
.apercu {
  position: relative;
  isolation: isolate;
  padding: 1.25rem;
  overflow: hidden;
  border-radius: var(--rayon-carte);
  background-color: var(--ampil-teal);
}

.apercu__recherche {
  padding: 0.875rem 1.25rem;
  border: 1px solid var(--line);
  border-radius: 9999px;
  color: var(--fg-muted);
  font-size: 0.875rem;
  line-height: 1.43;
}

.apercu__promos {
  display: flex;
  gap: 0.5rem;
  margin-top: 1rem;
  overflow: hidden;
}

.apercu__promos li {
  flex: none;
  padding: 0.5rem 1rem;
  border: 1px solid var(--line);
  border-radius: 9999px;
  color: var(--fg-muted);
  font-size: 0.75rem;
  font-weight: 600;
  line-height: 1rem;
}

.apercu__promos .est-active {
  border-color: transparent;
  background-color: var(--accent);
  color: var(--on-accent);
}

.apercu__lignes {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
  margin-top: 1.5rem;
}

.apercu__lignes li {
  display: flex;
  align-items: center;
  gap: 1rem;
  padding: 1rem;
  border-radius: 1rem;
  background-color: color-mix(in srgb, var(--ampil-teal-600) 70%, transparent);
}

.apercu__pastille {
  position: relative;
  flex: none;
  width: 2.75rem;
  height: 2.75rem;
}

.apercu__pastille .orb {
  inset: 0;
}

.apercu__barres {
  display: flex;
  flex: 1;
  flex-direction: column;
  gap: 0.625rem;
}

.apercu__barres span {
  height: 0.625rem;
  border-radius: 9999px;
  background-color: color-mix(in srgb, var(--ampil-beurre) 35%, transparent);
}

.apercu__barres span + span {
  height: 0.5rem;
  background-color: color-mix(in srgb, var(--ampil-beurre) 15%, transparent);
}

.apercu__voile {
  position: absolute;
  inset: auto 0 0;
  height: 62%;
  background-image: linear-gradient(to top, var(--ampil-teal), color-mix(in srgb, var(--ampil-teal) 90%, transparent) 50%, transparent);
}

.apercu__verrou {
  position: absolute;
  inset: auto 0 1.75rem;
  display: flex;
  align-items: center;
  gap: 0.625rem;
  width: fit-content;
  margin-inline: auto;
  padding: 0.75rem 1.25rem;
  border-radius: 9999px;
  background-color: var(--accent);
  color: var(--on-accent);
  font-size: 0.875rem;
  font-weight: 600;
  line-height: 1.43;
}

@media (min-width: 48rem) {
  .apercu {
    padding: 2rem;
    border-radius: 2.5rem;
  }

  .apercu__verrou {
    bottom: 2.5rem;
  }
}

@media (min-width: 64rem) {
  .annuaire__colonnes {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    align-items: center;
    gap: 5rem;
  }
}

/* --- 06 Les offres ---------------------------------------------------------------------- */
.offres {
  margin-top: 3rem;
  border-top: 1px solid var(--line);
}

.offres li {
  isolation: isolate;
  border-bottom: 1px solid var(--line);
}

/* Ligne d'offre : un aplat miel monte au survol. */
.offre {
  position: relative;
  display: grid;
  gap: 0.875rem;
  padding-block: 1.5rem;
  outline-offset: 0.5rem;
}

.offre,
.offre * {
  transition: color 0.4s var(--courbe);
}

.offre::before {
  content: "";
  position: absolute;
  inset: 0 -1rem;
  z-index: -1;
  border-radius: 1.5rem;
  background-color: var(--ampil-miel);
  transform: scaleY(0);
  transform-origin: 50% 100%;
  transition: transform 0.5s var(--courbe);
}

.offre__type {
  display: flex;
  align-items: center;
  gap: 0.75rem;
}

.offre__genre {
  color: var(--accent);
}

.offre__exemple {
  padding: 0.25rem 0.625rem;
  border: 1px solid currentColor;
  border-radius: 9999px;
  color: var(--fg-muted);
  font-size: 0.5625rem;
}

.offre__corps {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

.offre__infos {
  color: var(--fg-muted);
  font-size: 0.875rem;
  line-height: 1.43;
}

.offre__voir {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  font-size: 0.875rem;
  font-weight: 600;
}

.offre__fleche {
  transition: transform 0.45s var(--courbe);
}

/* Au survol (ou au focus clavier), la ligne passe en « thème miel » : en
   redéfinissant les couleurs de rôle, tout son texte devient bleu canard. */
.offre:focus-visible {
  --fg: var(--ampil-teal);
  --fg-muted: var(--ampil-teal);
  --accent: var(--ampil-teal);
  --focus: var(--ampil-miel);
  color: var(--fg);
}

.offre:focus-visible::before {
  transform: scaleY(1);
}

@media (hover: hover) {
  .offre:hover {
    --fg: var(--ampil-teal);
    --fg-muted: var(--ampil-teal);
    --accent: var(--ampil-teal);
    color: var(--fg);
  }

  .offre:hover::before {
    transform: scaleY(1);
  }

  .offre:hover .offre__fleche {
    transform: translate(0.2rem, -0.2rem);
  }
}

.offres__vide {
  margin-top: 3rem;
}

.offres__cta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 1rem 1.5rem;
  margin-top: 3rem;
}

.offres__cta p {
  max-width: 24rem;
  color: var(--fg-muted);
}

@media (min-width: 48rem) {
  .offres,
  .offres__cta {
    margin-top: 4rem;
  }

  .offre {
    grid-template-columns: 13.5rem minmax(0, 1fr) auto;
    align-items: center;
    gap: 2rem;
    padding-block: 2rem;
  }

  .offre::before {
    inset: 0 -1.5rem;
  }
}

/* --- 07 Les retrouvailles ------------------------------------------------------------------ */
.retrouvailles__colonnes {
  display: grid;
  gap: 3rem;
  margin-top: 2.5rem;
}

.retrouvailles__sous-titre {
  margin-top: 3rem;
  color: var(--fg-muted);
}

/* Éditions passées : trois cercles qui se chevauchent. */
.editions {
  display: flex;
  margin-top: 1.25rem;
}

.editions li {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.375rem;
  width: 34%;
  max-width: 10rem;
  aspect-ratio: 1;
  border-radius: 9999px;
  background-color: color-mix(in srgb, var(--ampil-beurre) 70%, transparent);
  box-shadow: inset 0 0 0 1.5px color-mix(in srgb, var(--fg) 45%, transparent);
  text-align: center;
}

.editions li + li {
  margin-left: -4%;
}

.editions .display {
  font-size: clamp(1.125rem, 5vw, 1.75rem);
  line-height: 1;
}

.editions li > span:last-child {
  color: var(--fg-muted);
  font-size: 0.75rem;
  font-weight: 600;
  line-height: 1rem;
}

.evenements {
  display: flex;
  flex-direction: column;
  gap: 1rem;
}

.evenement {
  position: relative;
  isolation: isolate;
  padding: 1.5rem;
  overflow: hidden;
  border-radius: var(--rayon-carte);
  background-color: var(--ampil-teal);
}

.evenement__orb-1 {
  top: -5rem;
  right: -14%;
  z-index: -1;
  width: 40%;
}

.evenement__orb-2 {
  top: 14%;
  right: 6%;
  z-index: -1;
  display: none;
  width: 16%;
}

.evenement__etat {
  color: var(--accent);
}

.evenement__date {
  margin-top: 2rem;
}

/* La date en grand, façon affiche. */
.evenement__affiche {
  display: flex;
  align-items: flex-end;
  gap: 1rem;
}

.evenement__jour {
  font-size: clamp(4.5rem, 17vw, 8rem);
  font-variant-numeric: tabular-nums;
  line-height: 0.76;
}

.evenement__mois {
  display: flex;
  flex-direction: column;
  padding-bottom: 0.25rem;
}

.evenement__mois > span:last-child {
  color: var(--fg-muted);
  font-size: 0.875rem;
  line-height: 1.43;
}

.evenement__titre {
  margin-top: 2.5rem;
}

.evenement__texte {
  max-width: 28rem;
  margin-top: 0.75rem;
  color: var(--fg-muted);
}

.evenement__lieu {
  margin-top: 0.5rem;
  font-size: 0.875rem;
  font-weight: 600;
}

.evenement__cta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.75rem 1.25rem;
  margin-top: 2rem;
}

.evenement__cta p {
  color: var(--fg-muted);
  font-size: 0.875rem;
}

.retrouvailles__photos {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 0.75rem;
  margin-top: 3.5rem;
}

.retrouvailles__photos > :first-child {
  grid-column: span 2;
}

@media (min-width: 48rem) {
  .retrouvailles__colonnes {
    margin-top: 4rem;
  }

  .evenement {
    padding: 2.5rem;
    border-radius: 2.5rem;
  }

  .evenement__orb-1 {
    top: -11rem;
  }

  .evenement__orb-2 {
    display: block;
  }

  .retrouvailles__photos {
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 1rem;
    margin-top: 6rem;
  }

  .retrouvailles__photos > :first-child {
    grid-column: auto;
  }

  .retrouvailles__photos .photo--bandeau {
    aspect-ratio: 4 / 5;
  }
}

@media (min-width: 64rem) {
  .retrouvailles__colonnes {
    grid-template-columns: 1fr 1.05fr;
    gap: 5rem;
  }
}

/* --- Appel final (photo de la soirée sous un voile sombre) ------------------------------- */
/* Le fond sombre tient la place tant que la photo n'est pas chargée : le texte beurre reste lisible. */
.appel {
  /* Voile du bleu canard le plus sombre, presque noir. À 72 %, le texte reste
     au-dessus de 7:1 devant la photo (mesuré sur mobile et grand écran). */
  --voile: color-mix(in srgb, var(--ampil-teal-900) 72%, transparent);
  margin-top: 0.75rem;
  padding-block: 6rem;
  background-color: var(--ampil-teal-900);
  text-align: center;
}

/* Les cercles pleins restent dans les angles, hors du texte ; seuls les
   anneaux, simples traits, passent derrière. */
.appel__orb-1 {
  top: -4rem;
  left: -12%;
  z-index: -1;
  width: 38%;
  max-width: 20rem;
}

.appel__orb-2 {
  top: 5%;
  right: 10%;
  z-index: -1;
  width: 22%;
  max-width: 13rem;
}

.appel__orb-3 {
  right: -12%;
  bottom: -7rem;
  z-index: -1;
  width: 46%;
  max-width: 24rem;
}

.appel__orb-4 {
  bottom: 4%;
  left: 8%;
  z-index: -1;
  width: 16%;
  max-width: 9rem;
}

.appel__contenu {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2rem;
}

.appel__titre {
  font-size: clamp(2.25rem, 9.6vw, 7.5rem);
  line-height: 0.94;
}

.appel__texte {
  max-width: 36rem;
}

@media (min-width: 48rem) {
  .appel {
    padding-block: 10rem;
  }

  .appel__orb-1 {
    top: -7rem;
    left: -4%;
  }

  .appel__orb-2 {
    top: 38%;
    right: auto;
    left: 10%;
  }

  .appel__orb-3 {
    right: -4%;
    bottom: -10rem;
  }

  .appel__orb-4 {
    right: 14%;
    bottom: 26%;
    left: auto;
  }
}

/* ==========================================================================
   9. AUTRES PAGES
   ========================================================================== */

.page {
  position: relative;
  isolation: isolate;
  padding-block: 9rem 5rem;
  overflow-x: clip;
}

/* Décor dans l'angle haut droit, à l'écart du titre. */
.page__orb-1 {
  top: 5rem;
  right: -14%;
  z-index: -1;
  width: 34%;
  max-width: 24rem;
}

.page__orb-2 {
  top: 11rem;
  right: -4%;
  z-index: -1;
  width: 20%;
  max-width: 10rem;
}

.page__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 1rem;
  margin-top: 2.5rem;
}

@media (min-width: 48rem) {
  .page {
    padding-block: 13rem 7rem;
  }

  /* Un grand titre en Syne ExtraBold file jusqu'à 80 % de la largeur : le cercle plein ne peut
     donc pas se tenir à sa hauteur. Il dépasse de l'angle et s'arrête à 14 rem du haut, au-dessus
     du titre (qui commence vers 15,5 rem), quelle que soit la largeur de l'écran. */
  .page__orb-1 {
    top: -10rem;
    right: -6%;
  }

  .page__orb-2 {
    top: 27rem;
    right: 10%;
  }
}

/* --- Devenir membre ------------------------------------------------------------ */
.adhesion {
  display: grid;
  gap: 1rem;
  margin-top: 4rem;
}

.adhesion .liste-coches {
  margin-top: 1.5rem;
}

.etapes {
  display: flex;
  flex-direction: column;
  gap: 1rem;
}

.etape {
  display: grid;
  gap: 0.75rem 2rem;
}

.etape__numero {
  color: var(--accent);
}

.etape p {
  margin-top: 0.5rem;
  color: var(--fg-muted);
}

.adhesion__engagement {
  max-width: 42rem;
  margin-top: 2.5rem;
  color: var(--fg-muted);
}

/* Le formulaire d'inscription passe en premier sur mobile, les explications ensuite. */
.adhesion__infos {
  display: flex;
  flex-direction: column;
  gap: 1rem;
}

.carte--formulaire {
  max-width: 32rem;
  margin-top: 3rem;
}

@media (min-width: 40rem) {
  .etape {
    grid-template-columns: 5.5rem 1fr;
    align-items: baseline;
  }
}

@media (min-width: 48rem) {
  .adhesion {
    margin-top: 6rem;
  }
}

@media (min-width: 64rem) {
  .adhesion {
    grid-template-columns: 1fr 1.3fr;
    align-items: start;
  }

  .adhesion--formulaire {
    grid-template-columns: 1.1fr 1fr;
  }
}

/* --- Installer l'application ----------------------------------------------------- */
.plateformes {
  display: grid;
  gap: 1rem;
  margin-top: 3rem;
}

.plateforme {
  display: flex;
  flex-direction: column;
  gap: 1rem;
}

.plateforme__entete {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem 1rem;
}

.plateforme__tag {
  padding: 0.125rem 0.75rem;
  border-radius: 9999px;
  background-color: var(--accent);
  color: var(--on-accent);
}

.plateforme__navigateur,
.plateforme__note {
  color: var(--fg-muted);
  font-size: 0.875rem;
}

/* L'appareil détecté passe en premier et prend un contour franc. */
.plateforme[data-detecte] {
  order: -1;
  box-shadow: 0 0 0 2px var(--ampil-teal);
}

.installation__etapes {
  display: flex;
  flex-direction: column;
  gap: 1.25rem;
}

.installation__etape {
  display: grid;
  grid-template-columns: 3rem 1fr;
  gap: 1rem;
  align-items: start;
}

.installation__icone {
  display: grid;
  place-items: center;
  width: 3rem;
  height: 3rem;
  border-radius: 9999px;
  background-color: var(--ampil-beurre);
  box-shadow: inset 0 0 0 1.5px var(--ampil-teal-300);
  color: var(--ampil-teal);
}

.installation__icone .icone {
  width: 1.5rem;
  height: 1.5rem;
}

.installation__titre {
  font-size: 1rem;
  font-weight: 700;
  line-height: 1.35;
}

.installation__numero {
  color: var(--fg-muted);
}

.installation__etape p {
  margin-top: 0.25rem;
  color: var(--fg-muted);
  font-size: 0.9375rem;
}

.installation__deja {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  max-width: 42rem;
  margin-top: 2rem;
  padding: 0.75rem 1rem;
  border-radius: 1rem;
  background-color: var(--ampil-beurre);
  box-shadow: inset 0 0 0 1px var(--line);
  font-weight: 600;
}

.installation__suite {
  margin-top: 1rem;
}

.installation__suite > p {
  max-width: 40rem;
  margin-top: 0.75rem;
  color: var(--fg-muted);
}

@media (min-width: 64rem) {
  .plateformes {
    grid-template-columns: repeat(3, minmax(0, 1fr));
    align-items: start;
  }
}

/* --- Mentions légales ------------------------------------------------------------ */
.mentions {
  margin-top: 3rem;
}

.mention {
  display: grid;
  gap: 1rem;
  padding-block: 2rem;
  border-top: 1px solid var(--line);
}

/* Titre volontairement petit : en Syne ExtraBold, « intellectuelle » doit tenir dans la colonne. */
.mention h2 {
  font-size: 1.125rem;
  line-height: 1.375;
}

.mention > div {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
  max-width: 42rem;
  color: var(--fg-muted);
}

/* Rappel bien visible d'une information légale manquante. */
.a-completer {
  padding: 0.125rem 0.625rem;
  border-radius: 9999px;
  background-color: var(--accent);
  color: var(--on-accent);
  font-size: 0.875rem;
  font-weight: 600;
}

.mentions__date {
  padding-top: 2rem;
  border-top: 1px solid var(--line);
  color: var(--fg-muted);
  font-size: 0.875rem;
}

.page--legale .page__actions {
  margin-top: 3rem;
}

@media (min-width: 48rem) {
  .mentions {
    margin-top: 5rem;
  }

  .mention {
    grid-template-columns: 17rem 1fr;
    gap: 2.5rem;
    padding-block: 2.5rem;
  }
}

/* --- Page introuvable ---------------------------------------------------------------- */
.page--introuvable {
  display: flex;
  align-items: center;
  min-height: 80svh;
}

.introuvable {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 2rem;
}

.introuvable__code {
  color: var(--accent);
}

.introuvable .chapo {
  max-width: 28rem;
}

/* ==========================================================================
   10. ESPACE MEMBRE
   Version sobre de l'identité, claire ou sombre selon le réglage du système
   (prefers-color-scheme). Deux panneaux comme dans une messagerie : la liste
   des discussions et la conversation. Sur mobile, un seul à la fois (la classe
   app__coque--fil indique qu'une discussion est ouverte).

   Toutes les couleurs de cette partie passent par les variables --app-* ci-dessous :
   le mode sombre n'est qu'un second jeu de valeurs, jamais une règle de plus.
   Il n'utilise que les variantes du bleu canard, du miel et du beurre.
   ========================================================================== */

.html-app {
  /* Les contrôles natifs (cases, barres de défilement) suivent le système. */
  color-scheme: light dark;

  /* Clair */
  --app-fond: var(--ampil-blanc); /* liste, barres, panneaux */
  --app-fond-conversation: var(--ampil-beurre-50);
  --app-fond-page: var(--ampil-beurre-50); /* profil, paramètres */
  --app-fond-doux: var(--ampil-beurre-50); /* recherche, puces, résultats */
  --app-fond-actif: var(--ampil-beurre); /* discussion ouverte, avatar de personne */
  --app-survol: var(--ampil-beurre-50);
  --app-carte: var(--ampil-blanc);
  --app-champ: var(--ampil-blanc);
  --app-contour: var(--ampil-teal-300); /* au moins 3:1, comme l'exige WCAG 1.4.11 */
  --app-bulle: var(--ampil-blanc);
  --app-bulle-bord: var(--line);
  --app-bulle-moi: var(--ampil-teal);
  --app-bulle-moi-texte: var(--ampil-beurre);
  --app-avatar-promo: var(--ampil-teal);
  --app-avatar-promo-texte: var(--ampil-beurre);
  --app-avatar-personne: var(--ampil-beurre);
  --app-avatar-personne-texte: var(--ampil-teal);
  --app-pastille: var(--ampil-teal);
  --app-pastille-texte: var(--ampil-miel);
  --app-puce: var(--ampil-miel); /* filtre et onglet actifs */
  --app-puce-texte: var(--ampil-teal);
  --app-rideau: var(--ampil-teal-900); /* écran d'accueil : sombre dans les deux modes, comme la barre du site */

  background-color: var(--app-fond);
}

@media (prefers-color-scheme: dark) {
  .html-app {
    /* Les mêmes rôles que le thème « dark » du site : texte beurre, accent miel. */
    --fg: var(--ampil-beurre);
    --fg-muted: color-mix(in srgb, var(--ampil-beurre) 78%, transparent);
    --line: color-mix(in srgb, var(--ampil-beurre) 16%, transparent);
    --accent: var(--ampil-miel);
    --on-accent: var(--ampil-teal);
    --surface: var(--ampil-teal-800);
    --focus: var(--ampil-miel);
    --btn-survol: var(--ampil-beurre);

    --app-fond: var(--ampil-teal-900);
    --app-fond-conversation: var(--ampil-teal-800);
    --app-fond-page: var(--ampil-teal-900);
    --app-fond-doux: var(--ampil-teal-800);
    --app-fond-actif: var(--ampil-teal-700);
    --app-survol: var(--ampil-teal-800);
    --app-carte: var(--ampil-teal-800);
    --app-champ: var(--ampil-teal-900);
    --app-contour: var(--ampil-teal-300);
    --app-bulle: var(--ampil-teal-700);
    --app-bulle-bord: transparent;
    --app-bulle-moi: var(--ampil-teal-500);
    --app-avatar-promo: var(--ampil-teal-500);
    --app-avatar-personne: var(--ampil-teal-700);
    --app-avatar-personne-texte: var(--ampil-beurre);
    --app-pastille: var(--ampil-miel);
    --app-pastille-texte: var(--ampil-teal);
  }
}

.app {
  --hauteur-barre: 3.75rem;
  --hauteur-recherche: 4.25rem;
  /* Pastille flottante (environ 4,1 rem) + sa marge de 0,75 rem sous elle. */
  --hauteur-onglets: calc(5rem + env(safe-area-inset-bottom));
  background-color: var(--app-fond);
  color: var(--fg);
}

/* L'application a ses propres transitions entre pages (partie 11) : le contenu glisse de côté,
   et la gélule du menu va d'un onglet à l'autre. Le cercle du site vitrine n'y a pas sa place. */
.app main {
  view-transition-name: contenu-app;
}

.app .onglets {
  view-transition-name: onglets;
}

.app .onglet--actif {
  view-transition-name: onglet-actif;
}

.app__coque {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  height: 100vh;
  height: 100dvh;
  overflow: hidden;
}

.app__liste,
.app__fil {
  display: flex;
  flex-direction: column;
  min-height: 0;
  min-width: 0;
}

/* Sur téléphone, la pastille d'onglets flotte sous la conversation : on lui réserve sa place. */
.app__fil {
  padding-bottom: var(--reserve-onglets, 0px);
}

.app__coque--fil .app__liste,
.app__coque:not(.app__coque--fil) .app__fil {
  display: none;
}

@media (min-width: 48rem) {
  .app__coque {
    grid-template-columns: minmax(19rem, 24rem) minmax(0, 1fr);
  }

  .app__coque--fil .app__liste,
  .app__coque:not(.app__coque--fil) .app__fil {
    display: flex;
  }

  .app__liste {
    border-right: 1px solid var(--line);
  }
}

/* Page d'un canal (Offres, Échanges) : le fil seul, sans liste de discussions. */
@media (min-width: 48rem) {
  .app__coque.app__coque--canal {
    grid-template-columns: minmax(0, 1fr);
  }
}

/* --- Liste des discussions ------------------------------------------------- */
.liste {
  background-color: var(--app-fond);
}

.liste__defilement {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  overscroll-behavior: contain;
}

/* Barre du haut : le logo, le titre réduit (il apparaît quand le grand titre a défilé), le « + ». */
.liste__barre {
  position: sticky;
  top: 0;
  z-index: 6;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  min-height: var(--hauteur-barre);
  padding: 0.5rem 1.25rem;
  background-color: var(--app-fond);
}

.liste__logo .logo {
  height: 1.5rem;
  color: var(--fg);
  transition: opacity 0.2s;
}

/* Quand le titre réduit apparaît (au centre de la barre), le logo lui laisse la place. */
.liste--titre-reduit .liste__logo .logo {
  opacity: 0;
}

.liste__titre-compact {
  position: absolute;
  left: 50%;
  font-family: var(--police-titre);
  font-size: 1rem;
  font-weight: 800;
  opacity: 0;
  transform: translateX(-50%) translateY(0.375rem);
  transition:
    opacity 0.2s,
    transform 0.25s var(--courbe);
  pointer-events: none;
}

.liste--titre-reduit .liste__titre-compact {
  opacity: 1;
  transform: translateX(-50%);
}

/* Grand titre, comme sur iPhone : il défile avec la liste puis cède la place au titre réduit. */
.liste__titre {
  padding: 0.25rem 1.25rem 0.875rem;
  font-size: clamp(1.75rem, 9vw, 2.25rem);
  line-height: 1.1;
}

.app__actions {
  display: flex;
  align-items: center;
  gap: 0.5rem;
}

/* Bouton rond « + » : nouvelle discussion. */
.app__icone {
  display: grid;
  flex: none;
  place-items: center;
  width: 2.5rem;
  height: 2.5rem;
  border-radius: 9999px;
  background-color: var(--accent);
  color: var(--on-accent);
}

.app__icone .icone {
  width: 1.25rem;
  height: 1.25rem;
}

/* Recherche : un champ arrondi avec sa loupe ; « Annuler » apparaît quand on y écrit. */
.liste__recherche {
  display: flex;
  align-items: center;
  gap: 0.875rem;
  padding: 0 1.25rem 0.75rem;
}

.recherche__champ {
  position: relative;
  flex: 1;
  min-width: 0;
}

.recherche__icone {
  position: absolute;
  top: 50%;
  left: 1rem;
  width: 1.125rem;
  height: 1.125rem;
  color: var(--fg-muted);
  transform: translateY(-50%);
  pointer-events: none;
}

.app__recherche-saisie {
  width: 100%;
  min-height: 2.75rem;
  padding: 0.6rem 1rem 0.6rem 2.75rem;
  border-radius: 9999px;
  background-color: var(--app-fond-doux);
  box-shadow: inset 0 0 0 1.5px var(--app-contour);
  color: var(--fg);
  font: inherit;
  font-size: 1rem;
  text-overflow: ellipsis;
}

.app__recherche-saisie::placeholder {
  color: var(--fg-muted);
  opacity: 1;
}

.app__recherche-saisie:focus-visible {
  outline: 2px solid var(--focus);
  outline-offset: 2px;
  box-shadow: none;
}

.recherche__annuler {
  flex: none;
  color: var(--accent);
  font-weight: 650;
}

/* La croix d'effacement du navigateur est bleue par défaut : on la redessine aux couleurs de la charte. */
.app__recherche-saisie::-webkit-search-cancel-button {
  -webkit-appearance: none;
  appearance: none;
  width: 1rem;
  height: 1rem;
  background-color: var(--fg);
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20' fill='none' stroke='black' stroke-width='2' stroke-linecap='round'%3E%3Cpath d='M5 5l10 10M15 5L5 15'/%3E%3C/svg%3E") center / contain no-repeat;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20' fill='none' stroke='black' stroke-width='2' stroke-linecap='round'%3E%3Cpath d='M5 5l10 10M15 5L5 15'/%3E%3C/svg%3E") center / contain no-repeat;
  cursor: pointer;
}

/* En recherche : la barre et le grand titre s'effacent, le champ prend la place en haut.
   Le titre n'est que masqué à la vue : la page garde son titre de niveau 1 pour les lecteurs d'écran. */
.liste--recherche .liste__barre,
.liste--recherche .bandeau {
  display: none;
}

.liste--recherche .liste__titre {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
}

.liste--recherche .liste__recherche {
  position: sticky;
  top: 0;
  z-index: 6;
  padding-top: 0.75rem;
  background-color: var(--app-fond);
}

/* Filtres : des puces qui défilent de côté, collées sous la barre. */
.filtres {
  position: sticky;
  top: var(--hauteur-barre);
  z-index: 5;
  display: flex;
  gap: 0.5rem;
  padding: 0.25rem 1.25rem 0.75rem;
  overflow-x: auto;
  background-color: var(--app-fond);
  scrollbar-width: none;
}

.filtres::-webkit-scrollbar {
  display: none;
}

.liste--recherche .filtres {
  top: var(--hauteur-recherche);
}

.filtre {
  display: inline-flex;
  flex: none;
  align-items: center;
  gap: 0.4rem;
  padding: 0.5rem 0.9rem;
  border-radius: 9999px;
  background-color: var(--app-fond-doux);
  box-shadow: inset 0 0 0 1px var(--line);
  font-size: 0.9375rem;
  font-weight: 600;
  transition:
    background-color 0.2s,
    color 0.2s;
}

.filtre[aria-pressed="true"] {
  background-color: var(--app-puce);
  box-shadow: none;
  color: var(--app-puce-texte);
  font-weight: 700;
}

.filtre__nombre {
  font-variant-numeric: tabular-nums;
}

.liste__aucune {
  padding: 2rem 1.25rem;
  color: var(--fg-muted);
  text-align: center;
}

/* Résultats « membres » de la recherche, au-dessus des discussions filtrées. */
.app__resultats {
  border-bottom: 1px solid var(--line);
  background-color: var(--app-fond-doux);
}

.app__resultats-titre {
  padding: 0.875rem 1.25rem 0.25rem;
  color: var(--fg-muted);
}

.discussion {
  position: relative;
  display: flex;
  align-items: center;
  gap: 0.875rem;
  padding: 0.875rem 1.25rem;
  border-bottom: 1px solid var(--line);
  transition: background-color 0.25s;
}

.discussion--active {
  background-color: var(--app-fond-actif);
}

/* Trait de repère à gauche de la discussion ouverte (le fond seul ne suffirait pas aux yeux fatigués). */
.discussion--active::before {
  content: "";
  position: absolute;
  inset: 0 auto 0 0;
  width: 0.25rem;
  background-color: var(--accent);
}

@media (hover: hover) {
  .discussion:not(.discussion--active):hover {
    background-color: var(--app-survol);
  }
}

/* Pastille ronde, le motif de la marque : bleu canard pour une promo, miel pour le groupe
   général, une teinte douce cerclée pour une personne (ses initiales). */
.avatar {
  display: grid;
  flex: none;
  place-items: center;
  width: 3rem;
  height: 3rem;
  border-radius: 9999px;
  font-size: 0.8125rem;
  font-weight: 700;
  letter-spacing: 0;
}

.avatar--promo {
  background-color: var(--app-avatar-promo);
  color: var(--app-avatar-promo-texte);
}

.avatar--general {
  background-color: var(--ampil-miel);
  color: var(--ampil-teal);
}

/* Un canal (offres, échanges) : la pastille de promo, avec une icône à la place de l'année. */
.avatar--canal {
  background-color: var(--app-avatar-promo);
  color: var(--app-avatar-promo-texte);
}

.avatar__icone {
  width: 1.5rem;
  height: 1.5rem;
}

.avatar--personne {
  background-color: var(--app-avatar-personne);
  box-shadow: inset 0 0 0 1.5px var(--app-contour);
  color: var(--app-avatar-personne-texte);
}

/* Photo de profil ou de groupe : elle remplit la pastille. Le fond se voit le temps du chargement. */
.avatar--photo {
  overflow: hidden;
  background-color: var(--app-fond-actif);
}

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

.discussion__corps {
  display: flex;
  flex: 1;
  flex-direction: column;
  gap: 0.125rem;
  min-width: 0;
}

.discussion__ligne {
  display: flex;
  align-items: center;
  gap: 0.5rem;
}

.discussion__nom {
  min-width: 0;
  overflow: hidden;
  font-weight: 700;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.discussion__etoile {
  display: flex;
  flex: none;
}

.discussion__etoile .icone {
  fill: var(--ampil-miel);
  color: var(--fg-muted);
}

.discussion__heure {
  flex: none;
  margin-left: auto;
  color: var(--fg-muted);
  font-size: 0.75rem;
}

.discussion__apercu {
  min-width: 0;
  flex: 1;
  overflow: hidden;
  color: var(--fg-muted);
  font-size: 0.875rem;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.discussion__non-lus {
  display: grid;
  flex: none;
  place-items: center;
  min-width: 1.5rem;
  height: 1.5rem;
  padding-inline: 0.4rem;
  border-radius: 9999px;
  background-color: var(--app-pastille);
  color: var(--app-pastille-texte);
  font-size: 0.75rem;
  font-weight: 700;
}

/* --- Membres (liste du panneau et résultats de recherche) -------------------- */
.membres {
  display: flex;
  flex-direction: column;
}

.membre__ligne {
  display: flex;
  align-items: center;
  gap: 0.875rem;
  width: 100%;
  padding: 0.75rem 1.25rem;
  border-bottom: 1px solid var(--line);
  text-align: left;
}

button.membre__ligne:disabled {
  opacity: 0.6;
}

@media (hover: hover) {
  button.membre__ligne:hover:not(:disabled) {
    background-color: var(--app-survol);
  }
}

.membre__texte {
  display: flex;
  flex: 1;
  flex-direction: column;
  min-width: 0;
}

.membre__nom {
  overflow: hidden;
  font-weight: 700;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.membre__promo {
  color: var(--fg-muted);
  font-size: 0.8125rem;
}

.membre__moi {
  flex: none;
  padding: 0.125rem 0.625rem;
  border-radius: 9999px;
  background-color: var(--app-fond-actif);
  font-size: 0.75rem;
  font-weight: 600;
}

/* --- Panneau latéral : membres d'un groupe, nouvelle discussion --------------- */
.panneau {
  position: fixed;
  inset: 0 0 0 auto;
  width: min(26rem, 100%);
  max-width: 100%;
  height: 100vh;
  height: 100dvh;
  max-height: none;
  margin: 0;
  padding: 0;
  border: 0;
  background-color: var(--app-fond);
  box-shadow: -1px 0 0 var(--line), -1.5rem 0 3rem rgb(0 21 26 / 0.08);
  color: var(--fg);
}

.panneau[open] {
  display: flex;
  flex-direction: column;
}

/* Voile clair en mode clair (un voile bleu canard posé sur le miel et le beurre tirerait vers le
   vert-gris), voile sombre en mode sombre. Les variables ne s'appliquent pas toujours à ::backdrop. */
.panneau::backdrop {
  background-color: rgb(255 255 255 / 0.7);
}

@media (prefers-color-scheme: dark) {
  .panneau::backdrop {
    background-color: rgb(0 21 26 / 0.72);
  }

  .panneau {
    box-shadow: -1px 0 0 var(--line);
  }
}

@media (prefers-reduced-motion: no-preference) {
  .panneau[open] {
    animation: panneau-entre 0.35s var(--courbe) both;
  }
}

@keyframes panneau-entre {
  from {
    transform: translateX(100%);
  }
}

.panneau__haut {
  display: flex;
  flex: none;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: 0.875rem 1.25rem;
  border-bottom: 1px solid var(--line);
}

.panneau__titre {
  font-family: var(--police-titre);
  font-size: 1.125rem;
  font-weight: 800;
  line-height: 1.2;
}

.panneau__fermer {
  display: grid;
  flex: none;
  place-items: center;
  width: 2.5rem;
  height: 2.5rem;
  margin-right: -0.5rem;
  border-radius: 9999px;
}

@media (hover: hover) {
  .panneau__fermer:hover {
    background-color: var(--app-fond-actif);
  }
}

.panneau__aide {
  padding: 0.875rem 1.25rem 0;
  color: var(--fg-muted);
  font-size: 0.875rem;
}

.panneau__action {
  flex: none;
  padding: 0.875rem 1.25rem 0;
}

.panneau__recherche {
  flex: none;
  padding: 0.75rem 1.25rem;
}

.panneau__total {
  flex: none;
  min-height: 1.5rem;
  padding: 0 1.25rem 0.5rem;
  color: var(--fg-muted);
  font-size: 0.8125rem;
}

.panneau__liste {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  overscroll-behavior: contain;
}

.panneau__plus {
  display: flex;
  flex: none;
  justify-content: center;
  padding: 0.75rem;
  border-top: 1px solid var(--line);
}

/* --- Conversation --------------------------------------------------------- */
.app__fil {
  background-color: var(--app-fond-conversation);
}

.fil__entete {
  display: flex;
  flex: none;
  align-items: center;
  gap: 0.875rem;
  padding: 0.75rem 1rem;
  border-bottom: 1px solid var(--line);
  background-color: var(--app-fond);
}

.fil__retour {
  display: grid;
  flex: none;
  place-items: center;
  width: 2.5rem;
  height: 2.5rem;
  margin-left: -0.5rem;
  border-radius: 9999px;
}

/* Sur grand écran la liste reste visible : le retour n'a plus de raison d'être. */
@media (min-width: 48rem) {
  .fil__retour {
    display: none;
  }
}

.fil__identite {
  flex: 1;
  min-width: 0;
}

/* Dans un groupe, tout le bloc ouvre la liste des membres (le bouton du titre le fait pour le clavier). */
.fil__identite[data-zone-membres] {
  cursor: pointer;
}

.fil__titre {
  overflow: hidden;
  font-family: var(--police-titre);
  font-size: 1.0625rem;
  font-weight: 800;
  line-height: 1.2;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.fil__titre-bouton {
  display: block;
  max-width: 100%;
  overflow: hidden;
  text-align: left;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* La liste des noms tient sur une ligne et se coupe par « … » comme dans WhatsApp. */
.fil__sous-titre {
  overflow: hidden;
  color: var(--fg-muted);
  font-size: 0.8125rem;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Étoile des favoris : contour seul, remplie de miel une fois activée. */
.fil__favori {
  display: grid;
  flex: none;
  place-items: center;
  width: 2.5rem;
  height: 2.5rem;
  margin-right: -0.5rem;
  border-radius: 9999px;
  color: var(--fg-muted);
}

.fil__favori .icone {
  transition: fill 0.2s;
}

.fil__favori[aria-pressed="true"] {
  color: var(--fg);
}

.fil__favori[aria-pressed="true"] .icone {
  fill: var(--ampil-miel);
}

.fil__messages {
  display: flex;
  flex: 1;
  flex-direction: column;
  min-height: 0;
  padding: 1rem;
  overflow-y: auto;
  overscroll-behavior: contain;
}

/* Les messages se posent en bas : un groupe presque vide ne laisse pas le vide sous le dernier message. */
.messages {
  display: flex;
  flex-direction: column;
  gap: 0.375rem;
  margin-top: auto;
}

.fil__plus {
  display: flex;
  justify-content: center;
  margin-bottom: 1rem;
}

.fil__plus-bouton {
  padding: 0.5rem 1.1rem;
  border-radius: 9999px;
  background-color: var(--app-fond);
  box-shadow: inset 0 0 0 1.5px var(--app-contour);
  font-size: 0.8125rem;
  font-weight: 600;
}

.fil__plus-bouton:disabled {
  opacity: 0.6;
}

.jour-message {
  display: flex;
  justify-content: center;
  margin-block: 0.75rem 0.375rem;
}

.jour-message span {
  padding: 0.25rem 0.75rem;
  border-radius: 9999px;
  background-color: var(--app-fond);
  box-shadow: inset 0 0 0 1px var(--line);
  color: var(--fg-muted);
  font-size: 0.75rem;
  font-weight: 600;
}

.message {
  display: flex;
}

.message--moi {
  justify-content: flex-end;
}

.message__bulle {
  max-width: min(34rem, 86%);
  padding: 0.5rem 0.875rem 0.375rem;
  border-radius: 1.25rem 1.25rem 1.25rem 0.375rem;
  background-color: var(--app-bulle);
  box-shadow: inset 0 0 0 1px var(--app-bulle-bord);
}

.message--moi .message__bulle {
  border-radius: 1.25rem 1.25rem 0.375rem 1.25rem;
  background-color: var(--app-bulle-moi);
  box-shadow: none;
  color: var(--app-bulle-moi-texte);
}

.message__auteur {
  font-size: 0.8125rem;
  font-weight: 700;
  line-height: 1.4;
}

.message__promo {
  color: var(--fg-muted);
  font-weight: 500;
}

/* « pre-wrap » garde les retours à la ligne écrits par l'auteur ; « anywhere » coupe une adresse très longue. */
.message__texte {
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}

.message__heure {
  display: block;
  color: var(--fg-muted);
  font-size: 0.6875rem;
  text-align: right;
}

.message--moi .message__heure {
  color: color-mix(in srgb, var(--app-bulle-moi-texte) 80%, transparent);
}

/* --- Offres d'emploi : une annonce par offre partagée, dans le fil du canal ------------ */
.message--offre {
  display: block;
}

.annonce {
  max-width: min(34rem, 100%);
  padding: 0.875rem 1.125rem 0.625rem;
  border-radius: 1.25rem;
  background-color: var(--app-bulle);
  box-shadow: inset 0 0 0 1px var(--app-bulle-bord);
}

.annonce__auteur {
  font-size: 0.8125rem;
  font-weight: 700;
  line-height: 1.4;
}

.annonce__titre {
  margin-top: 0.25rem;
  font-family: var(--police-titre);
  font-size: 1.0625rem;
  font-weight: 800;
  line-height: 1.25;
  overflow-wrap: anywhere;
}

.annonce__detail {
  margin-top: 0.25rem;
  color: var(--fg-muted);
  font-size: 0.9375rem;
  overflow-wrap: anywhere;
}

.annonce__etiquettes {
  display: flex;
  flex-wrap: wrap;
  gap: 0.375rem;
  margin-top: 0.625rem;
}

.annonce__etiquettes:empty {
  display: none;
}

.annonce__etiquette {
  padding: 0.2rem 0.625rem;
  border-radius: 9999px;
  background-color: var(--app-fond-actif);
  font-size: 0.75rem;
  font-weight: 650;
}

/* Le site d'origine : en contour, pour le distinguer du type de contrat. */
.annonce__etiquette--site {
  background-color: transparent;
  box-shadow: inset 0 0 0 1px var(--app-contour);
  color: var(--fg-muted);
}

.annonce__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem;
  margin-top: 0.875rem;
}

.annonce__formulaire {
  display: inline-flex;
}

.annonce__action {
  min-height: 2.75rem;
  padding: 0.5rem 1rem;
  border-radius: 9999px;
  box-shadow: inset 0 0 0 1.5px var(--app-contour);
  font-size: 0.875rem;
  font-weight: 650;
}

.annonce__action--retirer {
  color: var(--fg-muted);
}

@media (hover: hover) {
  .annonce__action:hover {
    background-color: var(--app-survol);
  }
}

/* Discussion vide, ou aucune discussion choisie. */
.fil__vide {
  margin-block: auto;
  padding: 2rem 1rem;
  text-align: center;
}

.fil__vide p + p {
  margin-top: 0.5rem;
  color: var(--fg-muted);
}

.app__fil--vide {
  justify-content: center;
}

.fil__accueil {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 1rem;
  max-width: 26rem;
  margin: auto;
  padding: 2rem;
  text-align: center;
}

.fil__accueil::before {
  content: "";
  width: 6rem;
  aspect-ratio: 1;
  border-radius: 9999px;
  background-image: radial-gradient(circle at 34% 28%, var(--ampil-miel-300), var(--ampil-miel) 52%, var(--ampil-miel-600));
}

.fil__accueil p {
  color: var(--fg-muted);
}

/* Un message qui arrive entre doucement (transform et opacité seulement). */
@media (prefers-reduced-motion: no-preference) {
  .message {
    animation: message-entre 0.3s var(--courbe) both;
  }
}

@keyframes message-entre {
  from {
    opacity: 0;
    transform: translateY(0.5rem);
  }
}

/* --- Zone d'écriture ---------------------------------------------------------- */
.composeur {
  position: relative;
  display: flex;
  flex: none;
  align-items: flex-end;
  gap: 0.75rem;
  padding: 0.75rem 1rem var(--composeur-bas, calc(0.75rem + env(safe-area-inset-bottom)));
  border-top: 1px solid var(--line);
  background-color: var(--app-fond);
}

.composeur__saisie {
  flex: 1;
  min-height: 3rem;
  max-height: 9rem;
  padding: 0.8rem 1.1rem;
  border-radius: 1.5rem;
  background-color: var(--app-fond-doux);
  box-shadow: inset 0 0 0 1.5px var(--app-contour);
  color: var(--fg);
  font: inherit;
  line-height: 1.4;
  resize: none;
}

.composeur__saisie::placeholder {
  color: var(--fg-muted);
  opacity: 1;
}

.composeur__saisie:focus-visible {
  outline: 2px solid var(--focus);
  outline-offset: 2px;
  box-shadow: none;
}

.composeur__envoyer {
  display: grid;
  flex: none;
  place-items: center;
  width: 3rem;
  height: 3rem;
  border-radius: 9999px;
  background-color: var(--accent);
  color: var(--on-accent);
}

.composeur__envoyer:disabled {
  opacity: 0.6;
}

.composeur__erreur {
  position: absolute;
  right: 1rem;
  bottom: 100%;
  left: 1rem;
  margin-bottom: 0.5rem;
  padding: 0.5rem 0.875rem;
  border-radius: 0.75rem;
  background-color: var(--ampil-miel);
  color: var(--ampil-teal);
  font-size: 0.875rem;
  font-weight: 650;
}

/* Canal d'offres : à la place de la zone d'écriture, un bouton pour ajouter une offre. */
.composeur--offre {
  justify-content: center;
}

.composeur--offre .btn {
  width: 100%;
  max-width: 24rem;
}

/* Confirmation simple : pastille cochée, texte, croix pour fermer. */
.notice {
  display: flex;
  flex: none;
  align-items: center;
  gap: 0.75rem;
  margin: 0.75rem 1rem 0;
  padding: 0.625rem 0.75rem;
  border-radius: 0.75rem;
  background-color: var(--ampil-beurre);
  box-shadow: inset 0 0 0 1px var(--line), 0 0.25rem 0.75rem rgb(0 21 26 / 0.08);
  color: var(--ampil-teal);
}

.notice__coche {
  display: grid;
  flex: none;
  place-items: center;
  width: 1.75rem;
  height: 1.75rem;
  border-radius: 9999px;
  background-color: var(--ampil-miel);
}

.notice__coche svg {
  width: 1.125rem;
  height: 1.125rem;
}

.notice__texte {
  flex: 1;
  min-width: 0;
  font-weight: 650;
  overflow-wrap: anywhere;
}

.notice__fermer {
  display: grid;
  flex: none;
  place-items: center;
  width: 2.5rem;
  height: 2.5rem;
  margin: -0.25rem;
  border-radius: 9999px;
}

@media (prefers-reduced-motion: no-preference) {
  .notice {
    animation: publiee-entre 0.35s var(--courbe) both;
  }
}

@keyframes publiee-entre {
  from {
    opacity: 0;
    transform: translateY(-0.5rem);
  }
}

/* Analyse du lien et mise en ligne : un petit cercle qui tourne. */
.offre-etat {
  margin-top: -0.5rem;
  color: var(--fg-muted);
  font-size: 0.875rem;
  font-weight: 600;
}

.offre-etat[hidden] {
  display: none;
}

.offre-etat--charge::before,
.btn--charge::before {
  content: "";
  display: inline-block;
  width: 0.9em;
  height: 0.9em;
  margin-right: 0.5rem;
  border: 2px solid currentColor;
  border-right-color: transparent;
  border-radius: 9999px;
  vertical-align: -0.1em;
}

@media (prefers-reduced-motion: no-preference) {
  .offre-etat--charge::before,
  .btn--charge::before {
    animation: tourne 0.8s linear infinite;
  }
}

@keyframes tourne {
  to {
    transform: rotate(360deg);
  }
}

/* Avis d'une action sur un canal (offre retirée, échec) : au-dessus du fil. */
.canal__avis {
  flex: none;
  margin: 0.75rem 1rem 0;
}

/* --- Barre d'onglets : Profil, Échanges, Offres, Carte, Discussions, Paramètres --
   Sur téléphone : une pastille flottante en « verre liquide », de la même forme que la barre
   du site. Elle est translucide et floue, bordée d'un reflet, et la liste défile dessous.
   Sur grand écran : une colonne plate à gauche (partie plus bas).
   Le verre est teinté du bleu canard le plus foncé, comme la barre du site : le texte beurre
   garde plus de 7:1 même devant un fond blanc. Un seul endroit règle son allure (--verre-*) ;
   plus l'opacité baisse, plus le contenu transparaît (en dessous de 70 %, le texte perd en lisibilité). */
.onglets {
  --verre-teinte: var(--ampil-teal-900);
  --verre-opacite: 86%;
  --onglet-texte: color-mix(in srgb, var(--ampil-beurre) 86%, transparent);
  --onglet-actif-fond: var(--ampil-miel);
  --onglet-actif-texte: var(--ampil-teal);
  --onglet-pastille: var(--ampil-miel);
  --onglet-pastille-texte: var(--ampil-teal);

  position: fixed;
  right: 0.75rem;
  bottom: calc(0.75rem + env(safe-area-inset-bottom));
  left: 0.75rem;
  z-index: 40;
  display: flex;
  gap: 0.25rem;
  max-width: 26rem;
  margin-inline: auto;
  padding: 0.375rem;
  border-radius: 9999px;
  background-color: color-mix(in srgb, var(--verre-teinte) var(--verre-opacite), transparent);
  /* Un reflet qui descend du bord supérieur, comme sur une vitre. */
  background-image: linear-gradient(180deg, rgb(255 255 255 / 0.09), rgb(255 255 255 / 0) 55%);
  -webkit-backdrop-filter: blur(22px) saturate(1.5);
  backdrop-filter: blur(22px) saturate(1.5);
  box-shadow:
    inset 0 0 0 1px rgb(255 255 255 / 0.14),
    inset 0 1px 0 rgb(255 255 255 / 0.24),
    inset 0 -1px 0 rgb(0 21 26 / 0.5),
    0 10px 30px rgb(0 21 26 / 0.28);
}

/* Navigateur sans flou d'arrière-plan, ou réglage « réduire la transparence » : un aplat presque plein. */
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .onglets {
    --verre-opacite: 96%;
  }
}

@media (prefers-reduced-transparency: reduce) {
  .onglets {
    --verre-opacite: 100%;
    -webkit-backdrop-filter: none;
    backdrop-filter: none;
  }
}

.onglet {
  display: flex;
  flex: 1;
  flex-direction: column;
  align-items: center;
  gap: 0.125rem;
  min-width: 0;
  padding: 0.5rem 0.25rem 0.4rem;
  border-radius: 9999px;
  color: var(--onglet-texte);
  font-size: 0.6875rem;
  font-weight: 600;
  line-height: 1.2;
  transition:
    background-color 0.25s,
    color 0.25s;
}

/* L'onglet actif est une gélule de miel qui contient l'icône et son nom. */
.onglet--actif {
  background-color: var(--onglet-actif-fond);
  box-shadow: inset 0 1px 0 rgb(255 255 255 / 0.45);
  color: var(--onglet-actif-texte);
  font-weight: 700;
}

.onglet__icone {
  position: relative;
  display: grid;
  place-items: center;
  width: 1.75rem;
  height: 1.5rem;
}

.icone--onglet {
  width: 1.5rem;
  height: 1.5rem;
}

.onglet__pastille {
  position: absolute;
  top: -0.5rem;
  right: -0.625rem;
  display: grid;
  place-items: center;
  min-width: 1.25rem;
  height: 1.25rem;
  padding-inline: 0.3rem;
  border-radius: 9999px;
  background-color: var(--onglet-pastille);
  color: var(--onglet-pastille-texte);
  font-size: 0.6875rem;
  font-weight: 700;
  line-height: 1;
}

/* Sur la gélule de miel, une pastille de miel ne se verrait pas : elle prend les couleurs inverses. */
.onglet--actif .onglet__pastille {
  background-color: var(--ampil-teal);
  color: var(--ampil-miel);
}

/* Téléphone : six onglets ne laissent pas à chaque nom la place de s'écrire. L'onglet ouvert garde
   le sien dans sa gélule, plus large ; les autres se réduisent à leur icône (leur nom reste lu
   par les lecteurs d'écran, et la page ouverte porte son titre). */
@media (max-width: 47.99rem) {
  .onglet {
    justify-content: center;
  }

  .onglet--actif {
    flex: 2.5;
  }

  .onglet:not(.onglet--actif) .onglet__libelle {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
  }
}

/* Téléphone : la pastille reste en bas dans les conversations aussi, et tout défile dessous. */
@media (max-width: 47.99rem) {
  .app--onglets .app__coque {
    --reserve-onglets: var(--hauteur-onglets);
    --composeur-bas: 0.75rem;
  }

  /* La liste passe sous le verre ; sa dernière ligne peut toutefois remonter au-dessus. */
  .app--onglets .liste__defilement {
    padding-bottom: var(--hauteur-onglets);
  }

  .app--onglets .app__page {
    padding-bottom: calc(var(--hauteur-onglets) + 1rem);
  }
}

/*
 * Clavier à l'écran ouvert : la pastille s'efface pour laisser sa place à la zone d'écriture.
 * Seulement sur un écran tactile (hover: none) : sur un ordinateur, le champ reçoit le focus dès
 * l'ouverture d'une conversation (messagerie.js), et la barre disparaissait d'une fenêtre étroite.
 */
@media (max-width: 47.99rem) and (hover: none) {
  .app--onglets .app__coque:has(.composeur__saisie:focus) {
    --reserve-onglets: 0px;
    --composeur-bas: calc(0.75rem + env(safe-area-inset-bottom));
  }

  .app--onglets .app__coque:has(.composeur__saisie:focus) ~ .onglets {
    display: none;
  }
}

/* Sur grand écran : une colonne plate d'icônes à gauche, toujours visible. */
@media (min-width: 48rem) {
  .onglets {
    --onglet-texte: var(--fg-muted);
    --onglet-actif-fond: var(--app-puce);
    --onglet-actif-texte: var(--app-puce-texte);
    --onglet-pastille: var(--app-pastille);
    --onglet-pastille-texte: var(--app-pastille-texte);

    inset: 0 auto 0 0;
    width: 5rem;
    max-width: none;
    margin: 0;
    flex-direction: column;
    justify-content: flex-start;
    gap: 0.5rem;
    padding: 1rem 0.25rem;
    border-radius: 0;
    background-color: var(--app-fond);
    background-image: none;
    -webkit-backdrop-filter: none;
    backdrop-filter: none;
    box-shadow: inset -1px 0 0 var(--line);
  }

  .onglet {
    flex: none;
    padding: 0.5rem 0;
    border-radius: 1rem;
  }

  .onglet--actif {
    box-shadow: none;
  }

  .app--onglets .app__coque {
    margin-left: var(--largeur-onglets, 5rem);
  }

  .app--onglets .app__page {
    margin-left: var(--largeur-onglets, 5rem);
  }
}

/* Dès qu'il y a la place pour trois colonnes : une vraie barre latérale, comme dans une messagerie
   d'ordinateur. Chaque ligne porte l'icône, le nom à côté et le nombre de non lues au bout ;
   la ligne ouverte se repère à son fond, sans aplat de miel. En dessous de cette largeur, la
   colonne étroite ci-dessus reste : la conversation n'aurait plus assez de place. */
@media (min-width: 64rem) {
  .app {
    --largeur-onglets: 13.5rem;
  }

  .onglets {
    --onglet-texte: var(--fg);
    --onglet-actif-fond: var(--app-fond-actif);
    --onglet-actif-texte: var(--fg);

    width: var(--largeur-onglets);
    gap: 0.125rem;
    padding: 1rem 0.625rem;
    background-color: var(--app-fond-doux);
  }

  .onglet {
    position: relative;
    flex-direction: row;
    gap: 0.75rem;
    /* À droite, la place du compteur, pour qu'un nom long ne passe jamais dessous. */
    padding: 0.625rem 2.75rem 0.625rem 0.75rem;
    border-radius: 0.75rem;
    font-size: 1rem;
    font-weight: 500;
    line-height: 1.5;
  }

  .onglet:hover {
    background-color: color-mix(in srgb, var(--fg) 6%, transparent);
  }

  .onglet--actif,
  .onglet--actif:hover {
    background-color: var(--onglet-actif-fond);
    font-weight: 650;
  }

  /* Le compteur quitte le coin de l'icône : il se cale sur le bord droit de la ligne. */
  .onglet__icone {
    position: static;
    flex: none;
  }

  .onglet .onglet__pastille {
    top: 0;
    right: 0.75rem;
    bottom: 0;
    min-width: 0;
    margin-block: auto;
    padding-inline: 0;
    background-color: transparent;
    color: var(--fg-muted);
    font-size: 0.9375rem;
    font-weight: 500;
  }
}

/* --- Invitation à activer les notifications ---------------------------------- */
.bandeau {
  margin: 0 1.25rem 0.75rem;
  padding: 0.75rem 1rem;
  border-radius: 1rem;
  background-color: var(--app-fond-actif);
}

.bandeau__texte {
  font-size: 0.875rem;
  font-weight: 600;
  line-height: 1.4;
}

.bandeau__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem 1rem;
  margin-top: 0.5rem;
}

.bandeau__bouton {
  padding: 0.5rem 1rem;
  border-radius: 9999px;
  background-color: var(--accent);
  color: var(--on-accent);
  font-size: 0.8125rem;
  font-weight: 650;
}

.bandeau__lien {
  font-size: 0.8125rem;
  font-weight: 600;
  text-decoration: underline;
  text-underline-offset: 0.2em;
}

/* --- Pages simples de l'espace membre (profil, paramètres) ------------------- */
.app__page {
  min-height: 100vh;
  min-height: 100dvh;
  background-color: var(--app-fond-page);
}

.app__page-contenu {
  display: flex;
  flex-direction: column;
  gap: 1.25rem;
  max-width: 40rem;
  margin-inline: auto;
  padding: 1.5rem 1.25rem 4rem;
}

/* Cartes et champs : le bleu canard translucide du site, posé sur le beurre, tirerait vers le vert ;
   ici, des aplats nets, clairs ou sombres selon le mode. */
.app .carte {
  background-color: var(--app-carte);
}

.app .champ__saisie {
  background-color: var(--app-champ);
  box-shadow: inset 0 0 0 1.5px var(--app-contour);
  color: var(--fg);
}

.app .champ__saisie:focus-visible {
  box-shadow: none;
}

.app .champ--erreur .champ__saisie {
  box-shadow: inset 0 0 0 2.5px var(--fg);
}

.app .champ__case {
  accent-color: var(--accent);
}

/* Champ « photo » : le bouton du navigateur (« Choisir un fichier ») prend l'allure d'une puce de l'application. */
.app .champ__saisie[type="file"] {
  padding: 0.5rem;
  font-size: 0.875rem;
}

.app .champ__saisie[type="file"]::file-selector-button {
  margin-right: 0.875rem;
  padding: 0.5rem 1rem;
  border: 0;
  border-radius: 0.625rem;
  background-color: var(--app-fond-actif);
  color: var(--fg);
  font: inherit;
  font-weight: 650;
  cursor: pointer;
}

/* Lien « Retour à la discussion » en tête d'une page ouverte depuis une conversation. */
.app__retour {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  min-height: 2.75rem;
  font-size: 0.9375rem;
  font-weight: 650;
}

@media (hover: hover) {
  .app__retour:hover span {
    text-decoration: underline;
    text-underline-offset: 0.2em;
  }
}

.app .formulaire__succes {
  background-color: var(--app-fond-actif);
  color: var(--fg);
}

/* --- Profil ------------------------------------------------------------------- */
.profil__entete {
  display: flex;
  align-items: center;
  gap: 1.25rem;
}

.avatar--grand {
  width: 5rem;
  height: 5rem;
  font-size: 1.5rem;
}

.profil__promo {
  color: var(--fg-muted);
}

/* Choix d'apparaître sur la carte : une zone à part, pour que ce soit un choix et non un détail. */
.profil__carte {
  margin: 0;
  padding: 1rem 1.125rem;
  border: 0;
  border-radius: 1rem;
  background-color: var(--app-fond-doux);
  box-shadow: inset 0 0 0 1px var(--line);
}

.profil__carte-titre {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0;
  font-weight: 700;
}

.profil__carte .champ--case {
  margin-top: 0.75rem;
}

.profil__carte-etat {
  display: flex;
  align-items: flex-start;
  gap: 0.5rem;
  margin-top: 0.75rem;
  font-size: 0.875rem;
}

.profil__carte-etat .icone {
  flex: none;
}

.profil__carte-etat a {
  font-weight: 650;
  text-decoration: underline;
  text-underline-offset: 0.2em;
}

/* Suggestions de villes : une liste qui s'ouvre sous le champ (ville.js). */
.ville__saisie {
  position: relative;
}

.ville__suggestions {
  position: absolute;
  inset: calc(100% + 0.25rem) 0 auto;
  z-index: 20;
  max-height: 15rem;
  margin: 0;
  padding: 0.25rem;
  overflow-y: auto;
  overscroll-behavior: contain;
  border-radius: 1rem;
  background-color: var(--app-fond);
  box-shadow: inset 0 0 0 1.5px var(--app-contour), 0 0.75rem 1.75rem rgb(0 21 26 / 0.16);
  list-style: none;
}

.ville__suggestions[hidden] {
  display: none;
}

.ville__option {
  padding: 0.75rem;
  border-radius: 0.625rem;
  cursor: pointer;
}

.ville__option[aria-selected="true"] {
  background-color: var(--app-fond-actif);
}

@media (hover: hover) {
  .ville__option:hover {
    background-color: var(--app-survol);
  }
}

/* --- Photo : la pastille se touche pour choisir une image, puis on la recadre ---- */
.photo-bouton {
  position: relative;
  flex: none;
  border-radius: 9999px;
}

.photo-bouton:disabled {
  cursor: default;
}

/* Petit appareil photo accroché à la pastille : c'est lui qui dit qu'elle se touche. */
.photo-bouton__badge {
  position: absolute;
  right: -0.25rem;
  bottom: -0.25rem;
  display: grid;
  place-items: center;
  width: 2rem;
  height: 2rem;
  border-radius: 9999px;
  background-color: var(--app-pastille);
  box-shadow: 0 0 0 2px var(--app-fond-page);
  color: var(--app-pastille-texte);
}

.photo-bouton__badge[hidden] {
  display: none;
}

.photo-bouton__badge .icone {
  width: 1.125rem;
  height: 1.125rem;
}

/* Avec JavaScript, la pastille remplace le champ de fichier : il ne reparaît que pour dire une erreur. */
.champ--photo-js:not(.champ--erreur),
.champ--photo-js .champ__saisie,
.champ--photo-js .champ__aide {
  display: none;
}

.recadrage {
  width: min(24rem, calc(100% - 2rem));
  max-height: calc(100dvh - 2rem);
  margin: auto;
  padding: 1.25rem;
  border: 0;
  border-radius: 1.5rem;
  background-color: var(--app-fond);
  box-shadow: inset 0 0 0 1px var(--line), 0 1.5rem 3rem rgb(0 21 26 / 0.16);
  color: var(--fg);
  overflow-y: auto;
}

.recadrage[open] {
  display: flex;
  flex-direction: column;
  gap: 1rem;
}

/* Même voile que le panneau des membres (les variables ne s'appliquent pas toujours à ::backdrop). */
.recadrage::backdrop {
  background-color: rgb(255 255 255 / 0.7);
}

@media (prefers-color-scheme: dark) {
  .recadrage::backdrop {
    background-color: rgb(0 21 26 / 0.72);
  }
}

.recadrage__titre {
  font-family: var(--police-titre);
  font-size: 1.125rem;
  font-weight: 800;
  line-height: 1.2;
}

/* Le cadre carré est ce qui sera gardé ; le rond montre ce que les autres verront dans la pastille.
   touch-action : le doigt déplace la photo, pas la page. */
.recadrage__cadre {
  position: relative;
  flex: none;
  width: 100%;
  aspect-ratio: 1;
  overflow: hidden;
  border-radius: 1rem;
  background-color: var(--app-fond-doux);
  cursor: grab;
  touch-action: none;
  -webkit-user-select: none;
  user-select: none;
}

.recadrage__cadre:active {
  cursor: grabbing;
}

/* Placée par photo.js (transform seulement) ; la largeur automatique du site ne doit pas la réduire. */
.recadrage__image {
  position: absolute;
  top: 0;
  left: 0;
  max-width: none;
  transform-origin: 0 0;
  pointer-events: none;
}

.recadrage__masque {
  position: absolute;
  inset: 0;
  border-radius: 9999px;
  box-shadow:
    0 0 0 100vmax color-mix(in srgb, var(--app-fond) 70%, transparent),
    inset 0 0 0 2px var(--app-contour);
  pointer-events: none;
}

.recadrage__aide {
  color: var(--fg-muted);
  font-size: 0.875rem;
}

.recadrage__zoom {
  display: flex;
  align-items: center;
  gap: 0.875rem;
  font-size: 0.875rem;
  font-weight: 600;
}

.recadrage__zoom input {
  flex: 1;
  min-width: 0;
  min-height: 2.75rem;
  accent-color: var(--accent);
}

.recadrage__actions {
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-end;
  gap: 0.75rem;
}

.profil__aide {
  color: var(--fg-muted);
  font-size: 0.9375rem;
}

.profil__courriel {
  font-weight: 600;
  overflow-wrap: anywhere;
}

.formulaire--profil {
  margin-top: 0;
}

/* --- Carte des membres : le globe, sa fiche, et la liste qui dit la même chose --------- */
.app__page-contenu--large {
  max-width: 72rem;
}

.carte__entete {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

.carte__corps {
  display: grid;
  gap: 1.5rem;
}

@media (min-width: 64rem) {
  .carte__corps {
    grid-template-columns: minmax(0, 1.5fr) minmax(19rem, 1fr);
    align-items: start;
  }

}

/* À côté du globe : la fiche du point touché (quand elle est ouverte), puis la liste. */
.carte__cote {
  display: flex;
  flex-direction: column;
  gap: 1.5rem;
  min-width: 0;
}

/* Le globe suit le mode de l'espace membre. Clair : une mer beurre, des terres bleu canard.
   Sombre : une mer bleu canard foncé, des terres beurre. Dans les deux cas il repose directement
   sur la page, sans carte ni contour autour de lui. Tout passe par les variables --globe-*
   ci-dessous, que globe.js lit : un mode n'est qu'un second jeu de valeurs.
   Le miel n'est jamais posé sur le beurre sans son cercle bleu canard (--globe-trait), sinon le point disparaît. */
.globe {
  --globe-fond: var(--app-fond-page); /* la page derrière lui : les commandes de zoom s'y mélangent */
  --globe-mer: var(--ampil-beurre);
  --globe-reflet: var(--ampil-beurre-50);
  --globe-terre: var(--ampil-teal);
  --globe-membre: var(--ampil-miel);
  --globe-trait: var(--ampil-teal-900); /* cercle des points et chiffre des regroupements */
  --globe-moi: var(--ampil-teal-900); /* cercle de mon point (plus épais, voir globe.js) */
  --globe-encre: var(--ampil-teal); /* commandes de zoom */
  --globe-nom: var(--ampil-teal-900); /* nom de la commune, de près */
  --globe-halo: var(--ampil-beurre); /* halo du nom, couleur de la mer */

  position: relative;
  aspect-ratio: 1;
  max-height: 70vh;
  overflow: hidden;
  border-radius: 2rem;
  color: var(--globe-encre);
}

@media (prefers-color-scheme: dark) {
  .globe {
    --globe-mer: var(--ampil-teal-900);
    --globe-reflet: var(--ampil-teal-700);
    --globe-terre: var(--ampil-beurre);
    --globe-moi: var(--ampil-beurre);
    --globe-encre: var(--ampil-beurre);
    --globe-nom: var(--ampil-beurre);
    --globe-halo: var(--ampil-teal-900);
  }
}

@media (min-width: 64rem) {
  .globe {
    aspect-ratio: auto;
    height: clamp(24rem, 72vh, 44rem);
    max-height: none;
  }
}

.globe__toile {
  display: block;
  width: 100%;
  height: 100%;
  cursor: grab;
  /* Le glissement fait tourner le globe : le navigateur ne doit pas le prendre pour un défilement. */
  touch-action: none;
}

.globe__toile:active {
  cursor: grabbing;
}

.globe__toile:focus-visible {
  outline: 3px solid var(--focus);
  outline-offset: -3px;
}

.globe__commandes {
  position: absolute;
  top: 0.75rem;
  right: 0.75rem;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

/* Sans JavaScript, il n'y a pas de globe : ses commandes n'ont pas de sens. */
.globe:not(.globe--pret) .globe__commandes {
  display: none;
}

.globe__commande,
.globe__fermer {
  display: grid;
  flex: none;
  place-items: center;
  width: 2.75rem;
  height: 2.75rem;
  border-radius: 9999px;
}

.globe__commande {
  /* Mélangés au fond du globe, non à du transparent : les points de terre ne doivent pas passer dessous. */
  background-color: color-mix(in srgb, var(--globe-encre) 14%, var(--globe-fond));
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--globe-encre) 32%, var(--globe-fond));
  color: var(--globe-encre);
}

@media (hover: hover) {
  .globe__commande:hover {
    background-color: color-mix(in srgb, var(--globe-encre) 26%, var(--globe-fond));
  }

  .globe__fermer:hover {
    background-color: var(--app-fond-actif);
  }
}

/* Fiche des personnes d'un point : une carte de la page, sous le globe sur téléphone et au-dessus
   de la liste sur grand écran. Elle ne recouvre jamais le globe : le point touché reste visible. */
.globe__fiche {
  display: flex;
  flex-direction: column;
  max-height: 34rem;
  border-radius: 1.5rem;
  background-color: var(--app-carte);
  box-shadow: inset 0 0 0 1px var(--app-contour);
  color: var(--fg);
}

.globe__fiche[hidden] {
  display: none;
}

.globe__fiche-haut {
  display: flex;
  flex: none;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  padding: 0.75rem 0.75rem 0 1.125rem;
}

.globe__fiche-titre {
  font-family: var(--police-titre);
  font-size: 1.0625rem;
  font-weight: 800;
  line-height: 1.2;
  overflow-wrap: anywhere;
}

/* Le titre reçoit le focus par script, pour que les lecteurs d'écran annoncent la fiche : ce n'est pas
   un contrôle, un cadre autour n'aurait aucun sens. */
.globe__fiche-titre:focus {
  outline: none;
}

.globe__fiche-total {
  flex: none;
  padding: 0 1.125rem;
  color: var(--fg-muted);
  font-size: 0.8125rem;
}

.globe__fiche-corps {
  display: grid;
  gap: 0.75rem;
  min-height: 0;
  padding: 0.75rem 0.75rem 0.75rem;
  overflow-y: auto;
  overscroll-behavior: contain;
}

.globe__membre {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  padding: 0.875rem;
  border-radius: 1rem;
  background-color: var(--app-fond-doux);
}

.globe__membre-haut {
  display: flex;
  align-items: center;
  gap: 0.75rem;
}

.globe__membre-identite {
  min-width: 0;
}

.globe__membre-nom {
  font-size: 1rem;
  font-weight: 700;
  overflow-wrap: anywhere;
}

.globe__membre-promo,
.globe__membre-poste {
  color: var(--fg-muted);
  font-size: 0.875rem;
}

.globe__membre-poste {
  color: var(--fg);
  font-weight: 600;
}

.globe__membre-presentation {
  font-size: 0.9375rem;
  overflow-wrap: anywhere;
}

.globe__membre-moi {
  align-self: flex-start;
  padding: 0.125rem 0.625rem;
  border-radius: 9999px;
  background-color: var(--app-fond-actif);
  font-size: 0.75rem;
  font-weight: 600;
}

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

.globe__erreur {
  padding: 0.5rem 0.875rem;
  border-radius: 0.75rem;
  background-color: var(--ampil-miel);
  color: var(--ampil-teal);
  font-size: 0.875rem;
  font-weight: 650;
}

.carte__liste {
  display: flex;
  flex-direction: column;
  gap: 1rem;
  min-width: 0;
}

.carte__liste-titre {
  color: var(--fg-muted);
}

.carte__vide {
  color: var(--fg-muted);
}

.carte__ville-nom {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding-bottom: 0.5rem;
  border-bottom: 1px solid var(--line);
  font-size: 0.9375rem;
  font-weight: 700;
}

.carte__ville-nom .icone {
  flex: none;
}

.carte__ville-nombre {
  margin-left: auto;
  padding: 0.125rem 0.625rem;
  border-radius: 9999px;
  background-color: var(--app-fond-actif);
  font-size: 0.75rem;
}

.carte__membre {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem 0.875rem;
  padding: 0.75rem 0;
  border-bottom: 1px solid var(--line);
}

.carte__membre-texte {
  flex: 1;
  min-width: 0;
}

.carte__membre-texte .membre__nom {
  overflow-wrap: anywhere;
  white-space: normal;
}

.carte__membre-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem;
  /* Sous le nom sur un écran étroit, alignées avec lui (avatar de 3 rem + écart). */
  flex-basis: 100%;
  padding-left: 3.875rem;
}

.carte__action {
  min-height: 2.75rem;
  padding: 0.5rem 1rem;
  border-radius: 9999px;
  box-shadow: inset 0 0 0 1.5px var(--app-contour);
  font-size: 0.875rem;
  font-weight: 650;
}

.carte__action[hidden] {
  display: none;
}

@media (hover: hover) {
  .carte__action:hover {
    background-color: var(--app-survol);
  }
}

/* --- Paramètres ---------------------------------------------------------------- */
.parametres__bloc {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 1rem;
}

.parametres__bloc .formulaire,
.parametres__bloc form {
  width: 100%;
  margin-top: 0;
}

.parametres__entete {
  display: flex;
  align-items: center;
  gap: 0.875rem;
}

.parametres__icone {
  display: grid;
  flex: none;
  place-items: center;
  width: 2.75rem;
  height: 2.75rem;
  border-radius: 9999px;
  background-color: var(--app-fond-actif);
  box-shadow: inset 0 0 0 1.5px var(--app-contour);
}

.parametres__bloc > p {
  color: var(--fg-muted);
}

.parametres__etat {
  font-weight: 600;
}

.parametres__etat:empty {
  display: none;
}

.parametres__actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
}

.parametres__choix {
  display: flex;
  flex-direction: column;
  gap: 0.875rem;
  min-width: 0;
  margin: 0;
  padding: 0;
  border: 0;
}

.parametres__choix legend {
  margin-bottom: 0.75rem;
  padding: 0;
  font-size: 0.875rem;
  font-weight: 700;
}

.parametres__sous-titre {
  margin-top: 0.75rem;
  font-size: 1rem;
  font-weight: 700;
}

/* Pastille du nombre de demandes, à côté du lien « Inscriptions à valider ». */
.parametres__compte {
  display: inline-grid;
  place-items: center;
  min-width: 1.5rem;
  height: 1.5rem;
  margin-left: 0.5rem;
  padding: 0 0.4rem;
  border-radius: 9999px;
  background-color: var(--app-pastille);
  color: var(--app-pastille-texte);
  font-size: 0.8125rem;
  font-weight: 700;
}

/* --- Inscriptions à valider (équipe) ------------------------------------------- */
.inscriptions {
  display: flex;
  flex-direction: column;
  gap: 1rem;
  margin: 0;
  padding: 0;
  list-style: none;
}

.inscription {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
}

.inscription__nom {
  font-size: 1.0625rem;
  font-weight: 700;
}

.inscription__details {
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
  margin: 0;
  color: var(--fg-muted);
  font-size: 0.9375rem;
}

.inscription__details dd {
  margin: 0;
}

/* Une adresse longue passe à la ligne plutôt que d'élargir la carte. */
.inscription__email {
  overflow-wrap: anywhere;
}

.inscriptions__vide {
  color: var(--fg-muted);
}

.parametres__infos dd {
  font-weight: 650;
  overflow-wrap: anywhere;
}

.parametres__bas {
  color: var(--fg-muted);
  font-size: 0.875rem;
}

/* --- Écran d'accueil après la connexion ----------------------------------------
   Un rideau sombre avec le logo et le prénom, qui se lève tout seul (partie 11).
   Masqué par défaut : il n'apparaît que si les animations sont acceptées, sinon
   il resterait devant l'application. */
.accueil-app {
  position: fixed;
  inset: 0;
  z-index: 80;
  display: none;
  place-content: center;
  justify-items: center;
  gap: 1.5rem;
  padding: 2rem;
  background-color: var(--app-rideau);
  text-align: center;
}

.accueil-app__logo {
  height: 2.5rem;
}

.accueil-app__texte {
  color: var(--fg-muted);
  font-size: 1rem;
}

/* Prénom et nom : Syne est très large, un nom long passe sur deux lignes plutôt que de déborder. */
.accueil-app__nom {
  display: block;
  margin-top: 0.4rem;
  color: var(--fg);
  font-size: clamp(1.25rem, 6vw, 2.25rem);
  line-height: 1.15;
  text-wrap: balance;
  overflow-wrap: anywhere;
}

/* ==========================================================================
   11. ANIMATIONS
   Les éléments animés par le script sont masqués avant le premier affichage
   seulement si le JavaScript est actif ET si le visiteur accepte les
   animations. Sinon, tout le contenu reste visible et statique.
   ========================================================================== */

@media (scripting: enabled) and (prefers-reduced-motion: no-preference) {
  [data-reveal],
  [data-reveal-item],
  [data-split],
  [data-intro] {
    opacity: 0;
  }

  /* Filet de sécurité : si le script n'a pas démarré au bout de 4 s
     (réseau coupé, erreur…), le contenu réapparaît de lui-même. */
  [data-motion-root]:not([data-motion-ready]) :is([data-reveal], [data-reveal-item], [data-split], [data-intro]) {
    animation: ampil-secours 0.5s ease 4s forwards;
  }
}

@keyframes ampil-secours {
  to {
    opacity: 1;
  }
}

/* Si les bibliothèques d'animation n'ont pas pu se charger (voir main.js),
   rien ne reste masqué. */
.sans-animations :is([data-reveal], [data-reveal-item], [data-split], [data-intro]) {
  opacity: 1 !important;
  animation: none !important;
}

/* Réglages attendus par Lenis, la bibliothèque de défilement fluide. */
html.lenis,
html.lenis body {
  height: auto;
}

.lenis.lenis-stopped {
  overflow: clip;
}

.lenis [data-lenis-prevent],
.lenis [data-lenis-prevent-horizontal] {
  overscroll-behavior: contain;
}

/* Masques des titres animés (SplitText) : un peu de marge pour ne pas rogner
   les jambages (p, q, g…) ni les accents. */
.split-line-mask,
.split-char-mask {
  margin-block: -0.16em;
  padding-block: 0.16em;
}

/* Entrée du texte du hero : en CSS pur, donc visible dès le premier affichage,
   sans attendre le chargement du script. --rang décale chaque élément. */
@media (prefers-reduced-motion: no-preference) {
  .hero-entree {
    animation: ampil-entree 0.9s var(--courbe) both;
    animation-delay: calc(0.05s + var(--rang, 0) * 0.08s);
  }
}

/* Départ à 1 % d'opacité et non à 0 : le texte est réellement dessiné dès la
   première image, ce qui permet aussi au navigateur de le compter comme
   contenu principal affiché (mesure LCP). */
@keyframes ampil-entree {
  from {
    opacity: 0.01;
    transform: translateY(1.75rem);
  }
}

/* --- Transitions entre pages --------------------------------------------------
   Le navigateur anime lui-même le passage d'une page à l'autre (View
   Transitions). La nouvelle page se dévoile dans un cercle qui grandit depuis
   le bas de l'écran : le motif des promos, encore. Les navigateurs qui ne
   connaissent pas cette fonction changent de page normalement. */
@view-transition {
  navigation: auto;
}

.entete {
  view-transition-name: entete;
}

main {
  view-transition-name: page;
}

::view-transition {
  pointer-events: none;
}

/* Le fond (dégradé, grain) ne se fond pas : seul le contenu est animé. */
::view-transition-old(root),
::view-transition-new(root) {
  animation: none;
}

::view-transition-old(page) {
  animation: 0.35s ease both ampil-page-sort;
}

::view-transition-new(page) {
  animation: 0.85s var(--courbe) both ampil-page-entre;
}

/* L'en-tête reste immobile pendant la transition. */
::view-transition-group(entete) {
  z-index: 100;
  animation: none;
}

::view-transition-old(entete) {
  display: none;
}

::view-transition-new(entete) {
  animation: none;
}

@keyframes ampil-page-sort {
  to {
    opacity: 0;
    transform: translateY(-1.5rem);
  }
}

@keyframes ampil-page-entre {
  from {
    clip-path: circle(0 at 50vw 100vh);
  }

  to {
    clip-path: circle(150vmax at 50vw 100vh);
  }
}

/* --- Transitions de l'application : onglets et conversations -------------------
   Comme dans une application : en changeant d'onglet, le contenu glisse de côté, dans le
   sens de la navigation (l'onglet de droite arrive par la droite), et la gélule de miel du
   menu glisse d'un onglet à l'autre. Sur téléphone, ouvrir une conversation fait entrer
   l'écran par la droite ; revenir à la liste le ramène par la gauche.
   Le sens (« avance » ou « recule ») est noté par Assets/js/transitions-app.js. Un navigateur
   qui ne connaît pas les types de transition enchaîne simplement les deux écrans en fondu. */

/* Le menu reste en place : l'ancienne image est retirée, seule la gélule (nommée à part) se déplace. */
::view-transition-old(onglets) {
  display: none;
}

::view-transition-new(onglets) {
  animation: none;
}

/* Dans l'image d'une transition, Chrome ne rogne pas le flou du verre aux angles arrondis : un
   rectangle pâle (le flou de ce qui passe dessous) déborde autour de la pastille. Le temps de la
   transition, la pastille perd donc son flou. Sans lui, le texte qui défile dessous se verrait à
   travers : la teinte est mélangée d'avance avec le fond de page, ce qui donne le même ton que le
   verre devant une page vide. Le verre revient une fois l'écran posé. Sur grand écran, la colonne
   est déjà un aplat : rien à changer. */
@media (max-width: 47.99rem) {
  html:active-view-transition .onglets {
    background-color: color-mix(in srgb, var(--verre-teinte) var(--verre-opacite), var(--app-fond));
    -webkit-backdrop-filter: none;
    backdrop-filter: none;
  }
}

::view-transition-old(contenu-app),
::view-transition-new(contenu-app) {
  mix-blend-mode: normal;
}

@media (prefers-reduced-motion: no-preference) {
  /* L'ancien écran s'efface vite, le nouveau n'apparaît qu'au moment où il a disparu : jamais deux
     textes superposés à moitié. Le nouvel écran démarre à 0,10 s ; l'ancien (0,12 s, linéaire) est
     alors à moins de 20 % d'opacité. */
  html:active-view-transition-type(avance)::view-transition-old(contenu-app) {
    animation: 0.12s linear both app-sort-vers-gauche;
  }

  html:active-view-transition-type(avance)::view-transition-new(contenu-app) {
    animation: 0.36s var(--courbe-app) 0.1s both app-entre-par-la-droite;
  }

  html:active-view-transition-type(recule)::view-transition-old(contenu-app) {
    animation: 0.12s linear both app-sort-vers-droite;
  }

  html:active-view-transition-type(recule)::view-transition-new(contenu-app) {
    animation: 0.36s var(--courbe-app) 0.1s both app-entre-par-la-gauche;
  }

  ::view-transition-group(onglet-actif) {
    animation-duration: 0.4s;
    animation-timing-function: var(--courbe-app);
  }

  /* Navigateur sans transitions entre pages : l'écran apparaît en douceur (classe posée par transitions-app.js). */
  .entree-douce .app main {
    animation: app-entre-en-douceur 0.3s var(--courbe-app) both;
  }
}

@keyframes app-sort-vers-gauche {
  to {
    opacity: 0;
    transform: translateX(-2.5rem);
  }
}

@keyframes app-sort-vers-droite {
  to {
    opacity: 0;
    transform: translateX(2.5rem);
  }
}

@keyframes app-entre-par-la-droite {
  from {
    opacity: 0;
    transform: translateX(2.5rem);
  }
}

@keyframes app-entre-par-la-gauche {
  from {
    opacity: 0;
    transform: translateX(-2.5rem);
  }
}

/* Écran d'accueil : le logo puis le nom montent, le rideau se lève. Une fois
   levé il est hors de l'écran et ne gêne plus les clics ; accueil.js le retire.
   Le rideau porte son propre nom de transition : sans lui, il resterait dans le
   calque de fond pendant le passage depuis la page de connexion, SOUS le contenu
   et la barre d'onglets (qui ont chacun leur calque), et l'on verrait
   l'application avant lui. Nommé, il arrive en fondu par-dessus tout le reste. */
@media (prefers-reduced-motion: no-preference) {
  .accueil-app {
    display: grid;
    view-transition-name: accueil;
    animation: accueil-leve 0.6s var(--courbe-app) 1.6s forwards;
  }

  .accueil-app__logo {
    animation: accueil-monte 0.55s var(--courbe) 0.25s both;
  }

  .accueil-app__texte {
    animation: accueil-monte 0.55s var(--courbe) 0.4s both;
  }
}

/* Arrivée depuis la page de connexion : seul le rideau entre, en fondu sur la page que
   l'on quitte. Les calques de l'application restent invisibles le temps du passage,
   sinon on la devinerait à travers le rideau encore translucide. */
html:has(.accueil-app)::view-transition-new(root),
html:has(.accueil-app)::view-transition-new(contenu-app),
html:has(.accueil-app)::view-transition-new(onglets),
html:has(.accueil-app)::view-transition-new(onglet-actif) {
  animation: none;
  opacity: 0;
}

html:has(.accueil-app)::view-transition-new(accueil) {
  animation: 0.3s ease-out both accueil-fondu;
}

@keyframes accueil-fondu {
  from {
    opacity: 0;
  }
}

@keyframes accueil-monte {
  from {
    opacity: 0;
    transform: translateY(1rem);
  }
}

@keyframes accueil-leve {
  to {
    transform: translateY(-100%);
  }
}

@keyframes app-entre-en-douceur {
  from {
    opacity: 0;
    transform: translateY(0.5rem);
  }
}

@media (prefers-reduced-motion: reduce) {
  ::view-transition-old(*),
  ::view-transition-new(*),
  ::view-transition-group(*) {
    animation-duration: 0s !important;
    animation-delay: 0s !important;
  }

  *,
  *::before,
  *::after {
    transition-duration: 0s !important;
  }
}
