/* Nunito Sans (licence SIL OFL 1.1, voir static/fonts/NUNITO-SANS-LICENSE.txt) :
   police VARIABLE (toutes les graisses de 200 à 1000 dans un seul fichier), sous-ensemble
   « latin » (français compris : é è ê à ç œ « » € …). Servie par le site lui-même (la
   CSP n'autorise que font-src 'self'). Les symboles absents (→, ▶, ✦) viennent de la
   police système. */
@font-face {
  font-family: "Nunito Sans";
  font-style: normal;
  font-weight: 200 1000;
  font-display: swap;
  src: url("../fonts/nunito-sans-latin-wght-normal.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Nunito Sans";
  font-style: italic;
  font-weight: 200 1000;
  font-display: swap;
  src: url("../fonts/nunito-sans-latin-wght-italic.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

:root {
  /* Palette du site (5 couleurs fournies par l'église) :
       #E3EAD9 vert très clair   #A2B78E vert sauge   #5E6E4F vert olive
       #3A4630 vert foncé        #F2EBC4 jaune pâle
     Le blanc sert aux cartes et aux champs de saisie. Contrastes vérifiés :
     texte #3A4630 sur #E3EAD9 = 8,1:1 ; blanc sur #5E6E4F = 5,5:1 ; #3A4630
     sur #A2B78E = 4,6:1. L'olive #5E6E4F seul sur #E3EAD9 ne fait que 4,5:1 :
     pour le texte courant atténué on utilise --color-text-muted, mélange
     50/50 olive + vert foncé (6,0:1). */
  --color-bg: #E3EAD9;
  --color-surface: #ffffff;
  --color-primary: #5E6E4F;
  --color-primary-dark: #3A4630;
  --color-accent: #A2B78E;
  --color-accent-text: #5E6E4F;
  --color-text: #3A4630;
  --color-text-muted: #4C5A3F;
  --color-border: #A2B78E;
  --color-bg-sunken: #F2EBC4;
  --color-yellow: #F2EBC4;
  --color-success-bg: #F2EBC4;
  --color-success-text: #3A4630;
  --color-error-bg: #fbe9e7;
  --color-error-text: #8a2c1f;
  --color-info: #2f7fad;
  /* Courbes du graphique "Statistiques" (bien distinctes sur fond blanc : la
     palette verte seule ne permet pas de séparer 5 courbes ; la sauge est
     assombrie en #7F9B63 pour rester lisible comme trait fin). */
  --chart-total: #3A4630;
  --chart-nouvelle: #2f7fad;
  --chart-attente: #9a7d1f;
  --chart-planifie: #7F9B63;
  --chart-en-cours: #5E6E4F;
  --radius: 14px;
  --shadow: 0 2px 10px rgba(58, 70, 48, 0.14);
  --max-width: 1080px;
  font-size: 17px;
}

* { box-sizing: border-box; }

html, body {
  margin: 0;
  padding: 0;
  background: var(--color-bg);
  color: var(--color-text);
  /* Police du site : Nunito Sans, EMBARQUÉE (static/fonts/, voir @font-face en
     tête de ce fichier) donc identique chez tous les visiteurs ; les polices
     système ne servent que de secours le temps du chargement. */
  font-family: "Nunito Sans", "Segoe UI", system-ui, -apple-system, Roboto, Helvetica, Arial, sans-serif;
  line-height: 1.55;
}

.container {
  max-width: var(--max-width);
  margin: 0 auto;
  padding: 0 1.5rem;
}

/* Tableau de bord admin (admin.html) : plus large que --max-width (utilisé
   par le reste du site) car le menu latéral (230px, voir .tabs-wrapper--
   sidebar) laisse peu de place aux tableaux larges (ex. "Gestion des
   travaux", voir .admin-table--travaux) sous cette limite — ce qui forçait
   un défilement horizontal même sur de grands écrans où la fenêtre du
   navigateur avait pourtant la place. Le tableau ne défile plus (voir
   .admin-table-scroll) que si la fenêtre elle-même est trop étroite,
   quelle que soit sa largeur réelle. */
.admin-container {
  max-width: 1400px;
}

.container.narrow {
  max-width: 640px;
}

/* Conteneur pleine largeur pour les carrousels : le nombre de dalles
   visibles s'adapte à la largeur réelle de l'écran, sans être limité par
   la largeur max habituelle du site. */
.container-wide {
  width: 100%;
  margin: 0 auto;
  padding: 0 1.5rem;
  box-sizing: border-box;
}

a { color: var(--color-primary-dark); }
a:hover { color: var(--color-primary); }

.skip-link {
  position: absolute;
  left: -999px;
  top: auto;
  background: var(--color-primary);
  color: #fff;
  padding: 0.75rem 1rem;
  border-radius: 0 0 8px 0;
  z-index: 100;
}
.skip-link:focus {
  left: 0;
  top: 0;
  z-index: 1000;
}

/* ---------- En-tête (par-dessus l'image du bandeau) ---------- */
/* L'en-tête est TRANSPARENT et se superpose à l'image du bandeau (hero) juste
   en dessous : l'image englobe donc le titre et le menu. Le bandeau est remonté
   de la hauteur de l'en-tête (--hero-top) et réserve cette place en haut.
   Toutes les hauteurs sont CALCULÉES par les variables ci-dessous (aucune
   mesure par script) ; l'en-tête ne reste plus collé en haut de l'écran.
   Avec un message flash (body.has-flash) le bandeau n'est pas remonté : le
   message s'intercale entre l'en-tête et le bandeau. */
body {
  --header-pad: 0.75rem;
  --title-size: clamp(0.8rem, 3.7vw, 2.4rem);
  --title-lh: 1.35;
  --nav-h: 2.5rem;
  --nav-gap: 1.3rem;
  --logo-h: max(44px, calc(var(--title-size) * 1.7));
  --header-h: calc(2 * var(--header-pad) + var(--logo-h));
  --hero-top: var(--header-h);
}
body.has-flash { --hero-top: 0px; }
/* En-tête FIXE en haut de l'écran (toutes largeurs), même quand on fait défiler la page.
   Le body réserve sa place (padding-top = --header-h, calculée) : la mise en page de départ
   est donc identique à l'ancienne (en-tête dans le flux). Il est transparent sur l'image du
   bandeau tant qu'on est en haut de page ; dès qu'on défile, main.js pose la classe
   .is-scrolled et il prend un fond plein (sinon le menu serait illisible sur le contenu).
   main.js publie aussi sa hauteur réelle (--header-offset) pour les ancres et éléments collants. */
body { padding-top: var(--header-h); }
html { scroll-padding-top: calc(var(--header-offset, 0px) + 0.75rem); }
.site-header {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 50;
  background: transparent;
  transition: background-color 0.2s ease, box-shadow 0.2s ease;
}
.site-header.is-scrolled {
  background: var(--color-bg);
  box-shadow: 0 2px 8px rgba(58, 70, 48, 0.25);
}
/* Deux dispositions :
   - grand écran (>= 1200px, voir plus bas) : le logo (colombe) à GAUCHE, sur
     deux rangées ; à droite le titre en grand (3,3rem = 3 x l'ancienne taille
     de 1,1rem), un espace, puis le menu. Hauteur du logo = ligne du titre +
     espace + menu ;
   - plus étroit (téléphone, tablette) : logo + titre + bouton "trois barres"
     sur UNE ligne ; le menu se déroule en liste par-dessus la page. */
.navbar {
  display: flex;
  align-items: center;
  justify-content: flex-start;
  padding: var(--header-pad) 1.5rem;
  min-height: var(--header-h);
  box-sizing: border-box;
  gap: 1rem;
  flex-wrap: nowrap;
  position: relative;
}
.brand-logo {
  display: block;
  flex-shrink: 0;
  line-height: 0;
  margin-right: -0.3rem;
}
.brand-logo .logo {
  display: block;
  height: var(--logo-h);
  width: auto;
}
.brand {
  display: flex;
  align-items: center;
  text-decoration: none;
  color: inherit;
  min-width: 0;
  flex-shrink: 1;
}
.site-title {
  display: block;
  font-size: var(--title-size);
  font-weight: 700;
  color: var(--color-primary-dark);
  line-height: var(--title-lh);
  min-width: 0;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.nav-toggle-input { display: none; }
.nav-toggle-label {
  display: none;
  margin-left: auto;
  flex-shrink: 0;
  flex-direction: column;
  justify-content: center;
  gap: 5px;
  width: 30px;
  height: 30px;
  cursor: pointer;
}
.nav-toggle-label span {
  display: block;
  height: 3px;
  border-radius: 2px;
  background: var(--color-primary-dark);
}

.nav-links {
  display: flex;
  gap: 0.3rem;
  flex-wrap: wrap;
}
.nav-links > a,
.nav-item > a {
  text-decoration: none;
  color: var(--color-text);
  font-weight: 600;
  padding: 0.5rem 0.8rem;
  border-radius: 999px;
  font-size: 0.95rem;
}
/* Sous-menus (sections de « Qui sommes nous ? » et « Activités ») */
.nav-item { position: relative; }
.submenu-toggle { display: none; }
.submenu {
  display: none;
  list-style: none;
  margin: 0;
  padding: 0.4rem;
}
.submenu a {
  display: block;
  padding: 0.45rem 0.8rem;
  border-radius: 8px;
  color: var(--color-text);
  font-weight: 500;
  font-size: 0.92rem;
  text-decoration: none;
}
.submenu a:hover,
.submenu a:focus-visible {
  background: var(--color-bg);
  color: var(--color-primary-dark);
}
/* Liens « Espace membre » / « Administration » (.header-links), toujours
   visibles : en grand écran à droite de la ligne du titre ; sous 1200px dans une
   fine rangée au-dessus du logo, cadrée à droite (voir le @media plus bas). */
.header-links {
  display: flex;
  gap: 1.4rem;
}
.header-links a {
  color: var(--color-primary-dark);
  font-weight: 600;
  font-size: 0.95rem;
  text-decoration: underline;
  text-underline-offset: 0.2em;
}
.header-links a:hover,
.header-links a[aria-current="page"] { color: var(--color-primary); }
.header-links a[aria-current="page"] { text-decoration-thickness: 2px; }
.nav-links > a:hover,
.nav-item > a:hover {
  background: rgba(255, 255, 255, 0.6);
  color: var(--color-primary-dark);
}
.nav-links > a[aria-current="page"],
.nav-item > a[aria-current="page"] {
  background: var(--color-primary);
  color: #fff;
}

@media (max-width: 1199px) {
  /* rangée des liens « Espace membre » / « Administration » au-dessus du logo :
     elle s'ajoute à la hauteur de l'en-tête (et donc du bandeau, --hero-top) */
  body {
    --links-h: 1.6rem;
    --header-h: calc(2 * var(--header-pad) + var(--logo-h) + var(--links-h));
  }
  .navbar { padding-top: calc(var(--header-pad) + var(--links-h)); }
  .header-links {
    position: absolute;
    top: 0.4rem;
    right: 1.5rem;
    gap: 1.1rem;
  }
  .header-links a { font-size: 0.82rem; }
  .nav-toggle-label { display: flex; }
  /* Menu déroulé : liste posée par-dessus la page (n'agrandit pas l'en-tête,
     donc ne décale pas le bandeau), sur fond plein pour rester lisible. */
  .nav-links {
    display: none;
    position: absolute;
    top: 100%;
    left: 1rem;
    right: 1rem;
    z-index: 60;
    flex-direction: column;
    gap: 0.2rem;
    padding: 0.5rem;
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    box-shadow: var(--shadow);
    /* l'en-tête étant fixe, le menu déroulé défile à l'intérieur s'il dépasse l'écran */
    max-height: calc(100vh - var(--header-offset, 6rem) - 1rem);
    overflow-y: auto;
  }
  .nav-links > a,
  .nav-item > a { padding: 0.7rem 0.9rem; }
  .nav-links > a:hover,
  .nav-item > a:hover { background: var(--color-bg); }
  .nav-toggle-input:checked ~ .nav-links { display: flex; }
  /* Entrée à sous-menu : lien + bouton ▾ qui déplie la liste des sections. */
  .nav-item {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
  }
  .nav-item > a { flex: 1 1 auto; }
  .submenu-toggle {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2.8rem;
    height: 2.8rem;
    background: none;
    border: 0;
    border-radius: 999px;
    color: var(--color-primary-dark);
    cursor: pointer;
  }
  .submenu-toggle:hover { background: var(--color-bg); }
  .submenu-toggle::before {
    content: "";
    padding: 3px;
    border: solid currentColor;
    border-width: 0 2px 2px 0;
    transform: rotate(45deg) translate(-2px, -2px);
    transition: transform 0.15s ease;
  }
  .nav-item.is-open .submenu-toggle::before { transform: rotate(-135deg) translate(-2px, -2px); }
  .submenu {
    flex: 1 0 100%;
    padding: 0 0 0.4rem 1rem;
    border-left: 3px solid var(--color-border);
    margin-left: 1rem;
  }
  .nav-item.is-open > .submenu { display: block; }
}

/* Grand écran : l'en-tête sur deux rangées avec le logo en pleine hauteur à
   gauche ; les liens « Espace membre » / « Administration » cadrés à droite de
   la ligne du titre. Seuil 1200px : sous cette largeur le menu ne tiendrait
   plus à côté du logo sans passer sur deux lignes, ce qui fausserait la
   hauteur du logo. Le titre rétrécit un peu (2,5 fois l'ancienne taille à
   1200px, 2,8 fois à 1280px) pour laisser la place aux deux liens ; il fait
   3,3rem (3 fois) dès ~1330px de large. */
@media (min-width: 1200px) {
  body {
    --title-size: min(3.3rem, calc((100vw - 26rem) / 16.2));
    --title-lh: 1.15;
    --logo-h: calc(var(--title-size) * var(--title-lh) + var(--nav-gap) + var(--nav-h));
  }
  /* Grand écran : le titre tient toujours (>= 1200px) ; on lève le
     "overflow: hidden" de la règle de base, qui rognait le bas du « g » à
     cause de l'interligne serré (1.15) nécessaire au calcul de --logo-h. */
  .site-title { overflow: visible; }
  .navbar {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr) auto;
    grid-template-rows: auto auto;
    column-gap: 1.1rem;
    row-gap: var(--nav-gap);
    max-width: 1600px;
  }
  .header-links {
    grid-column: 3;
    grid-row: 1;
    justify-self: end;
    align-self: center;
    position: static;
    gap: 1.4rem;
  }
  .brand-logo {
    grid-column: 1;
    grid-row: 1 / span 2;
    margin-right: 0;
  }
  .brand {
    grid-column: 2;
    grid-row: 1;
  }
  .nav-links {
    grid-column: 2 / span 2;
    grid-row: 2;
  }
  .nav-links > a,
  .nav-item > a {
    box-sizing: border-box;
    height: var(--nav-h);
    display: inline-flex;
    align-items: center;
  }
  .nav-item { display: inline-flex; }
  /* 9 entrées dans le menu : marges un peu réduites entre 1200 et 1399px pour
     qu'il reste sur UNE ligne (sinon la hauteur du logo ne suit plus). */
  .nav-links > a,
  .nav-item > a { padding-left: 0.6rem; padding-right: 0.6rem; }
  /* petit chevron ▾ : indique le sous-menu (ouvert au survol / au clavier) */
  .nav-item > a::after {
    content: "";
    margin-left: 0.5rem;
    padding: 2.5px;
    border: solid currentColor;
    border-width: 0 2px 2px 0;
    transform: rotate(45deg) translate(-1px, -2px);
    opacity: 0.7;
  }
  .submenu {
    position: absolute;
    top: 100%;
    left: 0;
    z-index: 70;
    min-width: 17rem;
    max-height: 70vh;
    overflow-y: auto;
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    box-shadow: var(--shadow);
  }
  .submenu--wide {
    min-width: 36rem;
    columns: 2;
    column-gap: 0.4rem;
  }
  .submenu li { break-inside: avoid; }
  .nav-item:hover > .submenu,
  .nav-item:focus-within > .submenu { display: block; }
  /* après un clic sur une section, le sous-menu se referme même si la souris
     est encore dessus (classe posée par main.js, retirée à la sortie) */
  .nav-item.submenu-closed > .submenu { display: none !important; }
}

/* ---------- Hero (page banner) ---------- */
/* Le bandeau remonte sous l'en-tête transparent (voir plus haut) : son image
   de fond couvre donc aussi la zone du titre et du menu. */
.page-hero {
  position: relative;
  margin-top: calc(-1 * var(--hero-top));
}
.page-hero-media {
  position: relative;
  box-sizing: border-box;
  /* pages autres que l'accueil : bandeau réduit à l'en-tête + le titre (et sous-titre) avec un
     petit espace au-dessus et en dessous (voir .page-hero-content) ; l'accueil a sa propre hauteur */
  min-height: var(--hero-top);
  padding-top: var(--hero-top);
  display: flex;
  align-items: center;
  /* Fond BLANC (volontairement hors palette) : la photo du temple (::before
     ci-dessous) y est posée à 50 % d'opacité max. */
  background-color: #fff;
  overflow: hidden;
}
/* Photo de l'intérieur du temple (6:1, comme le bandeau), derrière l'en-tête ET
   le bandeau de toutes les pages. Opacité en DÉGRADÉ horizontal : 0 % tout à
   gauche (fond blanc pur sous le logo et le titre) jusqu'à 50 % tout à droite
   — opacity: .5 plafonne le dégradé du masque (0 → 100 %) à 50 %. */
.page-hero-media::before {
  content: "";
  position: absolute;
  inset: 0;
  background: url("../img/temple-interieur.jpg") center / cover no-repeat;
  opacity: 0.5;
  -webkit-mask-image: linear-gradient(to right, transparent 0%, #000 100%);
  mask-image: linear-gradient(to right, transparent 0%, #000 100%);
}
/* Carrousel (« Gestion des défilements ») : remplace la photo fixe ci-dessus
   (::before masqué) et garde EXACTEMENT le même traitement : calque à 50 %
   d'opacité max., dégradé horizontal 0 % -> 100 % du masque, sur le fond blanc.
   Les photos glissent de droite à gauche (transform), une à la fois. */
.page-hero-media--slides::before { display: none; }
.hero-slides {
  position: absolute;
  inset: 0;
  overflow: hidden;
  opacity: 0.5;
  -webkit-mask-image: linear-gradient(to right, transparent 0%, #000 100%);
  mask-image: linear-gradient(to right, transparent 0%, #000 100%);
}
.hero-slide {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  transform: translateX(100%);
  transition: transform var(--hero-transition, 0.9s) ease-in-out;
}
.hero-slide.is-active { transform: translateX(0); }
.hero-slide.is-leaving { transform: translateX(-100%); }
.hero-slide.no-anim { transition: none; }
@media (prefers-reduced-motion: reduce) {
  .hero-slide { transition: none; }
}
/* Accueil : seulement la photo, sans texte ni église. Hauteur = la MOITIÉ de
   l'ancienne (en-tête + décor de proportion 1986x560 = 28,2vw), avec un
   plancher pour garder un peu d'image visible sous l'en-tête sur téléphone. */
.page-hero--home .page-hero-media {
  display: block;
  min-height: max(
    calc(var(--hero-top) + 6rem),
    calc((var(--hero-top) + 28.2vw) / 2)
  );
}
.hero-wave path { fill: var(--color-bg); }
/* Accueil : vague plus basse et cadres plus près du bandeau (peu d'espace sous les photos) */
.page-hero--home .hero-wave { height: 22px; }
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}
.page-hero-content {
  position: relative;
  z-index: 1;
  padding: 0.5rem 1.5rem 0.9rem;
  color: var(--color-primary-dark);
}
/* Le bandeau est clair partout (photo à 50 % max. sur fond blanc, sans voile) :
   titre et sous-titre en vert foncé, comme le titre de l'en-tête. */
.page-hero-content h1 {
  margin: 0 0 0.4rem;
  color: var(--color-primary-dark);
  font-size: 2.1rem;
  /* halo blanc : reste lisible par-dessus les zones chargées de la photo */
  text-shadow: 0 0 10px #fff, 0 0 4px #fff;
}
.hero-tagline {
  margin: 0;
  font-size: 1.05rem;
  max-width: 40rem;
  color: var(--color-primary-dark);
  font-weight: 500;
  text-shadow: 0 0 10px #fff, 0 0 4px #fff;
}
.hero-wave {
  display: block;
  width: 100%;
  height: 44px;
  margin-top: -2px;
}
.address { margin-top: 0; }

.intro-section {
  max-width: 46rem;
  margin: 2.5rem auto;
  color: var(--color-text-muted);
}
.intro-section ul {
  margin: 0 0 1rem;
  padding-left: 1.4rem;
  line-height: 1.7;
}
.intro-section li { margin-bottom: 0.3rem; }
.intro-section blockquote {
  white-space: pre-line;
  margin: 0 0 1rem;
  padding: 0.9rem 1.2rem;
  border-left: 3px solid var(--color-primary);
  background: var(--color-surface);
  border-radius: 0 var(--radius) var(--radius) 0;
  font-style: italic;
  line-height: 1.7;
}
.map-embed {
  position: relative;
  width: 100%;
  padding-top: 45%;
  margin: 1rem 0;
  border-radius: var(--radius);
  overflow: hidden;
  box-shadow: var(--shadow);
}
.map-embed iframe {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  border: 0;
}
/* Cadres de la page d'accueil, sous le bandeau : une grille de cartes (.home-card),
   une seule colonne tant qu'il n'y a qu'un cadre ; les suivants se placent à côté
   (assez de place) puis en dessous. */
.home-cards {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 26rem), 1fr));
  gap: 1.5rem;
  align-items: start;
  margin-top: 0.5rem;
  margin-bottom: 2.5rem;
}
.home-card {
  grid-column: 1 / -1; /* par défaut un cadre occupe toute la largeur (les uns sous les autres) ;
                          .home-card--half permet d'en placer deux côte à côte */
  box-sizing: border-box;
  background: var(--color-yellow); /* #F2EBC4 = R242 V235 B196 */
  border: 1px solid var(--color-border);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  padding: 2rem 2.25rem;
}
@media (max-width: 600px) {
  .home-card { padding: 1.25rem 1.1rem; }
}
.home-card--half { grid-column: auto; }
/* Quand il y a des activités spéciales ET assez de place à droite du cadre de texte
   (écran >= 1100px), leur cadre passe À DROITE du texte, en colonne étroite ; en
   dessous de cette largeur il reste sous le texte, sur toute la largeur. */
@media (min-width: 1100px) {
  .home-cards--side {
    grid-template-columns: minmax(0, 1fr) 22rem;
  }
  .home-cards--side .home-card { grid-column: auto; }
  .home-cards--side .home-specials,
  .home-cards--side .home-next { padding: 1.5rem 1.25rem; }
  .home-cards--side .home-specials-title { --title-max: 0.95rem; }
  .home-cards--side .agenda-date-badge { justify-self: start; min-width: 4.5rem; }
}
/* Trois cadres (texte, Prochainement, Activités spéciales) : sous 1400px le texte passe sur toute la
   largeur et les deux autres cadres se partagent la ligne du dessous ; dès 1400px les trois sont
   côte à côte (texte à gauche, deux colonnes de 22rem). */
/* Les deux cadres du côté sont dans .home-side-pair : empilés (< 1100px) le conteneur est invisible
   (display: contents) ; côte à côte (>= 1100px) c'est une grille à deux colonnes dont les cadres
   s'étirent à la MÊME hauteur. */
.home-side-pair { display: contents; }
@media (min-width: 1100px) {
  .home-side-pair {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    gap: 1.5rem;
    align-items: stretch;
  }
  /* cadres de même hauteur : colonne dont la partie centrale (l'événement) occupe la place restante,
     donc le pied (places + boutons) de chaque cadre est tout en bas */
  .home-side-pair .home-card { display: flex; flex-direction: column; }
  .home-side-pair .home-specials-viewport,
  .home-side-pair .home-next-event { flex: 1; }
  .home-side-pair .home-special,
  .home-side-pair .home-next-event { grid-template-rows: auto 1fr; }
  .home-side-pair .home-special-body { align-self: stretch; } /* le corps remplit la rangée : le pied descend en bas */
  /* « Activités spéciales » a une rangée de petits points sous l'événement quand il y en a plusieurs :
     on réserve la même place sous « Prochainement » pour que les boutons soient à la même hauteur */
  .home-side-pair--dots .home-next { padding-bottom: calc(1.5rem + var(--dots-h, 2.3rem)); /* 2,3rem = rangée de points : 0,7 + 2 x 0,35 + marge 0,9 */ }
}
@media (min-width: 1100px) and (max-width: 1399px) {
  .home-cards--three { grid-template-columns: minmax(0, 1fr); }
}
@media (min-width: 1400px) {
  .home-cards--three {
    grid-template-columns: minmax(0, 1fr) 45.5rem; /* 2 x 22rem + l'espace entre les cadres */
    align-items: stretch; /* les TROIS cadres côte à côte ont la même hauteur */
  }
}
/* les cadres sont des « containers » : la taille des titres suit leur largeur (voir .home-specials-title) */
.home-specials, .home-next { container-type: inline-size; }
/* Fond du cadre « Prochainement » : une grande horloge en filigrane (SVG, traits verts à 13 % d'opacité)
   à moitié coupée en bas à droite — le temps qui vient. Le texte reste par-dessus, inchangé. */
.home-next {
  background-image: url("../img/prochainement-horloge.svg");
  background-repeat: no-repeat;
  background-position: right -30px bottom -20px;
  background-size: 200px 200px;
  overflow: hidden;
}
/* Fond du cadre « Activités spéciales » : des étincelles (étoiles à quatre branches, comme celles du
   titre) en filigrane, en bas à droite. Le contenu glisse par-dessus, inchangé. */
.home-specials {
  background-image: url("../img/activites-speciales-etincelles.svg");
  background-repeat: no-repeat;
  background-position: right -10px bottom -10px;
  background-size: 200px 200px;
}
/* Cadre « Prochainement » : même présentation que « Activités spéciales », sans défilement */
.home-next-event {
  display: grid;
  grid-template-columns: 1fr; /* le texte est TOUJOURS sous la date, jamais à côté */
  gap: 0.7rem;
  align-items: start;
}
/* Cadre « Activités spéciales » : un événement à la fois, qui défile horizontalement.
   Tous les événements sont empilés dans la même cellule de grille (la hauteur est
   celle du plus grand) ; seul l'actif est visible et atteignable au clavier. */
/* Titre « Activités spéciales » : une pastille verte qui attire l'œil — reflet qui la
   traverse, onde lumineuse qui s'en échappe et deux étoiles qui scintillent. Texte
   blanc sur le vert olive de la palette (contraste conservé même sous le reflet).
   Tout est coupé si le visiteur demande moins d'animations. */
/* Une seule ligne : si le cadre est trop étroit, la police diminue (cqw = largeur du cadre, qui est un
   « container » : voir plus bas) ; --title-max = taille maximale (plus petite dans les cadres étroits). */
.home-specials-title {
  display: table;
  white-space: nowrap;
  margin: 0 auto 1.3rem;
  padding: 0.43em 1.3em;
  border-radius: 999px;
  color: #fff;
  font-size: 1.15rem;
  font-size: min(var(--title-max, 1.15rem), calc(100cqw / 19.5));
  letter-spacing: 0.06em;
  text-transform: uppercase;
  text-align: center;
  background: linear-gradient(110deg, #5e6e4f 0%, #5e6e4f 38%, #72866a 50%, #5e6e4f 62%, #5e6e4f 100%);
  background-size: 250% 100%;
  animation: special-shine 3.6s ease-in-out infinite, special-pulse 2.4s ease-out infinite;
}
.home-specials-title::before,
.home-specials-title::after {
  content: "✦";
  display: inline-block;
  margin: 0 0.6em;
  color: var(--color-yellow);
  animation: special-twinkle 1.8s ease-in-out infinite;
}
.home-specials-title::after { animation-delay: 0.9s; }
@keyframes special-shine {
  0% { background-position: 120% 0; }
  60%, 100% { background-position: -20% 0; }
}
@keyframes special-pulse {
  0% { box-shadow: 0 0 0 0 rgba(94, 110, 79, 0.55); }
  70%, 100% { box-shadow: 0 0 0 16px rgba(94, 110, 79, 0); }
}
@keyframes special-twinkle {
  0%, 100% { opacity: 1; transform: scale(1) rotate(0deg); }
  50% { opacity: 0.45; transform: scale(0.7) rotate(25deg); }
}
@media (prefers-reduced-motion: reduce) {
  .home-specials-title,
  .home-specials-title::before,
  .home-specials-title::after { animation: none; }
}
/* Titre « Prochainement » : même pastille, mais à la place des étoiles, trois chevrons « ››› » de chaque
   côté dont l'éclat avance de gauche à droite (ce qui vient). Le dégradé clair qui défile est
   découpé dans le texte (background-clip: text). */
.home-specials-title--next {
  /* pas d'onde qui s'échappe de la pastille : seulement le reflet qui la traverse */
  animation: special-shine 3.6s ease-in-out infinite;
}
.home-specials-title--next::before,
.home-specials-title--next::after {
  content: "›››";
  margin: 0 0.5em;
  font-size: 1.7em; /* le chevron « › » est petit dans cette police : on l'agrandit sans agrandir la pastille */
  line-height: 0.6;
  vertical-align: -0.12em;
  font-weight: 800;
  letter-spacing: 0.02em;
  color: transparent;
  background: linear-gradient(90deg, rgba(242, 235, 196, 0.45) 0%, rgba(242, 235, 196, 0.45) 30%, #fff 50%, rgba(242, 235, 196, 0.45) 70%, rgba(242, 235, 196, 0.45) 100%) 130% 0 / 300% 100% no-repeat;
  -webkit-background-clip: text;
  background-clip: text;
  animation: chevrons-run 1.5s linear infinite;
}
.home-specials-title--next::after { animation-delay: 0s; }
@keyframes chevrons-run {
  0% { background-position: 130% 0; }
  100% { background-position: -30% 0; }
}
@media (prefers-reduced-motion: reduce) {
  .home-specials-title--next { animation: none; }
  .home-specials-title--next::before,
  .home-specials-title--next::after {
    animation: none;
    background: none;
    color: var(--color-yellow);
  }
}
.home-specials-viewport { display: grid; overflow: hidden; }
.home-special {
  grid-area: 1 / 1;
  display: grid;
  grid-template-columns: 1fr; /* le texte est TOUJOURS sous la date, jamais à côté */
  gap: 0.7rem;
  align-items: start;
  visibility: hidden;
  transform: translateX(100%);
  transition: transform 0.9s ease-in-out;
}
/* Retour en arrière (points de navigation) : l'entrante vient de la GAUCHE et la sortante part
   vers la droite. */
.home-special.from-left { transform: translateX(-100%); }
.home-special.is-active { visibility: visible; transform: translateX(0); }
.home-special.is-leaving { visibility: visible; transform: translateX(-100%); }
.home-special.is-leaving-right { visibility: visible; transform: translateX(100%); }
.home-special.no-anim { transition: none; }
/* Petits points de navigation en bas du cadre (créés par main.js s'il y a 2 événements ou plus). */
.home-specials-dots {
  display: flex;
  justify-content: center;
  flex-wrap: wrap;
  gap: 0.1rem;
  margin-top: 0.9rem;
}
.home-specials-dot {
  box-sizing: content-box;
  width: 0.7rem;
  height: 0.7rem;
  padding: 0.35rem; /* zone de clic confortable autour du point */
  border: 0;
  background: transparent;
  cursor: pointer;
  position: relative;
}
.home-specials-dot::before {
  content: "";
  position: absolute;
  inset: 0.35rem;
  border-radius: 50%;
  border: 2px solid var(--color-primary);
  background: transparent;
  transition: background 0.2s ease, transform 0.2s ease;
}
.home-specials-dot:hover::before { background: var(--color-accent); }
.home-specials-dot[aria-current="true"]::before { background: var(--color-primary); transform: scale(1.15); }
.home-specials-dot:focus-visible { outline: 2px solid var(--color-accent); outline-offset: 0; border-radius: 50%; }
/* La date et, à sa droite, la petite photo de l'activité (même hauteur que la pastille de date) */
.home-special-lead { display: flex; align-items: stretch; gap: 0.7rem; }
.home-special-lead .agenda-date-badge { width: 5rem; box-sizing: border-box; }
.home-special-thumb {
  width: 5rem;
  height: auto;
  min-height: 4.2rem;
  object-fit: cover;
  border-radius: var(--radius);
  border: 1px solid var(--color-border);
  display: block;
}
.home-special-month {
  display: block;
  font-size: 0.65rem;
  color: var(--color-text-muted);
  margin-top: 0.15rem;
}
.home-special-body h3 { margin: 0 0 0.3rem; font-size: 1.15rem; color: var(--color-primary-dark); }
/* Boutons de l'activité : « Voir dans l'agenda » puis, à sa droite, « S'inscrire » (ou « Complet »)
   quand l'activité a des places ; ils passent à la ligne si la place manque. */
.home-special-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 0.6rem; }
/* Pied d'un cadre : places restantes (au-dessus) puis boutons ; calé en bas du corps de l'événement
   (margin-top:auto) pour que, dans deux cadres de même hauteur, les boutons soient à la même hauteur. */
.home-special-body { display: flex; flex-direction: column; }
.home-special-foot { margin-top: auto; }
.home-special-places { margin: 0.2rem 0 0.6rem; }
.home-special-places .agenda-capacity-pill { margin-top: 0; }
.home-special-text { margin: 0.3rem 0 0.8rem; color: var(--color-text-muted); line-height: 1.5; }
@media (max-width: 600px) {
  .home-special-lead .agenda-date-badge, .home-special-thumb { width: 4rem; }
}
@media (prefers-reduced-motion: reduce) {
  .home-special { transition: none; }
}
/* Cadre d'introduction (texte de présentation de l'église) */
.home-intro-banner { text-align: center; }
/* Fond : la photo de l'entrée du temple, en NOIR ET BLANC, à 20 % d'opacité au centre, centrée sur toute la hauteur du
   cadre ; ses bords gauche et droit se fondent jusqu'à 0 % (dégradé de masque). Le texte est par-dessus. */
.home-intro-banner {
  position: relative;
  overflow: hidden;
  isolation: isolate;
  background-color: var(--color-surface); /* fond BLANC (pas de jaune) : la photo en noir et blanc y ressort mieux */
}
.home-intro-banner::before {
  content: "";
  position: absolute;
  top: 0;
  bottom: 0;
  left: 50%;
  aspect-ratio: 9 / 16; /* proportions de la photo : la largeur suit la hauteur du cadre */
  transform: translateX(-50%);
  background: url("../img/temple-entree.jpg") center / cover no-repeat;
  opacity: 0.2;
  -webkit-mask-image: linear-gradient(to right, transparent 0%, #000 35%, #000 65%, transparent 100%);
  mask-image: linear-gradient(to right, transparent 0%, #000 35%, #000 65%, transparent 100%);
  pointer-events: none;
  z-index: -1;
}
.home-intro-header {
  max-width: 60rem;
  margin: 0 auto 1.8rem;
  color: var(--color-primary-dark);
  font-style: italic;
  font-size: 1.1rem;
  line-height: 1.75;
}
.home-intro-header-indent {
  display: inline-block;
  padding-left: 2em;
}
.home-intro-paragraph {
  max-width: 60rem;
  margin: 0 auto 1.2rem;
  color: var(--color-text-muted);
  font-size: 1.1rem;
  line-height: 1.75;
  text-align: justify;
}
.home-intro-paragraph:last-child { margin-bottom: 0; }
.intro-section h2 {
  color: var(--color-primary-dark);
}
.intro-section h3 {
  color: var(--color-primary-dark);
  margin-top: 1.5rem;
  margin-bottom: 0.4rem;
}
.intro-section-portrait {
  text-align: center;
  margin: 2rem 0;
}
.intro-section-portrait img {
  display: block;
  width: 160px;
  margin: 0 auto;
  border-radius: var(--radius);
  box-shadow: var(--shadow);
}
/* Photo dans un CADRE centré (paragraphe {"image", "frame": true} de content.json) : fond blanc,
   bordure, coins arrondis, ombre ; "large": true l'agrandit (photo de groupe). */
.intro-section-portrait--framed img {
  box-shadow: none;
  border-radius: calc(var(--radius) - 4px);
}
.intro-section-portrait--framed {
  width: fit-content;
  max-width: 100%;
  margin: 1.5rem auto;
  padding: 0.6rem;
  box-sizing: border-box;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
}
.intro-section-portrait--large { width: 19.3rem; } /* 18rem de photo + cadre : la légende revient à la ligne au lieu d'élargir le cadre */
.intro-section-portrait--large img {
  width: 18rem;
  max-width: 100%;
  height: auto;
}
.intro-section-portrait figcaption {
  white-space: pre-line;
  margin-top: 0.7rem;
  font-style: italic;
  line-height: 1.5;
}

.section-title {
  color: var(--color-primary-dark);
  margin: 2.5rem 0 1.25rem;
}

/* ---------- Page unique par menu (Qui sommes-nous ?, Activités, Services) :
   sommaire fixé pendant le défilement + sections illustrées ---------- */
.menu-full-page {
  display: grid;
  grid-template-columns: 220px minmax(0, 46rem);
  justify-content: center;
  gap: 3rem;
  align-items: start;
  padding: 2.5rem 0 3rem;
}
.menu-full-page--solo {
  grid-template-columns: minmax(0, 46rem);
}
.menu-toc {
  position: sticky;
  top: calc(var(--header-offset, 0px) + 1.5rem);
  scroll-margin-top: 1.5rem;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius);
  padding: 1.1rem 1.2rem;
}
/* Mobile uniquement (le sommaire n'est plus fixé, voir plus bas) : lien
   qui reste visible en haut de l'écran pendant le défilement pour
   revenir rapidement au sommaire, tout en haut de la page. */
.menu-toc-jump {
  display: none;
}
.menu-toc-label {
  margin: 0 0 0.6rem;
  font-size: 0.75rem;
  font-weight: 700;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--color-text-muted);
}
.menu-toc ul {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 0.05rem;
}
.menu-toc-link {
  display: block;
  padding: 0.22rem 0.6rem;
  border-radius: 6px;
  border-left: 3px solid transparent;
  color: var(--color-text);
  text-decoration: none;
  font-size: 0.92rem;
  line-height: 1.3;
}
.menu-toc-link:hover {
  background: var(--color-bg);
  color: var(--color-primary-dark);
}
.menu-toc-link.is-active {
  border-left-color: var(--color-primary);
  background: var(--color-bg);
  color: var(--color-primary-dark);
  font-weight: 600;
}

.menu-full-section {
  scroll-margin-top: 1.5rem;
  padding-bottom: 1.5rem;
  margin-bottom: 1.5rem;
  border-bottom: 1px solid var(--color-border);
}
.menu-full-section:last-child {
  border-bottom: none;
  margin-bottom: 0;
  padding-bottom: 0;
}
.menu-full-section-head {
  display: flex;
  align-items: center;
  gap: 1rem;
  margin-bottom: 0.5rem;
}
.menu-full-section-icon {
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 52px;
  height: 52px;
  font-size: 1.6rem;
  line-height: 1;
  background: var(--color-bg);
  border-radius: 50%;
}
.menu-full-section-head h2 {
  margin: 0;
  color: var(--color-primary-dark);
}
.menu-full-section-body {
  margin: 0;
}

@media (max-width: 860px) {
  .menu-full-page {
    grid-template-columns: minmax(0, 1fr);
    /* Le "gap: 3rem" ci-dessus sert d'écart horizontal sommaire/contenu en
       desktop ; en une seule colonne (mobile), ce même gap s'applique
       aussi entre les lignes empilées (sommaire, puis contenu) — beaucoup
       trop d'espace vertical pour cet usage-là. */
    gap: 0.5rem;
  }
  .menu-toc {
    position: static;
    margin-bottom: 0.5rem;
  }
  /* En-tête non collé : seul le bouton fixe "Retourner au sommaire" est à
     éviter lors d'un saut de sommaire. */
  .menu-full-section,
  .month-head {
    scroll-margin-top: 4.5rem;
  }
  .menu-toc-jump {
    display: inline-block;
    justify-self: start;
    position: sticky;
    top: calc(var(--header-offset, 0px) + 0.75rem);
    z-index: 40;
    margin-bottom: 0.6rem;
    padding: 0.45rem 0.9rem;
    background: var(--color-primary);
    color: #fff;
    text-decoration: none;
    font-size: 0.85rem;
    font-weight: 600;
    border-radius: 999px;
    box-shadow: var(--shadow);
  }
}

/* Pages « Qui sommes-nous ? », « Activités » et « Services » (menu_full_page.html) : les textes
   utilisent TOUTE la largeur de l'écran (seul le sommaire garde 220px) au lieu d'une colonne de
   46rem. Réservé au grand écran : en une colonne (<= 860px) la règle de base suffit. La page
   Agenda (evenements.html) partage .menu-full-page et reste inchangée. */
/* peu d'espace entre le bandeau et le premier texte (base : 2.5rem) */
.menu-full-page--wide { padding-top: 0.25rem; }
@media (min-width: 861px) {
  .menu-full-page--wide {
    grid-template-columns: 220px minmax(0, 1fr);
    justify-content: stretch;
  }
  .menu-full-page--wide.menu-full-page--solo { grid-template-columns: minmax(0, 1fr); }
  .menu-full-page--wide .menu-full-section-body { max-width: none; }
}

/* ---------- Cards ---------- */
.card-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(270px, 1fr));
  gap: 1.5rem;
}
.card {
  position: relative;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius);
  padding: 1.5rem;
  box-shadow: var(--shadow);
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
  overflow: hidden;
}
/* Pousse le bouton (S'inscrire, Ouvrir, Regarder sur YouTube, Complet...) en bas
   de la carte, quelle que soit la longueur du texte au-dessus. */
.card > .btn,
.card > .btn-disabled,
.card > .dropdown,
.card > .card-actions {
  margin-top: auto;
}
/* Regroupe plusieurs actions (ex. "S'inscrire" + "Envoyer à mon agenda")
   côte à côte, alignées en bas de la carte. */
.card-actions {
  display: flex;
  align-items: flex-start;
  gap: 0.6rem;
  flex-wrap: wrap;
}

/* Menu déroulant "Ouvrir" (espace membre) */
.dropdown summary {
  display: inline-block;
  list-style: none;
  cursor: pointer;
}
.dropdown summary::-webkit-details-marker { display: none; }
.dropdown summary::marker { content: ""; }
.dropdown summary::after {
  content: "";
  display: inline-block;
  margin-left: 0.5em;
  vertical-align: middle;
  width: 0;
  height: 0;
  border-left: 0.64em solid transparent;
  border-right: 0.64em solid transparent;
  border-top: 0.76em solid #fff;
  transition: transform 0.15s ease;
}
.dropdown[open] summary::after {
  transform: rotate(180deg);
}
.dropdown[open] summary {
  margin-bottom: 0.6rem;
}
.dropdown-menu {
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
}
.dropdown-menu a {
  display: block;
  padding: 0.55rem 0.9rem;
  border-radius: 8px;
  background: var(--color-bg);
  color: var(--color-primary-dark);
  text-decoration: none;
  font-weight: 600;
  border: 1px solid var(--color-border);
}
.dropdown-menu a:hover {
  background: var(--color-primary);
  color: #fff;
}

/* Formulaire "Envoyer à mon agenda" (événements) */
.agenda-form {
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
}
.agenda-form .form-field input {
  width: 100%;
}
.agenda-form-actions {
  display: flex;
  gap: 0.6rem;
  flex-wrap: wrap;
}
.btn-sm {
  padding: 0.5rem 1rem;
  font-size: 0.9rem;
}

/* Galerie photo (espace membre) */
.photo-gallery {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: 1.25rem;
}
/* Page « Photos » du menu : vignettes 2 fois plus grandes (colonnes de 440px
   au lieu de 220px ; min() pour ne jamais dépasser sur téléphone). */
.photo-gallery--large {
  grid-template-columns: repeat(auto-fill, minmax(min(440px, 100%), 1fr));
}
.photo-gallery-item {
  display: block;
  border-radius: var(--radius);
  overflow: hidden;
  box-shadow: var(--shadow);
  border: 1px solid var(--color-border);
  aspect-ratio: 4 / 3;
}
.photo-gallery-item img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  transition: transform 0.2s ease;
}
.photo-gallery-item:hover img {
  transform: scale(1.05);
}

/* Grille de photos avec suppression (espace admin, "Gestion des photos") */
#defilement-seconds { width: 8rem; max-width: 100%; }
.admin-photo-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(160px, 1fr));
  gap: 1rem;
  margin: 1rem 0 2rem;
}
.admin-photo-grid-item {
  border-radius: var(--radius);
  overflow: hidden;
  box-shadow: var(--shadow);
  border: 1px solid var(--color-border);
  background: var(--color-surface);
}
.admin-photo-grid-item img {
  width: 100%;
  aspect-ratio: 4 / 3;
  object-fit: cover;
  display: block;
}
.admin-photo-grid-item form {
  display: flex;
  justify-content: center;
  padding: 0.5rem;
}
/* Liste de vidéos (espace admin, "Gestion des vidéos") : une colonne
   plutôt qu'une grille de vignettes (une vidéo avec ses contrôles a
   besoin de plus de place qu'une photo en aperçu). */
.admin-video-list {
  display: flex;
  flex-direction: column;
  gap: 1.5rem;
  margin: 1rem 0 2rem;
}
.admin-video-list-item {
  max-width: 720px;
}
.admin-video-list-item form {
  margin-top: 0.5rem;
}
.season-video {
  display: block;
  width: 100%;
  max-width: 720px;
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  border: 1px solid var(--color-border);
  background: #000;
  margin-bottom: 1.25rem;
}

/* Tâches du "Groupe travaux" (espace admin "Gestion des travaux" + espace
   membre "Consulter les travaux") */
/* Piège déjà vécu avec .agenda-row (voir .agenda-row[hidden] plus bas) :
   .card définit display: flex, qui annule silencieusement la règle
   [hidden] { display: none } du navigateur (même spécificité, mais la
   feuille de style de l'auteur l'emporte sur celle, plus basse priorité,
   du navigateur) — sans cette règle, le filtre par statut de la page
   "Consulter les travaux" (voir .travaux-filters dans main.js) masquait
   l'attribut hidden en DOM sans jamais rien cacher visuellement. */
.travaux-card[hidden] {
  display: none;
}
.travaux-new-badge {
  display: inline-block;
  font-size: 0.78rem;
  font-weight: 700;
  padding: 0.15rem 0.55rem;
  border-radius: 999px;
  background: var(--color-accent);
  color: var(--color-primary-dark);
  margin-bottom: 0.4rem;
}
.travaux-statut-pill {
  display: inline-block;
  font-size: 0.82rem;
  font-weight: 600;
  padding: 0.2rem 0.7rem;
  border-radius: 999px;
  margin-bottom: 0.4rem;
}
/* Les 5 statuts suivent la palette du plus clair au plus foncé (progression
   de la tâche) : jaune pâle, vert très clair, sauge, olive, vert foncé. */
.travaux-statut-pill.statut-nouvelle_tache {
  background: var(--color-yellow);
  color: var(--color-primary-dark);
  box-shadow: inset 0 0 0 1px var(--color-accent);
}
.travaux-statut-pill.statut-en_attente {
  background: var(--color-bg);
  color: var(--color-primary-dark);
  box-shadow: inset 0 0 0 1px var(--color-accent);
}
.travaux-statut-pill.statut-planifie {
  background: var(--color-accent);
  color: var(--color-primary-dark);
}
.travaux-statut-pill.statut-en_cours {
  background: var(--color-primary);
  color: #fff;
}
.travaux-statut-pill.statut-termine {
  background: var(--color-primary-dark);
  color: #fff;
}
/* Filtre par statut au-dessus du tableau "À réaliser" (admin.html) : les
   pastilles réutilisent directement les couleurs de .travaux-statut-pill
   ci-dessus (mêmes classes statut-X) pour que le bouton de filtre ait la
   même couleur que le statut qu'il filtre. La pastille active est mise en
   avant par une bordure + opacité pleine ; les autres sont atténuées
   (opacité réduite) pour que la sélection actuelle reste repérable. */
.travaux-filters {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  /* Pas de margin-bottom propre : côté admin, l'espace jusqu'au tableau
     vient déjà du margin-top de .admin-table (1.5rem, hérité, inchangé)
     — exactement la même valeur que le margin-bottom de .tab-labels
     au-dessus des boutons de filtre, pour un espacement symétrique.
     Ajouter une marge ici s'additionnerait aux deux et casserait cette
     symétrie. Côté espace membre (.card-grid, sans margin-top propre),
     l'espacement équivalent est ajouté séparément ci-dessous. */
  margin: 0;
}
/* Espace membre (members_travaux.html) : .card-grid n'a pas de margin-top
   propre (dans les autres pages, l'espacement vient du margin-bottom du
   .section-title juste au-dessus) — ajouté ici spécifiquement quand une
   grille de cartes suit .travaux-filters, avec la même valeur (1.25rem)
   que le margin-bottom de .section-title au-dessus des boutons, pour un
   espacement symétrique équivalent à celui du tableau admin. */
.travaux-filters + .card-grid {
  margin-top: 1.25rem;
}
.travaux-filter-chip {
  cursor: pointer;
  border: 2px solid transparent;
  opacity: 0.8;
  transition: opacity 0.15s ease;
}
.travaux-filter-chip:hover {
  opacity: 1;
}
.travaux-filter-chip.is-active {
  opacity: 1;
  border-color: var(--color-text);
}
.travaux-filter-chip--tous {
  background: var(--color-surface);
  border-color: var(--color-border);
  color: var(--color-text-muted);
  font-size: 0.82rem;
  font-weight: 600;
  padding: 0.2rem 0.7rem;
  border-radius: 999px;
}
.travaux-filter-chip--tous.is-active {
  border-color: var(--color-text);
}
/* Tri par colonne (Lieu, Statut, dates) au clic sur l'en-tête, admin.html
   — voir .admin-table--travaux th[data-sortable] dans main.js. Flèche
   neutre au repos, orientée selon le sens de tri actif. */
.admin-table--travaux th[data-sortable] {
  cursor: pointer;
  user-select: none;
}
.admin-table--travaux th[data-sortable]:hover {
  color: var(--color-text);
}
.admin-table--travaux th[data-sortable]::after {
  content: "↕";
  display: inline-block;
  margin-left: 0.3rem;
  font-size: 1.1rem;
  line-height: 1;
  vertical-align: -0.1em;
  opacity: 0.5;
}
.admin-table--travaux th[data-sortable][data-sort-dir="asc"]::after {
  content: "↑";
  opacity: 1;
}
.admin-table--travaux th[data-sortable][data-sort-dir="desc"]::after {
  content: "↓";
  opacity: 1;
}
/* Onglet "Statistiques" (members_travaux.html) : graphique SVG rendu
   entièrement côté serveur (coordonnées calculées en Python — voir
   _travaux_chart_data dans app.py), pas de bibliothèque JS externe (le
   site n'en charge aucune, tout est self-hosted). Les <circle> avec
   <title> à l'intérieur donnent une infobulle native au survol, sans
   JS. */
.travaux-chart-wrap {
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius);
  padding: 1rem 1.25rem 0.5rem;
  box-shadow: var(--shadow);
}
.travaux-chart {
  width: 100%;
  height: auto;
  display: block;
}
.travaux-chart-gridline {
  stroke: var(--color-border);
  stroke-width: 1;
}
.travaux-chart-axis {
  stroke: var(--color-text-muted);
  stroke-width: 1;
}
.travaux-chart-axis-label {
  font-size: 10px;
  fill: var(--color-text-muted);
}
.travaux-chart-line {
  vector-effect: non-scaling-stroke;
}
.travaux-chart-legend {
  display: flex;
  flex-wrap: wrap;
  gap: 1rem;
  justify-content: center;
  padding: 0.6rem 0 0.8rem;
  font-size: 0.85rem;
  color: var(--color-text-muted);
}
.travaux-chart-legend-item {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
}
.travaux-chart-swatch {
  width: 14px;
  height: 3px;
  border-radius: 2px;
  display: inline-block;
}
.travaux-chart-swatch--total {
  background: repeating-linear-gradient(
    to right,
    var(--chart-total) 0 5px,
    transparent 5px 8px
  );
}
/* Une classe par statut plutôt qu'un style="background:..." inline : le
   CSP du site (style-src 'self', voir register_security_headers dans
   app.py) bloque silencieusement tout style inline, ce qui rendait ces
   pastilles invisibles (transparentes) sans lever la moindre erreur JS. */
.travaux-chart-swatch--nouvelle_tache {
  background: var(--chart-nouvelle);
}
.travaux-chart-swatch--en_attente {
  background: var(--chart-attente);
}
.travaux-chart-swatch--planifie {
  background: var(--chart-planifie);
}
.travaux-chart-swatch--en_cours {
  background: var(--chart-en-cours);
}
.travaux-chart-note {
  color: var(--color-text-muted);
  font-size: 0.85rem;
  margin-top: 0.75rem;
}
.travaux-photos {
  display: flex;
  flex-wrap: wrap;
  gap: 0.6rem;
  margin-top: 0.6rem;
}
.travaux-photo-item {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.3rem;
  font-size: 0.78rem;
  color: var(--color-text-muted);
  text-decoration: none;
}
.travaux-photo-item img {
  width: 90px;
  height: 90px;
  object-fit: cover;
  border-radius: 8px;
  border: 1px solid var(--color-border);
}
/* Édition d'une tâche (admin_travaux_tache.html) : une vignette + son
   bouton "Supprimer" par photo avant/après déjà présente, plusieurs
   possibles côte à côte (voir admin_delete_travaux_tache_photo).
   .travaux-current-photo (singulier, sans -s) est aussi réutilisée telle
   quelle par admin_agenda_event.html pour l'image (unique) d'un
   événement — nom conservé malgré le préfixe "travaux" pour éviter de
   dupliquer une règle par ailleurs identique. */
.travaux-current-photos {
  display: flex;
  flex-wrap: wrap;
  gap: 0.8rem;
  margin: 0.5rem 0;
}
.travaux-current-photo {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.4rem;
}
.travaux-current-photo img {
  width: 140px;
  height: 140px;
  object-fit: cover;
  border-radius: 8px;
  border: 1px solid var(--color-border);
  display: block;
}

/* ---------- Rapport d'une tâche du groupe travaux ---------- */
/* Mise en forme d'un rapport (éditeur riche de l'admin + affichage espace
   membre) : la CSP (style-src 'self') interdit les attributs style en ligne,
   report_html.py convertit donc tout style en CLASSES prédéfinies —
   rf-f-* (police), rf-s-* (taille), rf-c-* (couleur), à garder alignées avec
   REPORT_FONTS/REPORT_SIZES/REPORT_COLORS de ce module (pas de sélecteur
   générique dans ce projet, voir directives point 9). Les tailles sont en em :
   elles suivent la taille de base du conteneur (éditeur, fenêtre ou
   miniature). */
.rich-report p { margin: 0 0 0.6em; }
.rich-report p:last-child { margin-bottom: 0; }
.rich-report ul,
.rich-report ol { margin: 0 0 0.6em; padding-left: 1.4em; }
.rf-f-arial { font-family: Arial, Helvetica, sans-serif; }
.rf-f-georgia { font-family: Georgia, "Times New Roman", serif; }
.rf-f-times { font-family: "Times New Roman", Times, serif; }
.rf-f-verdana { font-family: Verdana, Geneva, sans-serif; }
.rf-f-trebuchet { font-family: "Trebuchet MS", Helvetica, sans-serif; }
.rf-f-courier { font-family: "Courier New", Courier, monospace; }
.rf-f-comic { font-family: "Comic Sans MS", "Comic Neue", cursive; }
.rf-s-petit { font-size: 0.85em; }
.rf-s-grand { font-size: 1.3em; }
.rf-s-tres-grand { font-size: 1.7em; }
.rf-c-noir { color: #222222; }
.rf-c-rouge { color: #c0392b; }
.rf-c-orange { color: #d9822b; }
.rf-c-vert { color: #2e8b57; }
.rf-c-bleu { color: #2f7fad; }
.rf-c-violet { color: #7b4fa3; }
.rf-c-marron { color: #7a3b2e; } /* couleur de TEXTE au choix de l'auteur : inchangée */
.rf-c-gris { color: #777777; }

/* Éditeur (admin_travaux_tache.html, voir main.js) : sans JS, seule la
   <textarea> de secours est visible ; main.js ajoute .is-enhanced pour
   montrer la barre d'outils + la zone éditable et masquer la textarea. */
.rich-editor-wrap {
  border: 1px solid var(--color-border);
  border-radius: 8px;
  background: var(--color-surface);
}
.rich-editor-wrap:focus-within {
  outline: 2px solid var(--color-accent);
  outline-offset: 1px;
}
.rich-editor-wrap:not(.is-enhanced) .rich-toolbar,
.rich-editor-wrap:not(.is-enhanced) .rich-editor { display: none; }
.rich-editor-wrap.is-enhanced .rich-editor-source { display: none; }
.rich-editor-wrap .rich-editor-source { border: 0; width: 100%; }
.rich-toolbar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.4rem;
  padding: 0.5rem;
  border-bottom: 1px solid var(--color-border);
  background: var(--color-bg-sunken);
  border-radius: 8px 8px 0 0;
}
.rich-btn {
  min-width: 2rem;
  height: 2rem;
  padding: 0 0.5rem;
  border: 1px solid var(--color-border);
  border-radius: 6px;
  background: var(--color-surface);
  color: var(--color-text);
  font: inherit;
  font-size: 0.9rem;
  cursor: pointer;
}
.rich-btn:hover { border-color: var(--color-accent); }
.rich-btn[aria-pressed="true"] {
  background: var(--color-primary);
  border-color: var(--color-primary);
  color: #fff;
}
.rich-editor-wrap .rich-select {
  height: 2rem;
  padding: 0 0.4rem;
  font-size: 0.9rem;
  max-width: 9rem;
}
.rich-swatches {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  padding: 0 0.3rem;
}
/* La couleur de la pastille est celle de sa classe rf-c-* (background:
   currentColor) : une seule définition par couleur. */
.rich-swatch {
  width: 1.4rem;
  height: 1.4rem;
  padding: 0;
  border: 2px solid #fff;
  border-radius: 50%;
  box-shadow: 0 0 0 1px var(--color-border);
  background: currentColor;
  cursor: pointer;
}
.rich-swatch:hover { box-shadow: 0 0 0 2px var(--color-accent); }
.rich-editor {
  min-height: 12rem;
  padding: 0.8rem;
  overflow: auto;
  resize: vertical;
  outline: none;
  border-radius: 0 0 8px 8px;
}

/* Espace membre (members_travaux.html) : bouton du dossier de suivi en PDF,
   juste au-dessus des onglets (voir members_travaux_pdf dans app.py). */
.travaux-pdf-cta { margin: 0.25rem 0 1.25rem; }

/* Espace membre (members_travaux.html) : miniature "Rapport" au bas de la
   tuile (même gabarit que les miniatures avant/après, .travaux-photo-item)
   + fenêtre <dialog> qui s'ouvre au clic (voir main.js). */
.rapport-thumb {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.3rem;
  font-size: 0.78rem;
  color: var(--color-text-muted);
  text-decoration: none;
}
.rapport-thumb-page {
  position: relative;
  width: 90px;
  height: 90px;
  overflow: hidden;
  padding: 0.4rem 0.45rem;
  border: 1px solid var(--color-border);
  border-radius: 8px;
  background: var(--color-bg-sunken);
  color: var(--color-text);
  font-size: 0.42rem;
  line-height: 1.3;
  text-align: left;
}
.rapport-thumb-page::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 1.6rem;
  background: linear-gradient(to bottom, transparent, var(--color-bg-sunken));
}
.rapport-thumb:hover .rapport-thumb-page,
.rapport-thumb:focus-visible .rapport-thumb-page {
  border-color: var(--color-accent);
  box-shadow: var(--shadow);
}
.rapport-dialog {
  width: min(42rem, 92vw);
  max-height: 85vh;
  padding: 0;
  border: 0;
  border-radius: var(--radius);
  background: var(--color-surface);
  color: var(--color-text);
  box-shadow: 0 12px 40px rgba(58, 70, 48, 0.4);
}
.rapport-dialog[open] {
  display: flex;
  flex-direction: column;
}
.rapport-dialog::backdrop { background: rgba(58, 70, 48, 0.6); }
.rapport-dialog-head {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: 1rem;
  padding: 1rem 1.25rem;
  border-bottom: 1px solid var(--color-border);
}
.rapport-dialog-head h3 { margin: 0; }
.rapport-dialog-head .card-description { margin: 0.2rem 0 0; }
.rapport-dialog-body {
  padding: 1.1rem 1.25rem 1.4rem;
  overflow: auto;
}

/* Planning du service d'accueil (extrait automatiquement de l'agenda PDF) */
.accueil-table {
  width: 100%;
  border-collapse: collapse;
  margin: 1rem 0 2rem;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius);
  overflow: hidden;
}
.accueil-table th,
.accueil-table td {
  text-align: left;
  padding: 0.65rem 1rem;
  border-bottom: 1px solid var(--color-border);
}
.accueil-table th {
  background: var(--color-bg);
  color: var(--color-primary-dark);
}
.accueil-table tr:last-child td {
  border-bottom: none;
}
.card-bg-image {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
  opacity: 0.14;
  z-index: 0;
  pointer-events: none;
}
.card h3 { margin: 0.2rem 0 0; color: var(--color-primary-dark); }
.card-schedule {
  color: var(--color-accent-text);
  font-weight: 600;
  margin: 0;
  font-size: 0.95rem;
}
.card-description {
  color: var(--color-text-muted);
  margin: 0.2rem 0 0.5rem;
}
.card-capacity {
  font-size: 0.9rem;
  color: var(--color-text-muted);
  margin: 0;
}
.empty {
  color: var(--color-text-muted);
  font-style: italic;
}

/* ---------- Agenda : filtre par type d'événement ---------- */
.agenda-filters {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin: 0 0 1rem;
}
.filter-chip {
  flex: 0 0 auto;
  padding: 0.45rem 1rem;
  border-radius: 999px;
  border: 1px solid var(--color-border);
  background: var(--color-surface);
  color: var(--color-text-muted);
  font: inherit;
  font-size: 0.85rem;
  font-weight: 600;
  cursor: pointer;
}
.filter-chip.is-active {
  background: var(--color-primary);
  border-color: var(--color-primary);
  color: #fff;
}
@media (max-width: 600px) {
  /* Les pastilles passent à la ligne (comme sur desktop) plutôt que de
     défiler horizontalement : avec 6-7 catégories possibles, un défilement
     sans indice visuel cachait des choix — moins découvrable qu'un simple
     retour à la ligne. */
  .filter-chip {
    padding: 0.4rem 0.8rem;
    font-size: 0.8rem;
  }
}

/* ---------- Agenda : liste chronologique groupée par mois ---------- */
.agenda-list {
  display: flex;
  flex-direction: column;
  background: var(--color-bg-sunken);
  border: 1px solid var(--color-border);
  border-radius: var(--radius);
  padding: 0.2rem 1.5rem 1.4rem;
  margin-top: 1.5rem;
}
.month-head {
  scroll-margin-top: 1.5rem;
  font-size: 0.85rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--color-text-muted);
  margin: 1.6rem 0 0.4rem;
}
.month-head:first-child { margin-top: 1.4rem; }
.agenda-row {
  /* 2 colonnes : la pastille de date et, à côté, le titre + l'horaire ; puis, SOUS la pastille, le
     texte explicatif sur TOUTE la largeur du cadre, la photo et les boutons */
  display: grid;
  grid-template-columns: 4.5rem minmax(0, 1fr);
  gap: 0.6rem 1.2rem;
  align-items: start;
  padding: 1.1rem 0;
  border-top: 1px solid var(--color-border);
}
.agenda-list .month-head + .agenda-row { border-top: none; }
/* Le filtre par type (main.js) cache des lignes via l'attribut natif
   [hidden] — mais "display: grid" ci-dessus est une règle d'AUTEUR, qui
   l'emporte toujours sur la règle UA par défaut "[hidden] { display:
   none }" (même à spécificité égale, une règle d'auteur bat une règle
   du navigateur). Sans cette ligne, l'attribut hidden n'a alors aucun
   effet visuel : la ligne reste affichée. Un sélecteur combiné avec
   [hidden] a une spécificité plus forte que .agenda-row seul, donc il
   gagne quel que soit l'ordre dans le fichier. */
.agenda-row[hidden] { display: none; }
/* événement atteint par un lien « #event-... » (voir main.js) : brève mise en évidence */
.agenda-row--target { animation: agenda-target 2.5s ease-out; }
@keyframes agenda-target {
  0%, 40% { background: var(--color-bg); box-shadow: 0 0 0 0.5rem var(--color-bg); }
  100% { background: transparent; box-shadow: 0 0 0 0.5rem transparent; }
}
@media (prefers-reduced-motion: reduce) { .agenda-row--target { animation: none; } }
.agenda-date-badge {
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius);
  text-align: center;
  padding: 0.4rem 0 0.45rem;
  grid-row: 1;
}
.agenda-row-body { grid-column: 2; }
.agenda-row-desc,
.agenda-row-actions,
.agenda-row-media { grid-column: 1 / -1; }
.agenda-row-desc { margin: 0; }
.agenda-day {
  display: block;
  font-size: 1.4rem;
  font-weight: 700;
  line-height: 1;
  color: var(--color-primary);
}
.agenda-weekday {
  display: block;
  font-size: 0.7rem;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  color: var(--color-text-muted);
  margin-top: 0.15rem;
}
.agenda-row-body h3 { margin: 0 0 0.25rem; color: var(--color-primary-dark); }
.agenda-capacity-pill {
  display: inline-block;
  /* à hauteur du bouton même quand « Envoyer à mon agenda » est déplié (pas de centrage) */
  align-self: flex-start;
  margin-top: 0.6rem;
  font-size: 0.85rem;
  font-weight: 600;
  padding: 0.2rem 0.7rem;
  border-radius: 999px;
  background: var(--color-success-bg);
  color: var(--color-success-text);
}
.agenda-row-actions {
  flex-direction: row;
  align-items: flex-start;
}
.agenda-row-actions a.btn {
  background: var(--color-accent);
  color: var(--color-primary-dark);
}
.agenda-row-actions a.btn:hover {
  background: var(--color-primary);
  color: #fff;
}
.agenda-row-actions .btn {
  border-radius: 8px;
}
/* Photo optionnelle d'un événement (espace admin "Gestion de l'agenda", voir
   _agenda_event_image_url dans app.py) : sous les boutons, à sa taille naturelle mais sans
   dépasser la largeur du texte. */
.agenda-row-thumb {
  display: inline-block;
  max-width: 100%;
}
.agenda-row-thumb img {
  display: block;
  width: auto;
  max-width: 100%;
  height: auto;
  border-radius: 8px;
  border: 1px solid var(--color-border);
}
@media (max-width: 600px) {
  .agenda-row { grid-template-columns: 3.4rem minmax(0, 1fr); }
  .agenda-date-badge { grid-row: 1; }
}
/* Le sélecteur .month-head de la règle de base ci-dessus (scroll-margin-top)
   est déclaré APRÈS la règle mobile équivalente sur .menu-full-section (voir
   plus haut, @media max-width:860px) : à spécificité égale, c'est l'ordre dans
   la feuille de style qui tranche, donc la valeur de base l'emporterait
   silencieusement même sous 860px. D'où ce correctif séparé, qui doit rester
   après la règle de base pour gagner la cascade — sans lui, le bouton fixe
   "Retourner au sommaire" (mobile) cache le titre du mois visé par un saut
   de sommaire. */
@media (max-width: 860px) {
  .month-head { scroll-margin-top: 4.5rem; }
}

/* ---------- Onglets ---------- */
.tabs-wrapper {
  margin: 0.75rem 0 3rem;
}
/* Pages Agenda et Ressources : peu d'espace entre le bandeau et les onglets (vague du bandeau
   réduite à 22px au lieu de 44px, plus de marge au-dessus des onglets). */
.tabs-wrapper--tight { margin-top: 0; }
.page-hero:has(+ div > .tabs-wrapper--tight) .hero-wave { height: 22px; }
/* Onglets imbriqués (ex. sous-catégories dans "Événements récurrents") :
   moins de marge, pas de double espacement avec les onglets parents. */
.tabs-wrapper--nested {
  margin: 0;
}
.tab-input {
  position: absolute;
  opacity: 0;
  pointer-events: none;
  width: 1px;
  height: 1px;
}
.tab-labels {
  display: flex;
  gap: 0.5rem;
  border-bottom: 2px solid var(--color-border);
  margin-bottom: 1.5rem;
}
.tab-label {
  cursor: pointer;
  padding: 0.75rem 1.5rem;
  font-weight: 600;
  color: var(--color-text-muted);
  border-bottom: 3px solid transparent;
  margin-bottom: -2px;
  user-select: none;
}
#tab-res-predications:checked ~ .tab-labels label[for="tab-res-predications"],
#tab-res-etudes:checked ~ .tab-labels label[for="tab-res-etudes"],
#tab-res-meditations:checked ~ .tab-labels label[for="tab-res-meditations"],
#tab-jeunesse:checked ~ .tab-labels label[for="tab-jeunesse"],
#tab-speciales:checked ~ .tab-labels label[for="tab-speciales"],
#tab-communautaires:checked ~ .tab-labels label[for="tab-communautaires"],
#tab-autres:checked ~ .tab-labels label[for="tab-autres"],
#tab-admin-communautaires:checked ~ .tab-labels label[for="tab-admin-communautaires"],
#tab-admin-jeunesse:checked ~ .tab-labels label[for="tab-admin-jeunesse"],
#tab-admin-speciales:checked ~ .tab-labels label[for="tab-admin-speciales"],
#tab-admin-agenda:checked ~ .tab-labels label[for="tab-admin-agenda"],
#tab-admin-inscriptions:checked ~ .tab-labels label[for="tab-admin-inscriptions"],
#tab-admin-tours-de-role:checked ~ .tab-labels label[for="tab-admin-tours-de-role"],
#tab-admin-travaux:checked ~ .tab-labels label[for="tab-admin-travaux"],
#tab-admin-marcheurs:checked ~ .tab-labels label[for="tab-admin-marcheurs"],
#tab-admin-travaux-a-realiser:checked ~ .tab-labels label[for="tab-admin-travaux-a-realiser"],
#tab-admin-travaux-historique:checked ~ .tab-labels label[for="tab-admin-travaux-historique"],
#tab-members-travaux-a-realiser:checked ~ .tab-labels label[for="tab-members-travaux-a-realiser"],
#tab-members-travaux-historique:checked ~ .tab-labels label[for="tab-members-travaux-historique"],
#tab-members-travaux-statistiques:checked ~ .tab-labels label[for="tab-members-travaux-statistiques"],
#tab-admin-liens:checked ~ .tab-labels label[for="tab-admin-liens"],
#tab-admin-documents:checked ~ .tab-labels label[for="tab-admin-documents"],
#tab-admin-photos:checked ~ .tab-labels label[for="tab-admin-photos"],
#tab-admin-defilements:checked ~ .tab-labels label[for="tab-admin-defilements"],
#tab-admin-frequentation:checked ~ .tab-labels label[for="tab-admin-frequentation"],
#tab-admin-maintenance:checked ~ .tab-labels label[for="tab-admin-maintenance"],
#tab-admin-duty-accueil:checked ~ .tab-labels label[for="tab-admin-duty-accueil"],
#tab-admin-duty-cafe:checked ~ .tab-labels label[for="tab-admin-duty-cafe"],
#tab-admin-duty-fleurs:checked ~ .tab-labels label[for="tab-admin-duty-fleurs"],
#tab-admin-duty-fermeture:checked ~ .tab-labels label[for="tab-admin-duty-fermeture"],
#tab-admin-duty-jeunes:checked ~ .tab-labels label[for="tab-admin-duty-jeunes"],
#tab-admin-duty-enfants:checked ~ .tab-labels label[for="tab-admin-duty-enfants"] {
  color: var(--color-primary-dark);
  border-bottom-color: var(--color-accent);
}
#tab-res-predications:focus-visible ~ .tab-labels label[for="tab-res-predications"],
#tab-res-etudes:focus-visible ~ .tab-labels label[for="tab-res-etudes"],
#tab-res-meditations:focus-visible ~ .tab-labels label[for="tab-res-meditations"],
#tab-jeunesse:focus-visible ~ .tab-labels label[for="tab-jeunesse"],
#tab-speciales:focus-visible ~ .tab-labels label[for="tab-speciales"],
#tab-communautaires:focus-visible ~ .tab-labels label[for="tab-communautaires"],
#tab-autres:focus-visible ~ .tab-labels label[for="tab-autres"],
#tab-admin-communautaires:focus-visible ~ .tab-labels label[for="tab-admin-communautaires"],
#tab-admin-jeunesse:focus-visible ~ .tab-labels label[for="tab-admin-jeunesse"],
#tab-admin-speciales:focus-visible ~ .tab-labels label[for="tab-admin-speciales"],
#tab-admin-agenda:focus-visible ~ .tab-labels label[for="tab-admin-agenda"],
#tab-admin-inscriptions:focus-visible ~ .tab-labels label[for="tab-admin-inscriptions"],
#tab-admin-tours-de-role:focus-visible ~ .tab-labels label[for="tab-admin-tours-de-role"],
#tab-admin-travaux:focus-visible ~ .tab-labels label[for="tab-admin-travaux"],
#tab-admin-marcheurs:focus-visible ~ .tab-labels label[for="tab-admin-marcheurs"],
#tab-admin-travaux-a-realiser:focus-visible ~ .tab-labels label[for="tab-admin-travaux-a-realiser"],
#tab-admin-travaux-historique:focus-visible ~ .tab-labels label[for="tab-admin-travaux-historique"],
#tab-members-travaux-a-realiser:focus-visible ~ .tab-labels label[for="tab-members-travaux-a-realiser"],
#tab-members-travaux-historique:focus-visible ~ .tab-labels label[for="tab-members-travaux-historique"],
#tab-members-travaux-statistiques:focus-visible ~ .tab-labels label[for="tab-members-travaux-statistiques"],
#tab-admin-liens:focus-visible ~ .tab-labels label[for="tab-admin-liens"],
#tab-admin-documents:focus-visible ~ .tab-labels label[for="tab-admin-documents"],
#tab-admin-photos:focus-visible ~ .tab-labels label[for="tab-admin-photos"],
#tab-admin-defilements:focus-visible ~ .tab-labels label[for="tab-admin-defilements"],
#tab-admin-frequentation:focus-visible ~ .tab-labels label[for="tab-admin-frequentation"],
#tab-admin-maintenance:focus-visible ~ .tab-labels label[for="tab-admin-maintenance"],
#tab-admin-duty-accueil:focus-visible ~ .tab-labels label[for="tab-admin-duty-accueil"],
#tab-admin-duty-cafe:focus-visible ~ .tab-labels label[for="tab-admin-duty-cafe"],
#tab-admin-duty-fleurs:focus-visible ~ .tab-labels label[for="tab-admin-duty-fleurs"],
#tab-admin-duty-fermeture:focus-visible ~ .tab-labels label[for="tab-admin-duty-fermeture"],
#tab-admin-duty-jeunes:focus-visible ~ .tab-labels label[for="tab-admin-duty-jeunes"],
#tab-admin-duty-enfants:focus-visible ~ .tab-labels label[for="tab-admin-duty-enfants"] {
  outline: 2px solid var(--color-accent);
  outline-offset: 2px;
}

/* Sous-onglets imbriqués (ex. "Photos du groupe de marche" par saison,
   espace admin) : forme en pilules pleines plutôt que le soulignement des
   onglets principaux, pour bien les distinguer visuellement. Ici l'état
   actif est géré en JS (.js-tab-trigger.is-active ci-dessous) plutôt que
   par un sélecteur #id — voir le commentaire sur .js-tab-trigger. */
.tabs-wrapper--nested .tab-labels {
  border-bottom: none;
  margin-bottom: 1.25rem;
}
.tabs-wrapper--nested .tab-label {
  border: 1px solid var(--color-border);
  border-radius: 6px;
  padding: 0.5rem 1.1rem;
  margin-bottom: 0;
  background: var(--color-surface);
}

/* Tableau de bord admin : même mécanisme radios+labels que les autres
   onglets du site (voir #tab-admin-X:checked ~ ... plus haut, inchangé),
   réarrangé en menu latéral plutôt qu'en ligne d'onglets — seuls
   .tab-labels et .tab-panel changent de position dans la grille. */
.tabs-wrapper--sidebar {
  display: grid;
  grid-template-columns: 230px minmax(0, 1fr);
  gap: 1.5rem;
  align-items: start;
}
.tabs-wrapper--sidebar > .tab-labels {
  grid-column: 1;
  grid-row: 1 / -1;
  flex-direction: column;
  gap: 0.15rem;
  border-bottom: none;
  margin-bottom: 0;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius);
  padding: 0.6rem;
  position: sticky;
  top: calc(var(--header-offset, 0px) + 20px);
}
.tabs-wrapper--sidebar > .tab-labels .tab-label {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  padding: 0.6rem 0.7rem;
  border-radius: 8px;
  border-bottom: none;
  margin-bottom: 0;
}
.tabs-wrapper--sidebar > .tab-labels .tab-label:hover {
  background: var(--color-bg);
}
.tabs-wrapper--sidebar > .tab-panel {
  grid-column: 2;
  /* minmax(0, 1fr) sur .tabs-wrapper--sidebar (grid-template-columns)
     autorise cette colonne à rétrécir sous la largeur de son contenu —
     condition nécessaire pour que le défilement horizontal scopé au
     tableau lui-même (.admin-table-scroll ci-dessous), plutôt qu'à tout
     le panneau, fonctionne sans élargir toute la grille. */
}
/* État actif : pastille pleine plutôt que le soulignement utilisé par
   les onglets à plat — la règle générique #tab-admin-X:checked ~
   .tab-labels label[...] plus haut donne déjà color+border-bottom-color
   à ces mêmes 8 onglets (partagée avec le reste du site) ; ici, une
   spécificité plus élevée (préfixée par .tabs-wrapper--sidebar) l'écrase
   uniquement dans ce contexte, sans toucher à la règle partagée. */
.tabs-wrapper--sidebar #tab-admin-documents:checked ~ .tab-labels label[for="tab-admin-documents"],
.tabs-wrapper--sidebar #tab-admin-agenda:checked ~ .tab-labels label[for="tab-admin-agenda"],
.tabs-wrapper--sidebar #tab-admin-inscriptions:checked ~ .tab-labels label[for="tab-admin-inscriptions"],
.tabs-wrapper--sidebar #tab-admin-tours-de-role:checked ~ .tab-labels label[for="tab-admin-tours-de-role"],
.tabs-wrapper--sidebar #tab-admin-travaux:checked ~ .tab-labels label[for="tab-admin-travaux"],
.tabs-wrapper--sidebar #tab-admin-marcheurs:checked ~ .tab-labels label[for="tab-admin-marcheurs"],
.tabs-wrapper--sidebar #tab-admin-liens:checked ~ .tab-labels label[for="tab-admin-liens"],
.tabs-wrapper--sidebar #tab-admin-photos:checked ~ .tab-labels label[for="tab-admin-photos"],
.tabs-wrapper--sidebar #tab-admin-defilements:checked ~ .tab-labels label[for="tab-admin-defilements"],
.tabs-wrapper--sidebar #tab-admin-frequentation:checked ~ .tab-labels label[for="tab-admin-frequentation"],
.tabs-wrapper--sidebar #tab-admin-maintenance:checked ~ .tab-labels label[for="tab-admin-maintenance"] {
  background: var(--color-primary);
  color: #fff;
  border-bottom-color: transparent;
}
.tabs-wrapper--sidebar #tab-admin-documents:focus-visible ~ .tab-labels label[for="tab-admin-documents"],
.tabs-wrapper--sidebar #tab-admin-agenda:focus-visible ~ .tab-labels label[for="tab-admin-agenda"],
.tabs-wrapper--sidebar #tab-admin-inscriptions:focus-visible ~ .tab-labels label[for="tab-admin-inscriptions"],
.tabs-wrapper--sidebar #tab-admin-tours-de-role:focus-visible ~ .tab-labels label[for="tab-admin-tours-de-role"],
.tabs-wrapper--sidebar #tab-admin-travaux:focus-visible ~ .tab-labels label[for="tab-admin-travaux"],
.tabs-wrapper--sidebar #tab-admin-marcheurs:focus-visible ~ .tab-labels label[for="tab-admin-marcheurs"],
.tabs-wrapper--sidebar #tab-admin-liens:focus-visible ~ .tab-labels label[for="tab-admin-liens"],
.tabs-wrapper--sidebar #tab-admin-photos:focus-visible ~ .tab-labels label[for="tab-admin-photos"],
.tabs-wrapper--sidebar #tab-admin-defilements:focus-visible ~ .tab-labels label[for="tab-admin-defilements"],
.tabs-wrapper--sidebar #tab-admin-frequentation:focus-visible ~ .tab-labels label[for="tab-admin-frequentation"],
.tabs-wrapper--sidebar #tab-admin-maintenance:focus-visible ~ .tab-labels label[for="tab-admin-maintenance"] {
  outline: 2px solid var(--color-accent);
  outline-offset: -2px;
}

/* Bouton "☰ Sections" : replie le menu latéral en mobile, même mécanique
   que #nav-toggle/.nav-links dans base.html (case à cocher + label). */
.admin-sidebar-toggle-input { display: none; }
.admin-sidebar-toggle-label {
  display: none;
  align-items: center;
  gap: 0.6rem;
  width: fit-content;
  padding: 0.6rem 1rem;
  margin-bottom: 1rem;
  border: 1px solid var(--color-border);
  border-radius: 999px;
  background: var(--color-surface);
  color: var(--color-primary-dark);
  font-weight: 600;
  cursor: pointer;
}
.admin-sidebar-toggle-label span {
  display: block;
  width: 18px;
  height: 2px;
  border-radius: 2px;
  background: var(--color-primary-dark);
}

@media (max-width: 780px) {
  .tabs-wrapper--sidebar {
    grid-template-columns: minmax(0, 1fr);
  }
  .admin-sidebar-toggle-label { display: flex; }
  .tabs-wrapper--sidebar > .tab-labels {
    display: none;
    grid-column: 1;
    grid-row: auto;
    position: static;
    margin-bottom: 1rem;
  }
  .admin-sidebar-toggle-input:checked ~ .tab-labels { display: flex; }
  .tabs-wrapper--sidebar > .tab-panel { grid-column: 1; }
}

/* Sous-onglets dynamiques dont le nombre n'est pas connu à l'avance (ex.
   "Photos du groupe de marche", espace admin — une saison = un onglet
   créé à la demande) : pas de sélecteur CSS par #id ici (impossible d'en
   écrire un pour un onglet qui n'existe pas encore), bascule gérée en JS
   (voir main.js). Les déclencheurs réutilisent .tab-label (pilule,
   .tabs-wrapper--nested .tab-label ci-dessus, une classe donc déjà
   générique) pour un style cohérent avec le reste du site ; seul l'état
   actif a besoin d'une règle ici. Les panneaux n'utilisent volontairement
   PAS la classe .tab-panel (display:none + une règle par #id ci-dessous,
   inadaptée à un nombre dynamique) : leur visibilité passe uniquement par
   l'attribut HTML natif [hidden], togglé en JS (jamais style.display).*/
.js-tab-trigger {
  font: inherit;
  color: inherit;
  cursor: pointer;
}
.js-tab-trigger.is-active {
  color: #fff;
  background: var(--color-primary);
  border-color: var(--color-primary);
}

.tab-panel { display: none; }
#tab-res-predications:checked ~ [data-panel="res-predications"] { display: block; }
#tab-res-etudes:checked ~ [data-panel="res-etudes"] { display: block; }
#tab-res-meditations:checked ~ [data-panel="res-meditations"] { display: block; }
#tab-jeunesse:checked ~ [data-panel="jeunesse"] { display: block; }
#tab-speciales:checked ~ [data-panel="speciales"] { display: block; }
#tab-communautaires:checked ~ [data-panel="communautaires"] { display: block; }
#tab-autres:checked ~ [data-panel="autres"] { display: block; }
#tab-admin-communautaires:checked ~ [data-panel="admin-communautaires"] { display: block; }
#tab-admin-jeunesse:checked ~ [data-panel="admin-jeunesse"] { display: block; }
#tab-admin-speciales:checked ~ [data-panel="admin-speciales"] { display: block; }
#tab-admin-agenda:checked ~ [data-panel="admin-main-agenda"] { display: block; }
#tab-admin-inscriptions:checked ~ [data-panel="admin-main-inscriptions"] { display: block; }
#tab-admin-tours-de-role:checked ~ [data-panel="admin-main-tours-de-role"] { display: block; }
#tab-admin-travaux:checked ~ [data-panel="admin-main-travaux"] { display: block; }
#tab-admin-marcheurs:checked ~ [data-panel="admin-main-marcheurs"] { display: block; }
#tab-admin-travaux-a-realiser:checked ~ [data-panel="admin-travaux-a-realiser"] { display: block; }
#tab-admin-travaux-historique:checked ~ [data-panel="admin-travaux-historique"] { display: block; }
#tab-members-travaux-a-realiser:checked ~ [data-panel="members-travaux-a-realiser"] { display: block; }
#tab-members-travaux-historique:checked ~ [data-panel="members-travaux-historique"] { display: block; }
#tab-members-travaux-statistiques:checked ~ [data-panel="members-travaux-statistiques"] { display: block; }
#tab-admin-liens:checked ~ [data-panel="admin-main-liens"] { display: block; }
#tab-admin-duty-accueil:checked ~ [data-panel="admin-duty-accueil"] { display: block; }
#tab-admin-duty-cafe:checked ~ [data-panel="admin-duty-cafe"] { display: block; }
#tab-admin-duty-fleurs:checked ~ [data-panel="admin-duty-fleurs"] { display: block; }
#tab-admin-duty-fermeture:checked ~ [data-panel="admin-duty-fermeture"] { display: block; }
#tab-admin-duty-jeunes:checked ~ [data-panel="admin-duty-jeunes"] { display: block; }
#tab-admin-duty-enfants:checked ~ [data-panel="admin-duty-enfants"] { display: block; }
#tab-admin-documents:checked ~ [data-panel="admin-main-documents"] { display: block; }
#tab-admin-photos:checked ~ [data-panel="admin-main-photos"] { display: block; }
#tab-admin-defilements:checked ~ [data-panel="admin-main-defilements"] { display: block; }
#tab-admin-frequentation:checked ~ [data-panel="admin-main-frequentation"] { display: block; }
#tab-admin-maintenance:checked ~ [data-panel="admin-main-maintenance"] { display: block; }

/* Onglet "Maintenance" : espace disque (barre <progress>, pas de style
   inline : la CSP l'interdit) et tailles des données. */
.maintenance-disk progress {
  width: 100%;
  height: 1.1rem;
  accent-color: var(--color-primary);
}
.maintenance-disk-figures {
  margin: 0.4rem 0 0;
}
.maintenance-disk--low progress {
  accent-color: #c0392b;
}
.maintenance-disk-warning {
  margin: 0.4rem 0 0;
  font-weight: 600;
  color: var(--color-error-text);
}
/* Les deux boutons de la barre (bouton + label d'import, emojis différents,
   bordure seulement sur le second) : même hauteur, texte centré. */
.maintenance-actions .btn {
  display: inline-flex;
  align-items: center;
  box-sizing: border-box;
  min-height: 3rem;
  border: 1px solid var(--color-primary);
  line-height: 1.2;
}
.maintenance-sizes {
  margin: 0.75rem 0 1.5rem;
  padding-left: 1.2rem;
}
.feed-notice {
  background: var(--color-error-bg);
  color: var(--color-error-text);
  padding: 0.65rem 1rem;
  border-radius: 8px;
  font-size: 0.9rem;
  margin-bottom: 1rem;
}

/* ---------- Buttons ---------- */
.btn {
  display: inline-block;
  background: var(--color-primary);
  color: #fff;
  padding: 0.65rem 1.3rem;
  border-radius: 999px;
  text-decoration: none;
  font-weight: 600;
  border: none;
  cursor: pointer;
  align-self: flex-start;
  font-size: 1rem;
}
.btn:hover { background: var(--color-primary-dark); color: #fff; }
.btn-secondary {
  background: transparent;
  color: var(--color-primary);
  border: 1px solid var(--color-primary);
}
.btn-secondary:hover { background: var(--color-primary); color: #fff; }
.btn-disabled {
  display: inline-block;
  background: var(--color-border);
  color: var(--color-text-muted);
  padding: 0.65rem 1.3rem;
  border-radius: 999px;
  font-weight: 600;
  align-self: flex-start;
}
.live-dot {
  display: inline-block;
  width: 0.9em;
  height: 0.9em;
  border-radius: 50%;
  background: #e0483e;
  vertical-align: middle;
  margin-bottom: 0.1em;
}
.btn-disabled .live-dot {
  background: currentColor;
}

/* ---------- Flash messages ---------- */
.flash-container {
  margin: 1.25rem auto 0;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}
.flash {
  padding: 0.85rem 1.1rem;
  border-radius: 10px;
  font-weight: 500;
}
.flash-success { background: var(--color-success-bg); color: var(--color-success-text); }
.flash-error { background: var(--color-error-bg); color: var(--color-error-text); }

/* ---------- Forms ---------- */
.registration-form {
  display: flex;
  flex-direction: column;
  gap: 1.1rem;
  margin-top: 1.5rem;
}
.form-field { display: flex; flex-direction: column; gap: 0.35rem; }
.form-field label { font-weight: 600; }
.form-field input,
.form-field textarea,
.form-field select {
  padding: 0.65rem 0.8rem;
  border: 1px solid var(--color-border);
  border-radius: 8px;
  font-size: 1rem;
  font-family: inherit;
  background: var(--color-surface);
  color: var(--color-text);
}
.form-field input:focus,
.form-field textarea:focus,
.form-field select:focus {
  outline: 2px solid var(--color-accent);
  outline-offset: 1px;
}
/* Case à cocher sous un champ (ex. « Indiquer une heure de fin ») */
.form-field .form-check {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  font-weight: 400;
  cursor: pointer;
}
.form-field .form-check input {
  width: 1.1rem;
  height: 1.1rem;
  padding: 0;
  accent-color: var(--color-primary);
}
.form-field input:disabled { opacity: 0.5; cursor: not-allowed; }
.field-error {
  color: var(--color-error-text);
  font-size: 0.9rem;
  margin: 0;
}
/* Champ de date (texte "JJ/MM" des tours de rôle, ou <input type="date">
   natif de l'agenda) + icône calendrier ouvrant un sélecteur à côté (voir
   main.js) : le champ visible garde le style .form-field input ci-dessus,
   seul le bouton a besoin d'un style propre. */
.date-input-with-picker {
  display: flex;
  gap: 0.4rem;
  align-items: stretch;
}
.date-input-with-picker input[type="text"],
.date-input-with-picker input[type="date"] {
  flex: 1;
  min-width: 0;
}
/* Le bouton fait déjà office d'icône calendrier : masque celle, redondante,
   que Chrome/Edge ajoutent nativement dans les <input type="date">
   (Firefox n'a pas d'équivalent ciblable en CSS — garde la sienne, sans
   gêner le fonctionnement). */
.date-input-with-picker input[type="date"]::-webkit-calendar-picker-indicator {
  display: none;
}
.date-picker-btn {
  flex-shrink: 0;
  width: 2.6rem;
  border: 1px solid var(--color-border);
  border-radius: 8px;
  background: var(--color-surface);
  font-size: 1.1rem;
  line-height: 1;
  cursor: pointer;
}
.date-picker-btn:hover {
  background: var(--color-bg);
}
.date-picker-btn:focus-visible {
  outline: 2px solid var(--color-accent);
  outline-offset: 1px;
}
/* Champ de mot de passe avec un oeil à l'intérieur, à droite (voir main.js,
   bloc .js-password-toggle) : oeil FERMÉ (barré) quand le mot de passe est
   masqué, OUVERT quand il est affiché — les deux <svg> sont dans le bouton,
   alternés en CSS d'après aria-pressed (pas de [hidden] : voir le piège
   décrit plus haut sur les règles display d'auteur). Le champ garde le
   style .form-field input, avec un padding droit réservé à l'oeil. */
.password-input-with-toggle {
  position: relative;
}
.form-field .password-input-with-toggle input {
  width: 100%;
  padding-right: 2.9rem;
}
/* Edge/IE ajoutent leur propre oeil natif dans les champs mot de passe :
   masqué pour ne pas avoir deux icônes superposées. */
.password-input-with-toggle input::-ms-reveal,
.password-input-with-toggle input::-ms-clear {
  display: none;
}
.password-toggle-btn {
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  width: 2.9rem;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  border: 0;
  border-radius: 0 8px 8px 0;
  background: transparent;
  color: var(--color-text-muted);
  cursor: pointer;
}
.password-toggle-btn:hover {
  color: var(--color-primary);
}
.password-toggle-btn:focus-visible {
  outline: 2px solid var(--color-accent);
  outline-offset: -2px;
}
.password-toggle-btn svg {
  width: 1.3rem;
  height: 1.3rem;
}
.password-toggle-btn .eye-open { display: none; }
.password-toggle-btn[aria-pressed="true"] .eye-open { display: block; }
.password-toggle-btn[aria-pressed="true"] .eye-closed { display: none; }
/* Modification d'une tâche (admin_travaux_tache.html) : le champ "Date du
   statut" à côté de la liste des statuts (passe à la ligne sur mobile). */
.statut-with-date {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
  align-items: flex-end;
}
.statut-with-date select { flex: 1 1 12rem; }
.statut-date-field {
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
  flex: 0 1 14rem;
}
.statut-date-label {
  font-size: 0.85rem;
  color: var(--color-text-muted);
}
.statut-with-date select:disabled,
.statut-date-field input:disabled {
  background: var(--color-bg-sunken);
  color: var(--color-text-muted);
}

/* "Gestion des liens" : état de la lecture automatique du lien du direct
   (voir live_link.py). */
.live-mail-status {
  background: var(--color-bg-sunken);
  border: 1px solid var(--color-border);
  border-radius: 8px;
  padding: 0.75rem 1rem;
  margin-bottom: 0.9rem;
  font-size: 0.9rem;
  overflow-wrap: anywhere;
}
.live-mail-status p { margin: 0.25rem 0; }
.live-schedule-row {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
}
.live-schedule-row .form-field { flex: 1 1 11rem; }
.form-field--checkbox label {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  font-weight: 600;
}
.field-hint {
  color: var(--color-text-muted);
  font-size: 0.85rem;
  margin: -0.3rem 0 0.5rem;
}
.field-hidden {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}
.back-link {
  display: inline-block;
  margin: 1.5rem 0 0.5rem;
  text-decoration: none;
}

/* ---------- Admin ---------- */
.admin-bar {
  display: flex;
  justify-content: space-between;
  align-items: center;
  flex-wrap: wrap;
  gap: 1rem;
  margin-top: 1.5rem;
  margin-bottom: 1.5rem;
}
.admin-bar h2 { margin: 0; color: var(--color-primary-dark); }
.admin-bar-actions {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  flex-wrap: wrap;
}
.admin-table {
  width: 100%;
  border-collapse: collapse;
  margin: 1.5rem 0 3rem;
  background: var(--color-surface);
  border-radius: var(--radius);
  overflow: hidden;
  box-shadow: var(--shadow);
}
.admin-table th, .admin-table td {
  text-align: left;
  padding: 0.7rem 1rem;
  border-bottom: 1px solid var(--color-border);
}
/* Taille de police réduite (introduite pour "Gestion des travaux", où les
   colonnes étroites en avaient besoin — voir .admin-table--travaux
   ci-dessous) puis étendue à TOUS les tableaux admin pour rester
   cohérente d'une section à l'autre. */
.admin-table td {
  font-size: 0.8rem;
}
.admin-table th {
  background: var(--color-bg);
  font-size: 0.68rem;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  color: var(--color-text-muted);
}
/* Enveloppe de défilement horizontal scopée au tableau seul (admin.html,
   utilisée autour de .admin-table--travaux ci-dessous) : contrairement à
   un overflow-x sur tout le panneau, le bouton "➕ Ajouter une tâche" et
   les sous-onglets "À réaliser"/"Historique" restent fixes, seul le
   tableau défile quand min-width (ci-dessous) dépasse la largeur
   disponible. */
.admin-table-scroll {
  overflow-x: auto;
}
/* Tableaux "Gestion des travaux" (admin.html) : colonne Description deux
   fois plus large que les autres colonnes de la même ligne. table-layout:
   fixed est nécessaire pour que la largeur soit vraiment respectée — en
   layout auto (par défaut), un `width` sur un <th> n'est qu'une
   suggestion que le contenu des autres colonnes peut écraser. */
.admin-table--travaux {
  table-layout: fixed;
  min-width: 960px;
}
.admin-table--travaux .col-travaux-description {
  width: 30%;
}
/* Colonnes serrées (Statut, dates, Photos, actions) : padding réduit et
   retour à la ligne forcé sur les mots trop longs pour leur colonne
   (évite qu'un en-tête en MAJUSCULES comme "Introduite le" ne déborde
   sur la colonne voisine sous table-layout: fixed ci-dessus) — la
   taille de police, elle, vient désormais de la règle .admin-table
   th/td ci-dessus, commune à tous les tableaux admin. */
.admin-table--travaux th,
.admin-table--travaux td {
  padding: 0.55rem 0.6rem;
  overflow-wrap: break-word;
}
.admin-table-actions {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  flex-wrap: wrap;
}
.admin-table-actions form {
  margin: 0;
}
/* Bouton "Supprimer" de certains tableaux admin (Gestion des travaux,
   Gestion de l'agenda, Gestion des tours de rôle (6 onglets, un seul bloc
   Jinja partagé — voir la boucle for tab in duty_tabs) — appliqué au cas
   par cas, pas globalement à .admin-table-actions) : même apparence que
   le lien "Modifier" à côté
   (texte souligné, sans fond ni bordure) plutôt que le bouton plein
   .btn/.btn-secondary utilisé par défaut ailleurs sur le site — reste un
   <button type="submit"> (nécessaire pour soumettre le formulaire de
   suppression), juste sans le style bouton. */
.admin-table-actions .btn-as-link {
  background: none;
  border: none;
  padding: 0;
  margin: 0;
  font: inherit;
  color: var(--color-primary);
  text-decoration: underline;
  cursor: pointer;
}
.admin-inline-form {
  max-width: 28rem;
}

/* ---------- Footer ---------- */
.site-footer {
  border-top: 1px solid var(--color-border);
  margin-top: 2rem;
  padding: 0.6rem 0 0.2rem;
  /* Fond vert clair de la palette (#A2B78E = R162 V183 B142) ; texte vert foncé
     (contraste 4,6:1) et trait crème du bandeau-image */
  color: var(--color-primary-dark);
  font-size: 0.92rem;
  background: var(--color-accent);
}
.footer-col p { margin: 0.3rem 0; }
/* Icônes Facebook / YouTube : tuiles arrondies jaune pâle, pictogramme plein
   vert foncé ; au survol la tuile devient olive et le pictogramme blanc. */
.footer-social {
  display: flex;
  align-items: flex-start;
  justify-content: flex-end; /* cadrées à droite */
  gap: 0.8rem;
  order: -2; /* petit écran : tout en haut du pied de page */
  margin-bottom: 0.8rem;
}
/* Grand écran : juste à GAUCHE de la colombe du bandeau (qui occupe de ~90,7 %
   à ~97,3 % de la largeur de l'image) et à sa hauteur (centre à ~37 %). */
@media (min-width: 600px) {
  /* Tuile = 78 % de la hauteur du dessin (--fb-h) : jamais plus haute que le temple et, centrée
     entre le haut et le trait (46,5 %), elle laisse ~3 px de vide au-dessus du trait. */
  .footer-social .social-link { width: calc(var(--fb-h) * 0.78); height: calc(var(--fb-h) * 0.78); border-radius: calc(var(--fb-h) * 0.2); }
  .footer-social .social-link svg { width: calc(var(--fb-h) * 0.42); height: calc(var(--fb-h) * 0.42); }
  .footer-social {
    position: absolute;
    right: calc(var(--fb-h) * 0.925 + 0.9rem); /* à gauche des étoiles de la colombe */
    gap: 0.5rem;
    top: 46.5%; /* centre entre le haut du dessin et le trait (93 % / 2) */
    transform: translateY(-50%);
    order: 0;
    margin-bottom: 0;
  }
}
.social-link {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.1rem;
  height: 2.1rem;
  background: var(--color-yellow);
  color: var(--color-primary-dark);
  border-radius: 8px;
  box-shadow: inset 0 0 0 1px var(--color-border);
  transition: background 0.15s ease, color 0.15s ease, transform 0.15s ease;
}
.social-link svg {
  width: 1.1rem;
  height: 1.1rem;
  fill: currentColor;
}
.social-link:hover {
  background: var(--color-primary);
  color: #fff;
  transform: translateY(-2px);
}
.social-link:focus-visible { outline: 2px solid var(--color-accent); outline-offset: 3px; }
.footer-title {
  font-weight: 700;
  color: var(--color-primary-dark);
  margin-bottom: 0.5rem !important;
}
/* Bandeau (temple à gauche, colombe à droite) : son trait horizontal remplace
   l'ancienne bordure au-dessus du copyright. Fond blanc du JPEG fondu dans
   celui du pied de page (multiply). */
/* Le bandeau du pied de page occupe TOUTE la largeur de l'écran (le temple dessiné est
   cadré à gauche, avec une petite marge), et non plus la largeur du contenu. */
.footer-wide { padding: 0 0.75rem; }
.footer-banner-wrap {
  position: relative;
  display: flex;
  flex-direction: column;
}
.footer-contact {
  order: -1;
  margin-bottom: 0.5rem;
  /* adresse et copyright en crème, comme le trait et le temple du bandeau ; une légère ombre
     vert foncé aide la lecture sur le fond vert clair */
  color: var(--color-yellow);
  text-shadow: 0 1px 2px rgba(58, 70, 48, 0.55);
}
.footer-contact .copyright { margin: 0.3rem 0 0; }
/* Grand écran : à droite du temple dessiné (qui occupe ~7 % de la largeur de
   l'image) et juste au-dessus du trait, lequel est à 70,5 % de la hauteur de
   l'image (186/264) : le bas du bloc est donc à 29,5 % du bas du bandeau. */
@media (min-width: 600px) {
  .footer-contact {
    position: absolute;
    left: calc(var(--fb-h) * 0.7 + 0.8rem); /* à droite du temple */
    bottom: calc(7% + 0.4rem); /* le trait est à 186 px sur 200 : 14 px (7 %) en dessous */
    order: 0;
    margin-bottom: 0;
    display: flex;
    align-items: flex-end;
    gap: 3rem;
  }
  .footer-contact p { margin: 0.1rem 0; }
  .footer-contact .copyright { margin: 0.1rem 0; white-space: nowrap; }
}
/* 600 - 899px : l'adresse et le copyright s'empilent (l'un sous l'autre) à côté du temple,
   qui est dessiné un peu plus grand pour les contenir. */
@media (min-width: 600px) and (max-width: 899px) {
  .footer-banner-wrap { --fb-h: 3.4rem; }
  .footer-contact { flex-direction: column; align-items: flex-start; gap: 0; }
}
/* L'image fait 2000 x 264, mais seuls les 200 px du haut sont gardés (le trait est à
   186 px) : la partie vide sous le trait est coupée pour réduire la hauteur du pied de page. */
/* Hauteur du dessin : --fb-h. Le temple (140 px sur 2000 de l'image d'origine, soit 0,7 fois
   la hauteur) et la colombe (200 px, soit 1 fois la hauteur) sont deux morceaux de la MÊME image
   SVG (fond de deux éléments) ; le trait entre les deux est une simple ligne crème. Le trait
   de l'image est à 186 px sur 200 : 93 % de la hauteur. */
.site-footer { --fb-h: 2.25rem; }
.footer-banner {
  display: grid;
  grid-template-columns: calc(var(--fb-h) * 0.7) 1fr var(--fb-h);
  height: var(--fb-h);
}
.fb-temple, .fb-colombe {
  background: url("../img/footer-banner.svg") no-repeat;
  background-size: auto calc(var(--fb-h) * 264 / 200);
}
.fb-temple { background-position: left top; }
.fb-colombe { background-position: right top; }
.fb-trait {
  grid-column: 2;
  align-self: start;
  margin-top: calc(var(--fb-h) * 0.93 - 0.5px);
  height: 1px;
  background: var(--color-yellow);
}
.copyright { margin: 0; }
/* Fenêtre étroite (< 600px) : une seule ligne, l'adresse et les 2 icônes À CÔTÉ du temple
   (et non plus au-dessus du bandeau). Seul le temple est gardé (ni trait ni colombe) et
   « © EPUB Marcinelle · vX.Y.Z » est masqué. Placé après les règles du bandeau pour les surcharger. */
@media (max-width: 599px) {
  .footer-banner-wrap {
    --fb-h: 2.25rem;
    display: grid;
    align-items: center;
    grid-template-columns: auto minmax(0, 1fr) auto;
    column-gap: 0.6rem;
  }
  .footer-banner { grid-column: 1; grid-row: 1; grid-template-columns: 1fr; width: calc(var(--fb-h) * 0.7); }
  .fb-trait, .fb-colombe { display: none; }
  .footer-contact { grid-column: 2; grid-row: 1; margin-bottom: 0; }
  .footer-contact .copyright { display: none; }
  .footer-social { grid-column: 3; grid-row: 1; order: 0; margin-bottom: 0; flex-direction: row; gap: 0.5rem; }
  .footer-contact { order: 0; }
}

h1 { color: var(--color-primary-dark); }
h2 { color: var(--color-primary-dark); }

@media (max-width: 600px) {
  :root { font-size: 16px; }
  .page-hero-content h1 { font-size: 1.6rem; }
}

/* ---------- Ressources : prédications (vidéos YouTube) ---------- */
.predications-intro { color: var(--color-text-muted); margin-top: 0; }
.predications-list {
  display: grid;
  gap: 2rem;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 28rem), 1fr));
  align-items: start;
}
.predication {
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: 10px;
  padding: 1rem 1.1rem 1.2rem;
}
.predication h3 { margin: 0 0 0.25rem; font-size: 1.1rem; }
/* Prédications : TOUS les cadres ont la même hauteur (toutes les rangées égales à la plus haute, les cadres
   d'une rangée s'étirent) ; le texte de description, très variable, est limité à 6 lignes. */
.predications-list--uniform { grid-auto-rows: 1fr; align-items: stretch; }
.predications-list--uniform .predication { display: flex; flex-direction: column; }
.predications-list--uniform .predication-text {
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 6;
  line-clamp: 6;
  overflow: hidden;
}
/* Méditations : ~100 vidéos en grille serrée (miniature puis titre, sans date ni texte) */
.predications-list--compact {
  gap: 1.1rem;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 15rem), 1fr));
}
.predication--compact { padding: 0.6rem 0.6rem 0.8rem; }
.predication--compact h3 { margin: 0.55rem 0.2rem 0; font-size: 0.95rem; line-height: 1.3; }
.predication--compact h3 a { color: inherit; text-decoration: none; }
.predication--compact h3 a:hover { text-decoration: underline; }
.predication-date { margin: 0 0 0.75rem; color: var(--color-text-muted); font-size: 0.9rem; }
.video-frame {
  position: relative;
  aspect-ratio: 16 / 9;
  background: #000;
  border-radius: 8px;
  overflow: hidden;
}
.video-frame iframe,
.video-play,
.video-play img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  border: 0;
}
.video-play img { object-fit: cover; }
.video-play-icon {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: 4rem;
  height: 4rem;
  border-radius: 50%;
  background: rgba(58, 70, 48, 0.85);
  color: #fff;
  font-size: 1.6rem;
  line-height: 4rem;
  text-align: center;
  padding-left: 0.25rem;
  box-sizing: border-box;
}
.video-play:hover .video-play-icon,
.video-play:focus-visible .video-play-icon { background: var(--color-primary); }
.predication-note { margin: 0.6rem 0 0; font-size: 0.85rem; color: var(--color-text-muted); font-style: italic; }
.predication-text {
  white-space: pre-line;
  overflow-wrap: anywhere;
  margin: 0.9rem 0 0;
  font-size: 0.95rem;
}
/* Sablier de chargement : la colombe du logo qui tourne (arrêtée si le visiteur
   demande moins d'animations). */
.video-loading {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.9rem;
  padding: 1.5rem 0;
  color: var(--color-text-muted);
}
.video-loading-icon {
  width: 4rem;
  height: auto;
  animation: dove-spin 1.6s linear infinite;
}
.video-loading--refresh { padding: 0.4rem 0 1rem; justify-content: flex-start; }
.video-loading--refresh .video-loading-icon { width: 2rem; }
@keyframes dove-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) {
  .video-loading-icon { animation: none; }
}
.predications-more { grid-column: 1 / -1; text-align: center; margin: 0; }

/* ---------- Texte enrichi des photos du bandeau (voir richtext.py) ---------- */
/* Classes produites par richtext.clean() : couleurs, polices, tailles. */
.rt-c-blanc { color: #FFFFFF; }
.rt-c-noir { color: #1F1F1F; }
.rt-c-vert-fonce { color: #3A4630; }
.rt-c-olive { color: #5E6E4F; }
.rt-c-vert-clair { color: #A2B78E; }
.rt-c-creme { color: #F2EBC4; }
.rt-c-orange { color: #C96F00; }
.rt-c-bleu { color: #1E6E9E; }
.rt-c-rouge { color: #B3261E; }
.rt-f-georgia { font-family: "Georgia", sans-serif; }
.rt-f-verdana { font-family: "Verdana", sans-serif; }
.rt-f-trebuchet { font-family: "Trebuchet MS", sans-serif; }
.rt-f-courier { font-family: "Courier New", sans-serif; }
.rt-f-manuscrite { font-family: "Comic Sans MS", sans-serif; }
.rt-s1 { font-size: 0.75rem; }
.rt-s2 { font-size: 0.9rem; }
.rt-s3 { font-size: 1.1rem; }
.rt-s4 { font-size: 1.3rem; }
.rt-s5 { font-size: 1.7rem; }
.rt-s6 { font-size: 2.2rem; }
.rt-s7 { font-size: 3rem; }

/* Légende d'une photo (bouton + texte), en bas à gauche du bandeau d'ACCUEIL.
   Chaque légende est un calque pleine taille qui glisse avec sa photo (mêmes
   classes que .hero-slide) ; seule la légende visible est atteignable au clavier. */
body { --hero-nav-w: var(--max-width); }
@media (min-width: 1200px) { body { --hero-nav-w: 1600px; } }
/* Les légendes sont EN FLUX (et non plus posées par-dessus l'image) : le bandeau d'accueil prend la
   hauteur de la plus haute légende (elles sont empilées dans la même cellule de grille), donc un
   texte long agrandit le bandeau au lieu de remonter sous le titre « Eglise Protestante… ». */
.hero-captions {
  position: relative;
  display: grid;
  /* CADRE du défilement : mêmes bords gauche et droit que le contenu de l'en-tête (colombe à
     gauche, liens à droite) ; le texte glisse à l'intérieur et disparaît à ces bords, sans
     jamais déborder sur les marges ni sous le logo */
  width: calc(min(100%, var(--hero-nav-w)) - 3rem);
  margin: 0 auto;
  overflow: hidden;
  pointer-events: none;
  z-index: 2;
}
.hero-caption {
  grid-area: 1 / 1;
  visibility: hidden;
  transform: translateX(100%);
  transition: transform var(--hero-transition, 0.9s) ease-in-out;
}
.hero-caption.is-active { visibility: visible; transform: translateX(0); }
.hero-caption.is-leaving { visibility: visible; transform: translateX(-100%); }
.hero-caption.no-anim { transition: none; }
.hero-caption-inner {
  box-sizing: border-box;
  width: 100%;
  padding: 0.6rem 0 1rem;
  pointer-events: auto;
}
.hero-caption-text { margin: 0 0 0.6rem; line-height: 1.3; overflow-wrap: anywhere; }
.hero-caption-btn { display: inline-block; }
/* Accueil avec légendes : le bandeau se cale en bas (légende au pied de l'image) et a au moins cette
   hauteur ; il s'agrandit si la légende est plus haute. */
.page-hero--home .page-hero-media--caption {
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  min-height: calc(var(--hero-top) + 6rem);
}
@media (prefers-reduced-motion: reduce) {
  .hero-caption { transition: none; }
}

/* Page d'édition (admin) : barre d'outils + zone de texte. */
.admin-caption-preview { width: 10rem; max-width: 100%; height: auto; border-radius: 8px; border: 1px solid var(--color-border); }
/* « Gestion des défilements » : cartes plus larges que celles de « Gestion des
   photos », pour loger le résumé (bouton / texte) et les deux boutons côte à côte. */
.admin-photo-grid--wide { grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); gap: 1.25rem; }
.admin-photo-caption-info { margin: 0; padding: 0.75rem 1rem 0.25rem; font-size: 0.9rem; }
.admin-photo-actions {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 0.6rem;
  padding: 0.5rem 1rem 1rem;
}
.admin-photo-actions form { padding: 0; }
/* Lien « Bouton et texte » et bouton « Supprimer » : même gabarit exact (un
   <button> n'hérite pas de la police ni de l'interligne d'un <a>). */
.admin-photo-actions .btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  box-sizing: border-box;
  min-height: 2.6rem;
  margin: 0;
  padding: 0.4rem 1.1rem;
  font-family: inherit;
  font-size: 0.95rem;
  line-height: 1.2;
}
.rt-toolbar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.4rem;
  margin-bottom: 0.4rem;
}
.rt-toolbar[hidden] { display: none; }
.rt-btn {
  min-width: 2.2rem;
  padding: 0.3rem 0.6rem;
  border: 1px solid var(--color-border);
  border-radius: 6px;
  background: var(--color-surface);
  cursor: pointer;
  font: inherit;
}
.rt-btn:hover { background: var(--color-bg); }
.rt-group { display: inline-flex; align-items: center; gap: 0.35rem; }
.rt-toolbar select { width: auto; max-width: 100%; }
.rt-sep { width: 1px; height: 1.4rem; background: var(--color-border); margin: 0 0.2rem; }
.rt-label { font-size: 0.85rem; color: var(--color-text-muted); }
.rt-swatch {
  width: 1.6rem;
  height: 1.6rem;
  border-radius: 50%;
  border: 2px solid #fff;
  box-shadow: 0 0 0 1px var(--color-border);
  cursor: pointer;
  padding: 0;
}
.rt-swatch:hover, .rt-swatch:focus-visible { box-shadow: 0 0 0 2px var(--color-accent); }
.rt-bg-blanc { background: #FFFFFF; }
.rt-bg-noir { background: #1F1F1F; }
.rt-bg-vert-fonce { background: #3A4630; }
.rt-bg-olive { background: #5E6E4F; }
.rt-bg-vert-clair { background: #A2B78E; }
.rt-bg-creme { background: #F2EBC4; }
.rt-bg-orange { background: #C96F00; }
.rt-bg-bleu { background: #1E6E9E; }
.rt-bg-rouge { background: #B3261E; }
.rt-editor {
  min-height: 7rem;
  padding: 0.6rem 0.8rem;
  border: 1px solid var(--color-border);
  border-radius: 8px;
  background: #fff;
  line-height: 1.3;
}
.rt-editor[hidden], .rt-source[hidden] { display: none; }
/* Aperçu fidèle dans l'éditeur : mêmes tailles que les classes .rt-sN */
.rt-editor font[size="1"] { font-size: 0.75rem; }
.rt-editor font[size="2"] { font-size: 0.9rem; }
.rt-editor font[size="3"] { font-size: 1.1rem; }
.rt-editor font[size="4"] { font-size: 1.3rem; }
.rt-editor font[size="5"] { font-size: 1.7rem; }
.rt-editor font[size="6"] { font-size: 2.2rem; }
.rt-editor font[size="7"] { font-size: 3rem; }

/* ---------- Admin : onglet « Fréquentation » ---------- */
.traffic-summary { display: grid; grid-template-columns: repeat(auto-fit, minmax(14rem, 1fr)); gap: 1rem; margin: 1rem 0 1.5rem; }
.traffic-card { background: var(--color-surface); border: 1px solid var(--color-border); border-radius: var(--radius); padding: 1rem 1.25rem; }
.traffic-card h3 { margin: 0 0 0.2rem; font-size: 0.95rem; color: var(--color-text-muted); }
.traffic-card p { margin: 0; }
.traffic-big { font-size: 2.2rem; font-weight: 700; color: var(--color-primary); line-height: 1.1; }
.traffic-title { margin: 1.5rem 0 0.6rem; font-size: 1.05rem; color: var(--color-primary-dark); }
.traffic-chart { display: block; width: 100%; max-width: 46rem; height: auto; }
.traffic-bar { fill: var(--color-primary); }
.traffic-bar--empty { fill: var(--color-border); }
.traffic-axis { font-size: 9px; fill: var(--color-text-muted); }
.traffic-tables { display: grid; grid-template-columns: repeat(auto-fit, minmax(18rem, 1fr)); gap: 1.5rem; }
.traffic-table { border-collapse: collapse; width: 100%; font-size: 0.95rem; }
.traffic-table th, .traffic-table td { text-align: left; padding: 0.4rem 0.6rem; border-bottom: 1px solid var(--color-border); }
.traffic-table th:not(:first-child), .traffic-table td:not(:first-child) { text-align: right; }
