/* Thème par défaut du site web — volontairement minimal et sans dépendance. */

/* :host (en plus de :root) : quand cette feuille est chargée dans le shadow
   root d'un aperçu de bloc côté éditeur (voir PageEditor.js), :root ne
   correspond à rien dans l'arbre du shadow root — :host cible alors
   l'élément hôte, qui transmet ces variables/le reset par héritage normal
   à son contenu. Sur le vrai site (pas de shadow DOM), :host ne
   correspond à rien : seul :root s'applique, sans changement de comportement.
   Un nouveau thème doit reprendre ce doublet pour être compatible avec
   l'aperçu fusionné de l'éditeur — voir README.md. */
:root, :host {
    /* Charte « papier crème »
       ------------------------------------------------------------------
       La page n'est pas blanche mais crème : c'est ce fond qui donne au site
       son air d'imprimé et qui fait ressortir les cartes, restées blanches.
       Trois couleurs de marque seulement — nuit, corail, moutarde — plus un
       turquoise pour les blocs qui doivent trancher (l'agenda).

       Deux corails : le vif sert aux aplats décoratifs et aux filets, le
       foncé à tout ce qui porte du texte. Le vif sur blanc plafonne à 4:1,
       sous le seuil RGAA pour du texte courant ; le distinguer évite d'avoir
       à y penser à chaque usage. */
    --site-accent: #b2392b;
    --site-accent-vivid: #d25030;
    --site-accent-bg: #ffe6d9;
    --site-night: #182544;
    --site-night-soft: #283b67;
    --site-gold: #f9d46b;
    --site-gold-bg: #ffe6a2;
    --site-gold-ink: #573000;
    --site-teal: #006566;
    --site-teal-bg: #d7f0ef;

    /* Durées d'animation. Regroupées ici pour qu'un thème dérivé puisse tout
       ralentir ou tout couper d'un coup. */
    --site-transition: .2s cubic-bezier(.22, .61, .36, 1);
    --site-reveal-duration: .7s;

    --site-text: #1a2438;
    --site-muted: #5e636f;
    --site-muted-bg: #f1ebdd;
    --site-bg: #fdf7ec;
    --site-bg-card: #ffffff;
    --site-bg-alt: #f7f1e4;
    --site-success: #1d6b33;
    --site-success-bg: #dff0dd;
    --site-warning: #8a5300;
    --site-warning-bg: var(--site-gold-bg);
    --site-danger: #a8352a;
    --site-danger-bg: #fbdfd7;

    /* Familles. Le serif porte les titres, le monospace les surtitres et les
       libellés courts (dates, catégories, intitulés de champ) : c'est ce
       contraste de familles, plus que la couleur, qui donne son caractère à
       la page. Le texte courant reste en sans-serif, plus lisible en petit
       corps et sur les longs paragraphes. */
    --site-font: 'Public Sans', system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
    --site-font-title: 'Instrument Serif', Iowan Old Style, Georgia, "Times New Roman", serif;
    --site-font-mono: 'IBM Plex Mono', ui-monospace, SFMono-Regular, Menlo, monospace;

    /* Traits de dessin. Une seule source pour les rayons et les ombres :
       un thème dérivé change l'allure de tout le site en surchargeant ces
       variables, sans réécrire un sélecteur. Les arrondis sont larges —
       c'est ce qui distingue une carte d'un simple rectangle bordé. */
    --site-border: #e3decf;
    --site-border-strong: #d3cdbf;
    --site-radius: 24px;
    --site-radius-lg: 32px;
    --site-radius-sm: 14px;
    --site-radius-pill: 999px;
    --site-shadow: 0 1px 2px rgba(60, 40, 10, .04);
    --site-shadow-hover: 0 18px 40px -24px rgba(60, 40, 10, .5);

    /* Largeurs
       --site-container : en-tête, pied de page et colonne par défaut des blocs.
       --site-reading   : mesure de confort du texte suivi (~68 caractères).
         Elle s'applique au texte lui-même, pas au bloc : un bandeau garde
         toute sa largeur, seules ses lignes de texte sont bornées. */
    --site-container: 1120px;
    --site-reading: 44rem;

    /* Rythme vertical : l'écart entre deux blocs, et le souffle d'une section
       pleine largeur (qui ne se règle pas comme une marge entre paragraphes). */
    --site-block-gap: clamp(2rem, 4vw, 3rem);
    --site-section-padding: clamp(3rem, 6vw, 5.5rem);
    --site-main-padding: clamp(2rem, 4vw, 3rem);
}

/* Palette dérivée
   ------------------------------------------------------------------
   Six couleurs seulement sont réglables depuis Site web → Configuration
   (celles déclarées dans theme.json) : accent, nuit, doré, turquoise, fond de
   page et texte courant. Les douze autres en découlent ici — même teinte,
   clarté et saturation recalculées.

   C'est ce qui rend la configuration honnête : avant, un établissement qui
   remplaçait le corail par du vert gardait un fond d'accent rose et des filets
   crème, sans rien pour l'en avertir. Les nuances suivent désormais la
   couleur dont elles dépendent.

   Deux familles de règles, pour deux intentions différentes :
   - clarté absolue (.942 pour un pastel, .351 pour une encre) — un fond
     pastel doit rester pastel et une encre rester lisible dessus, quelle que
     soit la couleur de départ ; c'est ce qui garantit le contraste du couple ;
   - clarté relative (calc(l ± …)) pour tout ce qui se détache du fond de
     page — bandes, filets, texte secondaire : ceux-là doivent suivre la page
     si elle s'assombrit, pas viser une clarté fixe.
   La saturation est toujours proportionnelle : un accent gris donne un fond
   gris, pas un pastel coloré sorti de nulle part.

   Les valeurs statiques ci-dessus restent la solution de repli des
   navigateurs sans syntaxe de couleur relative (avant Chrome 119 /
   Safari 16.4 / Firefox 128) : le site y garde la charte du thème. */
@supports (color: oklch(from white l c h)) {
    :root, :host {
        --site-accent-vivid: oklch(from var(--site-accent) calc(l + .081) calc(c * 1.08) h);
        --site-accent-bg: oklch(from var(--site-accent) .942 calc(c * .21) h);
        --site-night-soft: oklch(from var(--site-night) calc(l + .09) calc(c * 1.31) h);
        --site-gold-bg: oklch(from var(--site-gold) .93 calc(c * .69) h);
        --site-gold-ink: oklch(from var(--site-gold) .351 calc(c * .62) h);
        --site-teal-bg: oklch(from var(--site-teal) .937 calc(c * .33) h);

        --site-muted: oklch(from var(--site-text) calc(l + .239) calc(c * .5) h);
        --site-bg-alt: oklch(from var(--site-bg) calc(l - .019) calc(c * 1.13) h);
        --site-muted-bg: oklch(from var(--site-bg) calc(l - .037) calc(c * 1.25) h);
        --site-border: oklch(from var(--site-bg) calc(l - .078) calc(c * 1.31) h);
        --site-border-strong: oklch(from var(--site-bg) calc(l - .129) calc(c * 1.25) h);
    }
}

* {
    box-sizing: border-box;
}

/* Accessibilité (RGAA)
   ------------------------------------------------------------------ */

/* Contenu réservé aux lecteurs d'écran : retiré visuellement sans être
   retiré de l'arbre d'accessibilité (display:none le masquerait aussi
   pour les technologies d'assistance). */
.site-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;
}

/* Lien d'évitement : hors écran jusqu'à ce qu'il reçoive le focus. */
.site-skip-link {
    position: absolute;
    left: -9999px;
    top: 0;
    z-index: 100;
    padding: .75rem 1rem;
    background: var(--site-accent);
    color: #fff;
    text-decoration: none;
}

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

/* Focus toujours visible : :focus-visible ne s'affiche qu'au clavier, donc
   sans gêner la navigation à la souris. */
:focus-visible {
    outline: 3px solid var(--site-accent);
    outline-offset: 2px;
}

.site-skip-link:focus-visible {
    outline-color: #fff;
}

/* Respecte le réglage système « réduire les animations ». */
@media (prefers-reduced-motion: reduce) {
    *,
    *::before,
    *::after {
        animation-duration: .01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: .01ms !important;
        scroll-behavior: auto !important;
    }
}

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

/* Échelle typographique
   ------------------------------------------------------------------
   Les tailles par défaut du navigateur donnent une hiérarchie molle : un h2
   à peine plus gros qu'un h3, aucun resserrement. L'échelle ci-dessous est
   fluide (clamp) pour éviter une série de points de rupture, avec un
   interlignage court et un léger resserrement des lettres sur les grands
   titres — sans quoi un titre de deux lignes paraît décousu.
   Elle s'applique aussi au HTML saisi dans le bloc Texte, qui produit ses
   propres h2/h3 : le rendu d'un titre est le même qu'il vienne du bloc Titre
   ou de l'éditeur riche. */
/* Les titres sont en serif, en graisse normale : c'est le dessin de la
   lettre qui porte le titre, pas son gras. D'où des tailles nettement plus
   grandes qu'en sans-serif — un titre serif de 24 px paraît timide là où le
   même en gras s'imposait. */
h1, h2, h3, h4, h5, h6 {
    font-family: var(--site-font-title);
    font-weight: 400;
    line-height: 1.08;
    letter-spacing: -.015em;
    text-wrap: balance;
}

h1 {
    font-size: clamp(2.5rem, 1.6rem + 3.4vw, 3.75rem);
    margin: 0 0 1rem;
}

h2 {
    font-size: clamp(2rem, 1.4rem + 2.2vw, 3rem);
    margin: 0 0 .875rem;
}

h3 {
    font-size: clamp(1.5rem, 1.2rem + 1.2vw, 2rem);
    line-height: 1.15;
    margin: 0 0 .625rem;
}

h4 {
    font-size: 1.375rem;
    line-height: 1.2;
    margin: 0 0 .5rem;
}

/* L'italique du serif est une vraie italique dessinée : elle sert d'accent
   dans un titre, souvent doublée d'un surlignage (voir .site-mark). */
h1 em, h2 em, h3 em {
    font-style: italic;
    color: var(--site-accent);
}

/* Surlignage au feutre : le dégradé s'arrête au quart de la hauteur, ce qui
   imite un trait passé sous le mot plutôt qu'un fond de couleur. */
.site-mark {
    background: linear-gradient(to top, var(--site-gold) 26%, transparent 26%);
    padding: 0 .15em;
}

/* Dans le texte suivi, un titre ouvre une section : il lui faut plus d'air
   au-dessus qu'en dessous. */
.block-text h2,
.block-text h3,
.block-text h4,
.news-article-content h2,
.news-article-content h3 {
    margin-top: 2em;
}

.block-text > :first-child,
.news-article-content > :first-child {
    margin-top: 0;
}

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

/* Header
   Collant : sur une page longue (règlement intérieur, article), le visiteur
   garde la navigation à portée sans remonter. `top: 0` seulement — un
   en-tête qui se replie au défilement demanderait du JS pour un gain
   discutable. */
/* Barre d'accès (layout.twig)
   ------------------------------------------------------------------
   Le bandeau nuit posé au-dessus de l'en-tête : état d'ouverture à gauche,
   liens vers les services externes à droite. Il porte l'information que les
   familles cherchent en premier — « est-ce ouvert maintenant ? » — sans
   occuper la navigation principale. */
.site-accessbar {
    background: var(--site-night);
    color: #dee5f2;
    font-size: .8125rem;
}

.site-accessbar .site-container {
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: .75rem 1.5rem;
    min-height: 40px;
    padding-top: .375rem;
    padding-bottom: .375rem;
}

.site-accessbar-status {
    display: flex;
    align-items: center;
    gap: .625rem;
    margin: 0;
    letter-spacing: .04em;
}

/* La pastille double l'information portée par le texte : elle ne la remplace
   pas — une couleur seule ne peut pas être le seul vecteur d'un état (RGAA). */
.site-accessbar-dot {
    width: .4375rem;
    height: .4375rem;
    border-radius: 50%;
    background: #6ed274;
}

.site-accessbar-status.is-closed .site-accessbar-dot {
    background: #9ea5b2;
}

.site-accessbar-hours {
    color: #abb1be;
}

.site-accessbar-nav ul {
    list-style: none;
    display: flex;
    flex-wrap: wrap;
    gap: 1.375rem;
    margin: 0;
    padding: 0;
}

.site-accessbar-nav a {
    color: inherit;
    text-decoration: none;
}

.site-accessbar-nav a:hover {
    color: var(--site-gold);
}

.site-accessbar :focus-visible {
    outline-color: var(--site-gold);
}

/* En-tête : le même papier crème que la page, en translucide, avec un simple
   filet en bas. Un bandeau de couleur pleine écraserait le bandeau d'accueil
   qui le suit immédiatement. */
.site-header {
    position: sticky;
    top: 0;
    z-index: 30;
    background: rgba(253, 247, 236, .93);
    backdrop-filter: blur(12px);
    color: var(--site-text);
    border-bottom: 1px solid var(--site-border);
}

.site-header .site-container {
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    min-height: 76px;
    gap: 1.5rem;
}

.site-brand {
    display: flex;
    align-items: center;
    gap: .875rem;
    color: var(--site-text);
    text-decoration: none;
    font-family: var(--site-font-title);
    font-weight: 400;
    font-size: 1.5rem;
    line-height: 1.15;
}

/* À défaut de logo téléversé, l'initiale de l'établissement dans un carré
   corail : une marque tient rarement dans un nom seul. */
.site-brand-initial {
    width: 2.75rem;
    height: 2.75rem;
    flex: 0 0 auto;
    display: grid;
    place-items: center;
    border-radius: var(--site-radius-sm);
    background: var(--site-accent-vivid);
    color: #fdf7ec;
    font-size: 1.4375rem;
}

.site-brand-text {
    display: flex;
    flex-direction: column;
}

.site-brand-tagline {
    font-family: var(--site-font-mono);
    font-size: .65625rem;
    letter-spacing: .14em;
    text-transform: uppercase;
    color: var(--site-muted);
}

.site-logo {
    max-height: 44px;
    width: auto;
}

.site-socials {
    list-style: none;
    display: flex;
    flex-wrap: wrap;
    gap: 1rem;
    margin: .75rem 0 0;
    padding: 0;
}

.site-contact {
    margin: .75rem 0 0;
    font-style: normal;
}

.site-contact-item {
    display: inline-block;
    margin-right: 1rem;
}

.site-nav ul {
    list-style: none;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: clamp(.75rem, 1.6vw, 1.625rem);
    margin: 0;
    padding: 0;
}

.site-header .site-nav a {
    color: var(--site-muted);
    text-decoration: none;
    font-size: .9375rem;
    font-weight: 500;
    padding: .375rem 0;
    border-bottom: 2px solid transparent;
}

.site-header .site-nav a:hover,
.site-header .site-nav a[aria-current="page"] {
    color: var(--site-text);
    border-bottom-color: var(--site-accent-vivid);
}

/* Sous-menus (un seul niveau, voir WebsiteMenuItem::MAX_DEPTH).
   Ouverture au survol ET au focus clavier : sans :focus-within, le sous-menu
   serait inatteignable sans souris. */
.site-header .site-nav li {
    position: relative;
}

.site-header .site-nav .site-submenu {
    display: none;
    position: absolute;
    top: 100%;
    left: 0;
    z-index: 10;
    flex-direction: column;
    gap: 0;
    min-width: 12rem;
    padding: .5rem;
    background: var(--site-bg-card);
    border: 1px solid var(--site-border);
    border-radius: var(--site-radius-sm);
    box-shadow: var(--site-shadow-hover);
}

.site-header .site-nav li:hover > .site-submenu,
.site-header .site-nav li:focus-within > .site-submenu {
    display: flex;
}

.site-header .site-nav .site-submenu a {
    display: block;
    padding: .5rem .75rem;
    border-bottom: 0;
    border-radius: calc(var(--site-radius-sm) - 6px);
    white-space: nowrap;
}

.site-header .site-nav .site-submenu a:hover {
    background: var(--site-bg-alt);
    color: var(--site-text);
}

/* Sur petit écran, pas de survol fiable : le sous-menu est déplié en dessous. */
@media (max-width: 700px) {
    .site-header .site-nav .site-submenu {
        display: flex;
        position: static;
        min-width: 0;
        padding: 0 0 0 1rem;
        background: none;
        box-shadow: none;
    }
}

/* Main */
.site-main {
    padding: var(--site-main-padding) 0 calc(var(--site-main-padding) * 1.5);
}

.site-page h1 {
    margin-top: 0;
}

/* Une page qui s'ouvre sur un bloc pleine largeur démarre au ras de
   l'en-tête : le padding du <main> laisserait une bande de papier avant le
   bandeau, qui ressemble à un défaut d'intégration. Le bandeau d'accueil,
   lui, reste dans le conteneur (cadre arrondi) et garde ce padding. */
.site-page-content > .block-width-full:first-child,
.site-home > .block-width-full:first-child {
    margin-top: calc(-1 * var(--site-main-padding));
}

/* Mesure de lecture
   ------------------------------------------------------------------
   Le conteneur s'est élargi pour que les grilles (liens, équipe, actualités)
   respirent, mais une ligne de texte de 1120 px est illisible. La contrainte
   porte donc sur le texte suivi lui-même, jamais sur le bloc : le fond d'un
   encadré ou d'un bandeau garde toute sa largeur. */
.block-text,
.block-toc,
.block-quote blockquote,
.block-callout p,
.accordion-content,
.news-article-content {
    max-width: var(--site-reading);
}

/* Un bloc centré centre aussi sa colonne de texte, sans quoi le texte
   resterait calé à gauche dans une boîte centrée. */
.align-center.block-text,
.align-center .block-callout p,
.align-center.block-quote blockquote,
.block-width-full .align-center p {
    margin-left: auto;
    margin-right: auto;
}

/* Archive des actualités (news.twig) */
.news-categories {
    display: flex;
    flex-wrap: wrap;
    gap: .5rem;
    margin-bottom: 1.5rem;
}

.news-categories a {
    padding: .375rem .75rem;
    border: 1px solid var(--site-muted-bg);
    border-radius: var(--site-radius-pill);
    color: var(--site-muted);
    text-decoration: none;
    font-size: .875rem;
}

.news-categories a.active,
.news-categories a:hover {
    border-color: var(--site-accent);
    background: var(--site-accent-bg);
    color: var(--site-accent);
}

.news-item {
    display: flex;
    gap: 1.5rem;
    padding: 1.25rem;
    margin-bottom: 1rem;
    border: 1px solid var(--site-border);
    border-radius: var(--site-radius);
    transition: box-shadow .18s ease, border-color .18s ease;
}

.news-item:hover {
    border-color: transparent;
    box-shadow: var(--site-shadow-hover);
}

.news-item-cover {
    flex: 0 0 220px;
    overflow: hidden;
    border-radius: var(--site-radius-sm);
}

.news-item-cover img {
    width: 100%;
    height: 150px;
    object-fit: cover;
    display: block;
    transition: transform .4s ease;
}

.news-item:hover .news-item-cover img {
    transform: scale(1.04);
}

.news-item-date {
    color: var(--site-accent);
    font-size: .75rem;
    font-weight: 700;
    letter-spacing: .08em;
    text-transform: uppercase;
}

@media (max-width: 640px) {
    .news-item {
        flex-direction: column;
    }

    .news-item-cover {
        flex: 0 0 auto;
    }
}

.news-item-title {
    margin: .25rem 0 .5rem;
    font-size: 1.25rem;
}

.news-item-title a {
    color: var(--site-text);
    text-decoration: none;
}

.news-item-title a:hover {
    color: var(--site-accent);
}

.news-item-excerpt {
    margin: 0;
    color: var(--site-muted);
}

.news-pagination {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 1rem;
    margin-top: 2rem;
}

@media (max-width: 700px) {
    .news-item {
        flex-direction: column;
    }

    .news-item-cover {
        flex-basis: auto;
    }
}

.news-item-tags {
    margin: 0;
    display: flex;
    flex-wrap: wrap;
    gap: .35rem;
}

/* Article (newsArticle.twig) */
.news-article-meta {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .5rem;
    color: var(--site-muted);
    font-size: .875rem;
    margin-bottom: 1.5rem;
}

.news-article-cover {
    width: 100%;
    max-height: 420px;
    object-fit: cover;
    border-radius: var(--site-radius-sm);
    margin-bottom: 1.5rem;
}

.news-article-content {
    margin-bottom: 2rem;
}

.news-article-back {
    margin-top: 2rem;
    padding-top: 1rem;
    border-top: 1px solid var(--site-muted-bg);
}

/* Bloc Bandeau d'accueil (blocks/hero.twig)
   Toujours pleine largeur : la sortie de conteneur est faite ici, pas par
   l'option commune de largeur (que ce bloc n'expose pas). */
.block-hero {
    position: relative;
    display: flex;
    align-items: flex-end;
    background: var(--site-night);
    background-size: cover;
    background-position: center;
    border-radius: var(--site-radius-lg);
    overflow: hidden;
    isolation: isolate;
    padding: 3rem;
}

.hero-medium { min-height: 420px; }
.hero-large { min-height: min(70vh, 620px); }

/* Deux halos qui dérivent lentement derrière la photo : purement décoratifs,
   coupés par `prefers-reduced-motion` (règle globale plus haut). */
.block-hero::before,
.block-hero::after {
    content: '';
    position: absolute;
    z-index: -1;
    border-radius: 50%;
    filter: blur(10px);
    pointer-events: none;
}

.block-hero::before {
    width: 42vw;
    height: 42vw;
    top: -16vw;
    left: -8vw;
    background: radial-gradient(circle at 35% 35%, rgba(249, 212, 107, .3), transparent 65%);
    animation: hero-drift 22s ease-in-out infinite alternate;
}

.block-hero::after {
    width: 34vw;
    height: 34vw;
    right: -10vw;
    bottom: -18vw;
    background: radial-gradient(circle at 60% 40%, rgba(210, 80, 48, .35), transparent 62%);
    animation: hero-drift 28s ease-in-out infinite alternate-reverse;
}

@keyframes hero-drift {
    from { transform: translate3d(0, 0, 0) scale(1); }
    to { transform: translate3d(3vw, 2vw, 0) scale(1.12); }
}

/* La carte de contenu : c'est elle qui porte le texte, sur un fond crème
   opaque. Aucune photo n'a donc besoin d'être assombrie pour rester
   lisible — le contraste ne dépend plus de l'image choisie par le
   rédacteur, ce qui était la faiblesse du voile sombre. */
.hero-inner {
    position: relative;
    width: 100%;
    max-width: 40rem;
    background: rgba(253, 247, 236, .95);
    border-radius: var(--site-radius);
    padding: 2.5rem 2.75rem;
    color: var(--site-text);
}

.hero-center {
    justify-content: center;
    text-align: center;
}

.hero-center .hero-inner { text-align: center; }

.hero-title {
    margin: 0;
    font-family: var(--site-font-title);
    font-weight: 400;
    font-size: clamp(2.25rem, 1.4rem + 3.4vw, 3.75rem);
    line-height: 1.03;
    letter-spacing: -.015em;
}

.hero-subtitle {
    max-width: 34rem;
    margin: 1.125rem 0 0;
    font-size: clamp(1rem, .95rem + .4vw, 1.125rem);
    line-height: 1.6;
    color: var(--site-muted);
}

.hero-center .hero-subtitle {
    margin-left: auto;
    margin-right: auto;
}

.hero-actions {
    display: flex;
    flex-wrap: wrap;
    gap: .75rem;
    margin: 1.75rem 0 0;
}

/* Entrée en cascade : titre, accroche, puis boutons. Sans JS, l'animation
   joue quand même et s'achève à l'état normal — rien ne peut rester caché. */
.hero-title,
.hero-subtitle,
.hero-actions {
    animation: hero-enter .85s cubic-bezier(.22, .61, .36, 1) both;
}

.hero-subtitle { animation-delay: .12s; }
.hero-actions { animation-delay: .24s; }

@keyframes hero-enter {
    from {
        opacity: 0;
        transform: translateY(18px);
    }
    to {
        opacity: 1;
        transform: none;
    }
}

.hero-center .hero-actions { justify-content: center; }

/* Sur la carte crème, le bouton « contour » reprend le style commun : plus
   besoin de la variante blanche qu'imposait le fond sombre. */
.block-hero .site-btn-outline {
    border-color: var(--site-border-strong);
    color: var(--site-text);
}

.block-hero .site-btn-outline:hover {
    background: var(--site-bg-card);
    border-color: var(--site-night);
}

/* Bloc Tableau (blocks/table.twig)
   .table-scroll est focusable (tabindex="0") pour qu'un tableau plus large que
   l'écran reste défilable au clavier — critère RGAA. */
/* L'encadrement et l'arrondi sont portés par le conteneur, pas par la table :
   `border-collapse: collapse` fait passer les bordures des cellules par-dessus
   les coins arrondis de la table elle-même. */
.table-scroll {
    overflow-x: auto;
    border: 1px solid var(--site-border);
    border-radius: var(--site-radius);
}

.site-table {
    width: 100%;
    border-collapse: collapse;
}

.site-table caption {
    margin-bottom: .625rem;
    text-align: left;
    font-weight: 600;
    color: var(--site-muted);
}

.site-table th,
.site-table td {
    padding: .875rem 1rem;
    border-bottom: 1px solid var(--site-border);
    text-align: left;
    vertical-align: top;
}

.site-table tbody tr:last-child th,
.site-table tbody tr:last-child td {
    border-bottom: 0;
}

.site-table thead th {
    background: var(--site-bg-alt);
    color: var(--site-muted);
    font-family: var(--site-font-mono);
    font-weight: 500;
    font-size: .6875rem;
    letter-spacing: .1em;
    text-transform: uppercase;
    white-space: nowrap;
}

.site-table tbody th[scope="row"] {
    font-weight: 600;
}

.site-table tbody tr:nth-child(even) {
    background: var(--site-bg-alt);
}

/* Titre d'un bloc (liens, chiffres, équipe, documents, agenda, « à lire
   aussi »…) : un seul style pour tous, sinon chaque bloc introduit sa propre
   taille et la page perd sa hiérarchie. */
.links-title,
.stats-title,
.team-title,
.documents-title,
.events-title,
.related-title,
.tiles-title,
.partners-title,
.form-block-title {
    margin: 0 0 1.5rem;
    font-family: var(--site-font-title);
    font-weight: 400;
    font-size: clamp(1.5rem, 1.25rem + 1vw, 2.125rem);
    letter-spacing: -.015em;
    line-height: 1.12;
}

/* Surtitre (bloc Titre, option « surtitre »)
   ------------------------------------------------------------------
   Le petit libellé en capitales espacées posé au-dessus d'un titre de
   section. C'est ce qui distingue une page composée d'une suite de
   paragraphes : il annonce la rubrique là où le titre annonce le sujet.
   Le carré coloré est décoratif, d'où l'absence de texte alternatif. */
.block-overline {
    display: flex;
    align-items: center;
    gap: .625rem;
    margin: 0 0 .75rem;
    font-family: var(--site-font-mono);
    font-size: .75rem;
    font-weight: 500;
    letter-spacing: .16em;
    text-transform: uppercase;
    color: var(--site-accent);
}

.align-center .block-overline,
.align-center.block-heading .block-overline {
    justify-content: center;
}

.align-right .block-overline {
    justify-content: flex-end;
}

/* Sur un fond coloré ou une image, le surtitre reprend la couleur du texte
   ambiant : l'accent y serait illisible. */
.bg-accent .block-overline,
.block-hero .block-overline,
.block-width-full .bg-accent .block-overline {
    color: inherit;
    opacity: .85;
}

/* Bloc Liens utiles (blocks/links.twig) */
.links-grid {
    list-style: none;
    display: grid;
    gap: 1rem;
    margin: 0;
    padding: 0;
}

.links-cols-2 { grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); }
.links-cols-3 { grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); }
.links-cols-4 { grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); }

.links-item {
    display: flex;
    align-items: center;
    gap: 1rem;
    height: 100%;
    padding: 1.125rem 1.25rem;
    border: 1px solid var(--site-border);
    border-radius: var(--site-radius);
    color: var(--site-text);
    text-decoration: none;
    /* Une carte posée sur la page, pas un rectangle dessiné dessus : le léger
       dégradé et l'ombre au repos lui donnent une épaisseur, sans laquelle
       une grille de cartes blanches sur fond blanc reste plate. */
    background: var(--site-bg-card);
    transition: transform var(--site-transition), box-shadow var(--site-transition), border-color var(--site-transition);
}

.links-item:hover {
    border-color: transparent;
    box-shadow: var(--site-shadow-hover);
    transform: translateY(-2px);
}

/* Chevron d'appel : il indique que la carte entière est cliquable, ce que
   ne dit pas un simple changement de fond au survol. */
.links-item::after {
    content: '';
    width: .5rem;
    height: .5rem;
    margin-left: auto;
    flex: 0 0 auto;
    border-top: 2px solid var(--site-accent);
    border-right: 2px solid var(--site-accent);
    transform: rotate(45deg);
    transition: transform .18s ease;
}

.links-item:hover::after {
    transform: rotate(45deg) translate(2px, -2px);
}

/* Pastille d'icône : la couleur d'accent est portée par le fond, l'icône
   reste lisible même sur un thème à accent très clair. */
.links-item-icon {
    width: 2.75rem;
    height: 2.75rem;
    padding: .625rem;
    flex: 0 0 auto;
    border-radius: var(--site-radius-sm);
    background: var(--site-accent-bg);
    fill: var(--site-accent);
}

.links-item-body {
    display: flex;
    flex-direction: column;
    gap: .125rem;
    min-width: 0;
}

.links-item-label { font-weight: 600; }

.links-item-description {
    color: var(--site-muted);
    font-size: .875rem;
    line-height: 1.45;
}

/* Variante « pilules » : une barre de raccourcis, pas une grille de cartes.
   Pensée pour être posée juste sous un bandeau d'accueil, avec les trois ou
   quatre démarches que les familles viennent chercher en premier. */
.block-links.style-pills .links-grid {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: .625rem;
}

.block-links.style-pills .links-item {
    padding: .75rem 1.375rem;
    border-radius: var(--site-radius-pill);
    background: var(--site-bg-card);
    border-color: var(--site-border);
    box-shadow: none;
    font-weight: 600;
    font-size: .9375rem;
    gap: .5rem;
}

.block-links.style-pills .links-item-icon {
    width: 1.25rem;
    height: 1.25rem;
    padding: 0;
    background: none;
}

/* Ni description ni chevron sur une pilule : elle doit rester lisible d'un
   coup d'œil, en une ligne. */
.block-links.style-pills .links-item-description,
.block-links.style-pills .links-item::after {
    display: none;
}

/* Bloc Chiffres clés (blocks/stats.twig) */
.stats-grid {
    list-style: none;
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
    gap: 2rem 1.5rem;
    margin: 0;
    padding: 0;
    text-align: center;
}

.stats-item {
    display: flex;
    flex-direction: column;
    gap: .375rem;
}

/* Un chiffre clé se lit de loin ou ne sert à rien : il est en serif, à la
   taille d'un grand titre. La couleur change d'un chiffre à l'autre — quatre
   nombres de la même teinte se lisent comme un tableau, pas comme des repères
   distincts. */
.stats-item-value {
    font-family: var(--site-font-title);
    font-size: clamp(2.75rem, 2rem + 3vw, 3.5rem);
    font-weight: 400;
    line-height: 1;
    letter-spacing: -.01em;
    color: var(--site-accent);
    font-variant-numeric: tabular-nums;
}

.stats-item:nth-child(4n+2) .stats-item-value { color: var(--site-teal); }
.stats-item:nth-child(4n+3) .stats-item-value { color: #267d30; }
.stats-item:nth-child(4n+4) .stats-item-value { color: #974391; }

.block-width-full > .bg-accent .stats-item-value,
.block-width-full > .bg-accent .stats-item:nth-child(n) .stats-item-value {
    color: var(--site-gold);
}

.stats-item-label {
    color: var(--site-muted);
    font-family: var(--site-font-mono);
    font-size: .6875rem;
    font-weight: 400;
    letter-spacing: .14em;
    text-transform: uppercase;
}

/* Bloc Équipe (blocks/team.twig) */
.team-grid {
    list-style: none;
    display: grid;
    gap: 1.5rem;
    margin: 0;
    padding: 0;
}

.team-cols-2 { grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); }
.team-cols-3 { grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); }
.team-cols-4 { grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); }

.team-member {
    text-align: center;
}

.team-member-photo {
    width: 132px;
    height: 132px;
    object-fit: cover;
    border-radius: 50%;
    margin: 0 auto .875rem;
    display: block;
    /* L'anneau détache le portrait du fond de la page sans lui ajouter de
       cadre : sur une photo claire, sans lui, la tête flotte. */
    box-shadow: 0 0 0 4px var(--site-bg), 0 0 0 5px var(--site-border);
}

.team-member-name {
    margin: 0;
    font-weight: 700;
}

.team-member-role {
    margin: .125rem 0 0;
    color: var(--site-accent);
    font-size: .9375rem;
}

.team-member-description {
    margin: .5rem 0 0;
    color: var(--site-muted);
    font-size: .875rem;
}

/* Bloc Formulaire (blocks/form.twig) — le titre suit le style commun des
   titres de bloc, défini plus haut. */
.form-block-description {
    margin: 0 0 1rem;
    color: var(--site-muted);
}

.form-block-confirmation {
    padding: 1rem;
    border-radius: var(--site-radius-sm);
    background: var(--site-success-bg);
    color: var(--site-success);
    font-weight: 600;
}

.form-block-actions {
    margin-top: 1.5rem;
}

/* Questions du formulaire
   ------------------------------------------------------------------
   Les questions ne sont pas écrites par le thème mais par FormRenderer.js,
   partagé avec le module Formulaires de l'intranet : son HTML porte les
   classes du back-office (.card, .form-control, label.checkbox…) et
   css/form/display.css, chargé avec lui, ne fait que les compléter (notes,
   grilles, RGPD) — il ne les définit jamais. Elles viennent de format.css,
   la feuille de l'intranet, qui n'a rien à faire sur le site public. C'est
   donc au thème de les habiller.

   Tout est sous `.block-form` pour deux raisons : ne rien imposer au reste
   de la page, et passer devant display.css, chargé après cette feuille
   (voir le bloc `assets` de page.twig) et qui gagnerait à spécificité égale.
   Un thème dérivé qui accepte le bloc Formulaire doit reprendre cette
   section — voir README.md. */
.form-block-questions {
    display: grid;
    gap: 1rem;
}

/* Une question = une carte, plus discrète que les cartes éditoriales du
   site : c'est un support de saisie, il ne doit pas concurrencer le
   contenu de la page. */
.block-form .card {
    margin: 0;
    /* Sans min-width:0, la largeur minimale d'une case de grille est celle
       de son contenu : une question en tableau (large) élargirait la carte
       au-delà de l'écran au lieu de défiler dans son .table-responsive. */
    min-width: 0;
    border: 1px solid var(--site-border);
    border-radius: var(--site-radius-sm);
    background: var(--site-bg-card);
    box-shadow: var(--site-shadow);
}

.block-form .card-content {
    padding: 1.25rem 1.375rem;
}

/* Le libellé arrive dans un <h3> : sans cela il hériterait du serif et de
   la taille des titres de section, alors qu'il annonce un champ. */
.block-form .form-question-label {
    margin: 0 0 .875rem;
    font-family: var(--site-font);
    font-weight: 600;
    font-size: 1.0625rem;
    line-height: 1.35;
    letter-spacing: 0;
    color: var(--site-text);
}

.block-form .form-question-label.required::after {
    color: var(--site-danger);
}

.block-form .form-question-media img {
    border-radius: var(--site-radius-sm);
}

/* Champs de saisie */
.block-form .form-control {
    display: block;
    width: 100%;
    padding: .6875rem .875rem;
    border: 1px solid var(--site-border-strong);
    border-radius: var(--site-radius-sm);
    background: var(--site-bg-card);
    color: var(--site-text);
    font: inherit;
    line-height: 1.5;
}

.block-form .form-control::placeholder {
    color: var(--site-muted);
}

/* Aucune règle de focus ici : un champ de saisie déclenche :focus-visible
   même à la souris, l'anneau global suffit — une bordure colorée en plus
   ne ferait que doubler le liseré. */

.block-form textarea.form-control {
    min-height: 8rem;
    resize: vertical;
}

/* Cases à cocher et boutons radio
   ------------------------------------------------------------------
   format.css masque la commande native et redessine tout en ::before /
   ::after sur le <div> du libellé. Ici on garde la commande native, mise
   à la couleur du site par accent-color : moins de CSS à maintenir, et le
   rendu suit les réglages d'accessibilité du système. */
.block-form .checkbox-group,
.block-form .radio-group {
    display: flex;
    flex-direction: column;
    gap: .125rem;
}

.block-form label.checkbox,
.block-form label.radio {
    display: flex;
    align-items: center;
    gap: .625rem;
    padding: .375rem 0;
    cursor: pointer;
}

.block-form label.checkbox input,
.block-form label.radio input {
    flex: none;
    width: 1.125rem;
    height: 1.125rem;
    margin: 0;
    accent-color: var(--site-accent);
    cursor: pointer;
}

.block-form label.checkbox > div,
.block-form label.radio > div {
    line-height: 1.4;
}

/* Option « Autre » : la case et son champ de précision sur une même ligne
   (le .d-flex de FormRenderer vient de la grille de l'intranet, absente
   ici ; le gap remplace le .mr-3 qui l'accompagne). */
.block-form .d-flex {
    display: flex;
    align-items: center;
    gap: .625rem;
}

.block-form .other-input-container {
    min-width: 0;
}

/* Pavé de consentement RGPD */
.block-form .rgpd-consent {
    padding: 1rem 1.125rem;
    border: 1px solid var(--site-border);
    border-radius: var(--site-radius-sm);
    background: var(--site-bg-alt);
}

.block-form .rgpd-consent label.checkbox > div {
    color: var(--site-muted);
}

/* Échelles de notation
   ------------------------------------------------------------------
   display.css met la commande radio en display:none, ce qui la sort aussi
   du parcours clavier : on la repasse hors écran pour qu'elle reste
   focusable, et le focus est reporté sur l'étiquette visible. */
.block-form .rating-option {
    position: relative;
}

.block-form .rating-input {
    display: block;
    position: absolute;
    width: 1px;
    height: 1px;
    opacity: 0;
    pointer-events: none;
}

.block-form .rating-input:focus-visible + .rating-label {
    outline: 3px solid var(--site-accent);
    outline-offset: 2px;
}

.block-form .rating-label:hover {
    background: var(--site-bg-alt);
}

/* Le choix retenu prend l'aplat coloré ; les étoiles et les smileys, eux,
   portent déjà leur couleur — un aplat par-dessus la rendrait illisible. */
.block-form .rating-input:checked + .rating-label {
    background: var(--site-bg-alt);
    color: var(--site-text);
}

.block-form .rating-scale-numbers .rating-input:checked + .rating-label {
    background: var(--site-accent);
    color: #fff;
}

.block-form .rating-scale-numbers .rating-input:checked + .rating-label .rating-number {
    color: inherit;
}

.block-form .rating-scale-numbers .rating-number {
    font-family: var(--site-font-title);
    font-weight: 400;
}

.block-form .rating-label-text {
    color: var(--site-muted);
}

.block-form .rating-input:checked + .rating-label .rating-label-text {
    color: inherit;
}

/* Grille (une question par ligne, une réponse par colonne) */
.block-form .grid-table th,
.block-form .grid-table td,
.block-form .grid-table th:first-child,
.block-form .grid-table td:first-child {
    border-color: var(--site-border);
    background: var(--site-bg-card);
}

.block-form .grid-table th,
.block-form .grid-table thead th:first-child {
    background: var(--site-bg-alt);
    color: var(--site-muted);
    font-family: var(--site-font-mono);
    font-weight: 500;
    font-size: .6875rem;
    letter-spacing: .1em;
    text-transform: uppercase;
}

.block-form .grid-table tbody tr:hover td,
.block-form .grid-table tbody tr:hover td:first-child {
    background: var(--site-bg-alt);
}

.block-form .grid-table td:first-child {
    text-align: left;
}

/* Bloc Documents (blocks/documents.twig) */
.documents-list,
.documents-grid {
    list-style: none;
    margin: 0;
    padding: 0;
}

.documents-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
    gap: .875rem;
}

.documents-item a {
    display: flex;
    align-items: center;
    gap: .875rem;
    padding: .875rem 1.125rem;
    border: 1px solid var(--site-border);
    border-radius: var(--site-radius);
    color: var(--site-text);
    text-decoration: none;
    transition: box-shadow .18s ease, border-color .18s ease;
}

.documents-list .documents-item + .documents-item {
    margin-top: .625rem;
}

.documents-item a:hover {
    border-color: transparent;
    box-shadow: var(--site-shadow-hover);
}

.documents-item svg {
    width: 2.25rem;
    height: 2.25rem;
    padding: .5rem;
    flex: 0 0 auto;
    border-radius: var(--site-radius-sm);
    background: var(--site-accent-bg);
    fill: var(--site-accent);
}

.documents-item-title {
    font-weight: 600;
}

.documents-item-meta {
    margin-left: auto;
    color: var(--site-muted);
    font-size: .8125rem;
    white-space: nowrap;
}

/* Bandeau de prévisualisation (layout.twig) */
.site-preview-banner {
    padding: .625rem 1rem;
    background: var(--site-warning, #b45309);
    color: #fff;
    text-align: center;
    font-size: .875rem;
    font-weight: 600;
}

/* Page 404 (404.twig) */
.site-page-error {
    text-align: center;
    padding: 3rem 0;
}

.site-error-code {
    margin: 0;
    font-size: 4rem;
    font-weight: 700;
    line-height: 1;
    color: var(--site-muted);
}

/* Footer : le seul grand aplat sombre de la page, qui la referme. */
.site-footer {
    margin-top: 5rem;
    background: var(--site-night);
    color: #cbd1df;
    padding: 4rem 0 1.5rem;
    font-size: .9375rem;
}

/* Colonnes du pied de page : leur nombre vient du menu `footer` (une colonne
   par entrée de premier niveau), pas d'une valeur écrite ici. `auto-fit` les
   répartit donc quel qu'en soit le nombre. */
.site-footer-top {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
    gap: 3rem;
}

.site-footer-name {
    margin: 0 0 .75rem;
    font-family: var(--site-font-title);
    font-size: 1.625rem;
    color: #fff;
}

.site-footer-column-title {
    margin: 0 0 .75rem;
    font-family: var(--site-font-mono);
    font-size: .6875rem;
    letter-spacing: .12em;
    text-transform: uppercase;
    color: var(--site-gold);
}

.site-footer-column ul {
    list-style: none;
    display: flex;
    flex-direction: column;
    gap: .625rem;
    margin: 0;
    padding: 0;
}

.site-footer a {
    color: #cbd1df;
    text-decoration: none;
}

.site-footer a:hover {
    color: #fff;
    text-decoration: underline;
}

.site-footer-credit {
    margin: 2rem 0 0;
    padding-top: 1.375rem;
    border-top: 1px solid rgba(255, 255, 255, .12);
    font-size: .84375rem;
    color: #9ea5b2;
}

/* Blocs de contenu */
.block {
    margin-bottom: var(--site-block-gap);
}

/* Largeur des blocs (App\Class\WebsiteBlocks::WIDTH)
   ------------------------------------------------------------------
   Sortie du conteneur centré : `left: 50%` puis recentrage par translation,
   ce qui fonctionne quelle que soit la largeur du conteneur parent, sans
   marges négatives calculées à la main. */
.block-width {
    position: relative;
    left: 50%;
    transform: translateX(-50%);
}

.block-width-full {
    width: 100vw;
}

/* Bandeau pleine largeur : le fond va d'un bord à l'autre, mais le contenu
   reste aligné sur le conteneur du site. Le padding fait le centrage, ce qui
   évite d'ajouter un conteneur interne à chacun des templates de blocs. */
/* Le `+ 1.25rem` reprend le padding interne de .site-container : sans lui, le
   texte d'un bandeau serait décalé de 20 px vers la gauche par rapport à
   celui des blocs qui l'entourent — un désalignement discret mais visible dès
   qu'un bandeau suit un paragraphe. */
.block-width-full > .block {
    padding-left: max(1.25rem, calc(50vw - var(--site-container) / 2 + 1.25rem));
    padding-right: max(1.25rem, calc(50vw - var(--site-container) / 2 + 1.25rem));
    border-radius: 0;
}

/* Une bande colorée est une section, pas un paragraphe sur fond de couleur :
   sans souffle vertical, elle se lit comme un encadré qui aurait débordé.
   Le padding horizontal reste celui calculé ci-dessus. */
.block-width-full > .bg-default,
.block-width-full > .bg-muted,
.block-width-full > .bg-accent,
.block-width-full > .bg-success,
.block-width-full > .bg-warning,
.block-width-full > .bg-danger,
.block-width-full > .block-articleheader {
    padding-top: var(--site-section-padding);
    padding-bottom: var(--site-section-padding);
}

/* Deux bandes de même fond qui se suivent doivent se lire comme une seule
   section : l'écart entre blocs ferait apparaître une couture blanche. */
.block-width-full + .block-width-full {
    margin-top: calc(-1 * var(--site-block-gap));
}

/* 100vw inclut la barre de défilement : sans ça, un bloc pleine largeur
   provoquerait un défilement horizontal de quelques pixels.
   `clip` et non `hidden` : `overflow-x: hidden` fait du <body> un conteneur
   de défilement, ce qui neutralise le `position: sticky` de l'en-tête. */
body {
    overflow-x: clip;
}

/* Options communes (App\Class\WebsiteBlocks::ALIGN/BACKGROUND/SPACING) */
.align-left { text-align: left; }
.align-center { text-align: center; }
.align-right { text-align: right; }

.bg-default,
.bg-muted,
.bg-accent,
.bg-success,
.bg-warning,
.bg-danger {
    padding: 1.75rem;
    border-radius: var(--site-radius);
}

/* Les fonds ne changent que le fond : le texte garde la couleur du corps.
   `bg-muted` forçait la couleur atténuée sur tout son contenu, y compris les
   titres — le contraste tombait sous le seuil RGAA sans que l'auteur de la
   page l'ait demandé. */
.bg-default { background: var(--site-bg-alt); }
.bg-muted { background: var(--site-muted-bg); }
.bg-accent { background: var(--site-accent-bg); }
.bg-success { background: var(--site-success-bg); }
.bg-warning { background: var(--site-warning-bg); }
.bg-danger { background: var(--site-danger-bg); }

/* Sections pleine largeur : elles ne se contentent pas d'un aplat.
   ------------------------------------------------------------------
   En pleine largeur, le fond « accent » devient le vrai bandeau de marque —
   dégradé plein et texte blanc — tandis que les fonds neutres reçoivent une
   trame de points très discrète, qui suffit à les distinguer du blanc de la
   page sans attirer l'œil. */
.block-width-full > .bg-accent {
    background: var(--site-night);
    color: #fdf7ec;
}

.block-width-full > .bg-accent a:not(.site-btn) {
    color: #fff;
    text-decoration-thickness: 2px;
    text-underline-offset: 3px;
}

.block-width-full > .bg-accent .site-btn-solid {
    background: #fff;
    color: var(--site-accent);
    box-shadow: 0 12px 26px -14px rgba(0, 0, 0, .6);
}

/* Opacité volontairement haute : sous 0.9, un libellé de 13 px en capitales
   sur la partie la plus claire du dégradé passe sous le seuil de contraste. */
.block-width-full > .bg-accent .stats-item-label,
.block-width-full > .bg-accent .block-overline {
    color: inherit;
    opacity: .94;
}

.block-width-full > .bg-default,
.block-width-full > .bg-muted {
    border-top: 1px solid var(--site-border);
    border-bottom: 1px solid var(--site-border);
}

.color-muted { color: var(--site-muted); }
.color-accent { color: var(--site-accent); }
.color-success { color: var(--site-success); }
.color-warning { color: var(--site-warning); }
.color-danger { color: var(--site-danger); }

.spacing-none { margin-bottom: 0; }
.spacing-sm { margin-bottom: 1rem; }
.spacing-lg { margin-bottom: calc(var(--site-block-gap) * 1.75); }

/* Bloc Titre
   L'en-tête collant recouvrirait le titre visé depuis le sommaire : la marge
   de défilement le décale d'autant. */
.block-heading {
    scroll-margin-top: 6rem;
}

.block-heading h2,
.block-heading h3,
.block-heading h4 {
    margin: 0;
}

/* Bloc Image et Bloc Vidéo (la classe .block-image/.block-video est portée
   par le <figure> lui-même) : ne touchent pas margin-bottom, laissé à
   .block / .spacing-* (cascade). La largeur est portée par l'option commune
   (.block-width-*), pas par ces blocs. */
.block-image,
.block-video {
    margin-top: 0;
    margin-left: 0;
    margin-right: 0;
}

.block-image img {
    max-width: 100%;
    height: auto;
    border-radius: var(--site-radius-sm);
    display: block;
}

.block-image img { width: 100%; }
/* Sortie de conteneur : gérée par l'option commune de largeur
   (.block-width-*), plus par des classes propres à ces deux blocs. */
.block-width-full .block-image img { border-radius: 0; }
.block-width-full .block-video .video-responsive,
.block-width-full .block-video video { border-radius: 0; }

.block-image figcaption,
.block-video figcaption {
    margin-top: .5rem;
    font-size: .875rem;
    color: var(--site-muted);
}

.block-image figcaption .credit {
    opacity: .8;
}

/* Bloc Vidéo */
.block-video video {
    max-width: 100%;
    border-radius: var(--site-radius-sm);
    display: block;
}

.video-responsive {
    position: relative;
    padding-bottom: 56.25%; /* 16:9 */
    height: 0;
    overflow: hidden;
    border-radius: var(--site-radius-sm);
}

.video-responsive iframe {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    border: 0;
}

.video-fallback a {
    color: var(--site-accent);
}

/* Bloc Galerie */
.gallery-grid {
    display: grid;
    gap: 1rem;
}

.gallery-cols-2 { grid-template-columns: repeat(2, 1fr); }
.gallery-cols-3 { grid-template-columns: repeat(3, 1fr); }
.gallery-cols-4 { grid-template-columns: repeat(4, 1fr); }

.gallery-item {
    margin: 0;
    overflow: hidden;
    border-radius: var(--site-radius);
}

.gallery-item img {
    width: 100%;
    height: 100%;
    aspect-ratio: 4 / 3;
    object-fit: cover;
    display: block;
    transition: transform .4s ease;
}

.gallery-item:hover img {
    transform: scale(1.05);
}

/* Disposition « bande » : une frise d'images bord à bord, qui défile
   horizontalement. Elle sert de respiration entre deux sections de texte,
   là où une grille demanderait au visiteur de la regarder image par image.
   Le défilement reste manuel (pas d'animation automatique) : une bande qui
   bouge toute seule est ingérable au clavier et fatigante à lire. */
.gallery-strip {
    display: flex;
    gap: .5rem;
    overflow-x: auto;
    scroll-snap-type: x mandatory;
    padding-bottom: .5rem;
    /* La bande touche les bords de l'écran même quand le bloc est dans le
       conteneur : c'est ce débord qui fait la frise. */
    scrollbar-width: thin;
}

.gallery-strip .gallery-item {
    flex: 0 0 clamp(240px, 30vw, 420px);
    scroll-snap-align: start;
    border-radius: 0;
}

.gallery-strip .gallery-item img {
    aspect-ratio: 3 / 2;
}

.gallery-strip .gallery-item:first-child { border-radius: var(--site-radius) 0 0 var(--site-radius); }
.gallery-strip .gallery-item:last-child { border-radius: 0 var(--site-radius) var(--site-radius) 0; }

/* En pleine largeur, la frise touche vraiment les bords : le padding qui
   recentre le contenu des bandeaux la ramènerait dans le conteneur, et une
   frise qui s'arrête à 1120 px n'est plus une frise. */
.block-width-full > .block-gallery.has-strip {
    padding-left: 0;
    padding-right: 0;
}

.block-width-full .gallery-strip .gallery-item {
    border-radius: 0;
}

.gallery-item figcaption {
    margin-top: .4rem;
    font-size: .8125rem;
    color: var(--site-muted);
}

@media (max-width: 640px) {
    .gallery-cols-3,
    .gallery-cols-4 {
        grid-template-columns: repeat(2, 1fr);
    }
}

/* Bloc Embed */
.embed-map {
    position: relative;
    height: 400px;
    border-radius: var(--site-radius-sm);
    overflow: hidden;
}

.embed-map iframe {
    width: 100%;
    height: 100%;
    border: 0;
}

.embed-link-card {
    display: flex;
    align-items: center;
    gap: .6rem;
    padding: 1rem 1.25rem;
    background: var(--site-bg-alt);
    border-radius: var(--site-radius-sm);
    color: var(--site-text);
    text-decoration: none;
    word-break: break-all;
}

.embed-link-card:hover {
    background: var(--site-muted-bg);
}

.embed-link-card svg {
    flex-shrink: 0;
    width: 1.25rem;
    height: 1.25rem;
    fill: var(--site-accent);
}

/* Bloc Citation */
.block-quote blockquote {
    margin: 0;
    padding: 0;
    font-style: italic;
}

.block-quote.style-boxed blockquote {
    padding: 2rem 2.25rem;
    border-radius: var(--site-radius);
    background: var(--site-gold-bg);
}

/* Citation mise en avant : le guillemet ouvrant, en très grand et en
   filigrane, sert de signal visuel — la seule italique ne suffit pas à
   détacher la citation du texte qui l'entoure. */
.block-quote.style-large blockquote {
    position: relative;
    padding-top: 2.25rem;
    font-family: var(--site-font-title);
    font-size: clamp(1.75rem, 1.3rem + 1.8vw, 2.5rem);
    line-height: 1.22;
    font-style: normal;
    font-weight: 400;
    letter-spacing: -.015em;
}

.block-quote.style-large blockquote::before {
    content: '\201C';
    position: absolute;
    top: -.75rem;
    left: -.25rem;
    font-family: var(--site-font-title);
    font-size: 5rem;
    line-height: 1;
    color: var(--site-accent-vivid);
    opacity: .25;
}

.align-center.block-quote.style-large blockquote::before {
    left: 50%;
    transform: translateX(-50%);
}

.block-quote cite {
    display: block;
    margin-top: 1.25rem;
    font-family: var(--site-font-mono);
    font-style: normal;
    font-size: .75rem;
    font-weight: 500;
    letter-spacing: .1em;
    text-transform: uppercase;
    color: var(--site-muted);
}

/* Bloc Encadré
   ------------------------------------------------------------------
   Une information de service (dates d'inscription, fermeture exceptionnelle)
   se présente comme le bandeau « à la une » d'un journal : un aplat clair,
   un pictogramme en pastille, et le texte sur une seule ligne de lecture. */
.block-callout {
    display: flex;
    gap: 1.25rem;
    align-items: center;
    padding: 1.375rem 1.75rem;
    border-radius: var(--site-radius);
}

/* Le type « info » — le plus courant — prend le jaune du bandeau « à la une ».
   Les trois autres gardent la couleur de leur nature (succès, attention,
   danger), sans quoi une alerte se lirait comme une simple information. */
.block-callout.bg-accent {
    background: var(--site-gold-bg);
}

.block-callout svg {
    flex-shrink: 0;
    width: 2.5rem;
    height: 2.5rem;
    padding: .5rem;
    border-radius: var(--site-radius-pill);
    background: var(--site-accent);
    fill: #fff;
}

.block-callout.bg-success svg { background: var(--site-success); }
.block-callout.bg-warning svg { background: var(--site-warning); }
.block-callout.bg-danger svg { background: var(--site-danger); }

.block-callout p {
    margin: 0;
    line-height: 1.55;
}

/* Bloc Bouton
   Le bouton plein porte le dégradé de marque et une ombre teintée : c'est le
   point le plus regardé d'une page, celui qui doit avoir de la couleur. Le
   reflet qui le traverse au survol (::before) remplace le classique
   changement d'opacité, qui ne se voit pas. */
.site-btn {
    position: relative;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: .5rem;
    padding: .75rem 1.75rem;
    border-radius: var(--site-radius-pill);
    text-decoration: none;
    font-weight: 600;
    line-height: 1.25;
    border: 2px solid transparent;
    overflow: hidden;
    transition: transform var(--site-transition), box-shadow var(--site-transition), background-color var(--site-transition);
}

.site-btn-sm { padding: .5rem 1.125rem; font-size: .9375rem; }
.site-btn-lg { padding: .9375rem 2.25rem; font-size: 1.125rem; }

/* Bouton principal : bleu nuit sur crème. Le reflet qui le traverse au
   survol remplace le changement d'opacité, qui ne se voyait pas. */
.site-btn-solid {
    background: var(--site-night);
    color: #fdf7ec;
}

.site-btn-solid::before {
    content: '';
    position: absolute;
    top: 0;
    left: -60%;
    width: 45%;
    height: 100%;
    background: linear-gradient(100deg, transparent, rgba(255, 255, 255, .28), transparent);
    transform: skewX(-18deg);
    transition: left .55s ease;
}

.site-btn-solid:hover {
    background: var(--site-night-soft);
    transform: translateY(-2px);
    box-shadow: var(--site-shadow-hover);
}

.site-btn-solid:hover::before {
    left: 115%;
}

/* Bouton secondaire : simple contour, sans remplissage — sur un fond crème,
   deux aplats côte à côte se disputeraient l'attention. */
.site-btn-outline {
    background: transparent;
    border-color: var(--site-border-strong);
    color: var(--site-text);
}

.site-btn-outline:hover {
    background: var(--site-bg-card);
    border-color: var(--site-night);
}

/* Appel à l'action secondaire, corail : réservé aux actions d'inscription et
   de contact, celles qu'un visiteur doit trouver sans chercher. */
.site-btn-accent.site-btn-solid {
    background: var(--site-accent);
    color: #fff;
}

.site-btn-accent.site-btn-solid:hover {
    background: var(--site-accent-vivid);
}

.site-btn-success.site-btn-solid { background: var(--site-success); }
.site-btn-success.site-btn-outline { border-color: var(--site-success); color: var(--site-success); }
.site-btn-warning.site-btn-solid { background: var(--site-warning); }
.site-btn-warning.site-btn-outline { border-color: var(--site-warning); color: var(--site-warning); }
.site-btn-danger.site-btn-solid { background: var(--site-danger); }
.site-btn-danger.site-btn-outline { border-color: var(--site-danger); color: var(--site-danger); }

/* Bloc Séparateur */
.site-divider-line {
    border: none;
    border-top: 1px solid var(--site-muted-bg);
}

.site-divider-line.size-sm { margin: 1rem 0; }
.site-divider-line.size-md { margin: 2rem 0; }
.site-divider-line.size-lg { margin: 3.5rem 0; }

.site-spacer.size-sm { height: 1rem; }
.site-spacer.size-md { height: 2.5rem; }
.site-spacer.size-lg { height: 5rem; }
.site-spacer.size-xl { height: 8rem; }

/* Bloc Accordéon (<details>/<summary> natifs) */
.block-accordion {
    border-top: 1px solid var(--site-muted-bg);
}

.accordion-item {
    border-bottom: 1px solid var(--site-muted-bg);
}

.accordion-item summary {
    display: flex;
    align-items: center;
    gap: .875rem;
    padding: 1.125rem 0;
    font-weight: 600;
    cursor: pointer;
    list-style: none;
}

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

/* Chevron plutôt que +/− : la rotation dit l'état (ouvert/fermé) sans
   changer de glyphe, et se lit à la même vitesse qu'un signe. */
.accordion-item summary::before {
    content: '';
    width: .5rem;
    height: .5rem;
    flex: 0 0 auto;
    margin-right: .25rem;
    border-right: 2px solid var(--site-accent);
    border-bottom: 2px solid var(--site-accent);
    transform: rotate(-45deg);
    transition: transform .2s ease;
}

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

.block-accordion.marker-success .accordion-item summary::before { border-color: var(--site-success); }
.block-accordion.marker-warning .accordion-item summary::before { border-color: var(--site-warning); }
.block-accordion.marker-danger .accordion-item summary::before { border-color: var(--site-danger); }

.accordion-content {
    padding: 0 0 1.25rem 1.75rem;
    white-space: pre-line;
}

/* Bloc Colonnes */
.block-columns {
    display: grid;
    gap: 2rem;
}

.block-columns.columns-2 { grid-template-columns: repeat(2, 1fr); }
.block-columns.columns-3 { grid-template-columns: repeat(3, 1fr); }
.block-columns.valign-center { align-items: center; }

.columns-col > .block:last-child {
    margin-bottom: 0;
}

@media (max-width: 640px) {
    .block-columns.columns-2,
    .block-columns.columns-3 {
        grid-template-columns: 1fr;
    }
}

.block-text-images {
    display: flex;
    gap: 2rem;
    align-items: flex-start;
    flex-wrap: wrap;
}

.block-text-images .block-text-images-text {
    flex: 3;
    min-width: 260px;
}

.block-text-images .block-text-images-media {
    flex: 2;
    min-width: 260px;
    /* Contient l'agrandissement au survol (voir plus bas) : sans lui, l'image
       déborderait de son coin arrondi. */
    overflow: hidden;
    border-radius: var(--site-radius);
}

.block-text-images.media-left .block-text-images-media {
    order: -1;
}

.block-text-images img {
    width: 100%;
    height: auto;
    border-radius: var(--site-radius-sm);
    display: block;
}

/* Carrousel */
.site-carousel {
    position: relative;
}

.site-carousel-prev,
.site-carousel-next {
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
    background: rgba(0, 0, 0, .45);
    color: #fff;
    border: none;
    border-radius: 50%;
    width: 36px;
    height: 36px;
    font-size: 1.25rem;
    line-height: 1;
    cursor: pointer;
}

.site-carousel-prev { left: .5rem; }
.site-carousel-next { right: .5rem; }

.site-carousel-prev:hover,
.site-carousel-next:hover {
    background: rgba(0, 0, 0, .7);
}

.site-carousel-dots {
    display: flex;
    justify-content: center;
    gap: .4rem;
    margin-top: .5rem;
}

.site-carousel-dots button {
    width: 10px;
    height: 10px;
    border-radius: 50%;
    border: none;
    background: #c4c8cf;
    cursor: pointer;
    padding: 0;
}

.site-carousel-dots button.active {
    background: var(--site-accent);
}

/* Bloc En-tête d'article */
.block-articleheader {
    padding: clamp(2.5rem, 5vw, 4.5rem) 1.5rem;
    text-align: center;
    background-size: cover;
    background-position: center;
    border-radius: var(--site-radius);
}

.block-articleheader.align-left { text-align: left; }

.block-articleheader.has-bg {
    color: #fff;
}

.block-articleheader h1 {
    margin: 0 auto .75rem;
    max-width: 22ch;
}

.block-articleheader.align-left h1 {
    margin-left: 0;
}

.articleheader-category {
    display: inline-block;
    padding: .3125rem .875rem;
    border-radius: var(--site-radius-pill);
    background: var(--site-accent-bg);
    color: var(--site-accent);
    font-size: .75rem;
    font-weight: 700;
    letter-spacing: .08em;
    text-transform: uppercase;
    margin-bottom: 1rem;
}

.block-articleheader.has-bg .articleheader-category {
    background: rgba(255, 255, 255, .15);
    color: #fff;
}

.articleheader-excerpt {
    font-size: 1.1875rem;
    line-height: 1.5;
    max-width: 46ch;
    margin: 0 auto 1.25rem;
    opacity: .9;
}

.block-articleheader.align-left .articleheader-excerpt {
    margin-left: 0;
}

.articleheader-meta {
    display: flex;
    gap: 1rem;
    justify-content: center;
    flex-wrap: wrap;
    font-size: .875rem;
    margin: 0;
    opacity: .8;
}

.block-articleheader.align-left .articleheader-meta {
    justify-content: flex-start;
}

/* Bloc Sommaire */
.block-toc {
    padding: 1.25rem 1.5rem;
    background: var(--site-bg-alt);
    border: 1px solid var(--site-border);
    border-radius: var(--site-radius);
}

.toc-title {
    margin: 0 0 .625rem;
    font-family: var(--site-font-mono);
    font-size: .6875rem;
    font-weight: 500;
    letter-spacing: .12em;
    text-transform: uppercase;
    color: var(--site-muted);
}

.block-toc li {
    margin-bottom: .25rem;
}

.block-toc ul {
    margin: 0;
    padding-left: 1.1rem;
}

.block-toc .toc-level-3 { padding-left: 1rem; }
.block-toc .toc-level-4 { padding-left: 2rem; }

.block-toc a {
    color: var(--site-text);
}

.toc-sidebar {
    float: right;
    width: 260px;
    margin-left: 2rem;
}

@media (max-width: 720px) {
    .toc-sidebar {
        float: none;
        width: auto;
        margin-left: 0;
    }
}

/* Blocs À lire aussi et Actualités (mêmes cartes)
   ------------------------------------------------------------------
   Une carte d'actualité est d'abord une image : c'est elle qui donne envie
   de cliquer, le titre confirme. La photo occupe donc tout le haut de la
   carte, le titre est en serif, et la date passe en monospace — trois
   familles pour trois natures d'information. */
.related-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
    gap: 1.5rem;
}

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

.related-item {
    display: flex;
    flex-direction: column;
    border: 1px solid var(--site-border);
    border-radius: var(--site-radius);
    background: var(--site-bg-card);
    color: var(--site-text);
    text-decoration: none;
    overflow: hidden;
    transition: transform var(--site-transition), box-shadow var(--site-transition);
}

.related-item:hover {
    transform: translateY(-4px);
    box-shadow: var(--site-shadow-hover);
}

.related-item-cover {
    display: block;
    width: 100%;
    aspect-ratio: 16 / 9;
    object-fit: cover;
    transition: transform .5s ease;
}

.related-item:hover .related-item-cover {
    transform: scale(1.04);
}

/* Le corps de la carte : tout ce qui n'est pas la photo. Le padding est posé
   ici plutôt que sur la carte, sinon la photo ne pourrait pas aller d'un
   bord à l'autre. */
.related-item-date,
.related-item-title,
.related-item-excerpt {
    padding-left: 1.625rem;
    padding-right: 1.625rem;
}

.related-item-date {
    display: block;
    padding-top: 1.5rem;
    margin-bottom: .5rem;
    font-family: var(--site-font-mono);
    font-size: .6875rem;
    letter-spacing: .1em;
    text-transform: uppercase;
    color: var(--site-muted);
}

.related-item-title {
    display: block;
    font-family: var(--site-font-title);
    font-weight: 400;
    font-size: 1.5rem;
    line-height: 1.15;
}

.related-item-title:first-child {
    padding-top: 1.5rem;
}

.related-item-excerpt {
    display: block;
    margin-top: .625rem;
    padding-bottom: 1.75rem;
    font-size: .9375rem;
    line-height: 1.6;
    color: var(--site-muted);
}

.related-item-title:last-child {
    padding-bottom: 1.75rem;
}

/* En liste, la carte reste compacte : ni photo pleine largeur ni gros titre,
   c'est une file de liens, pas une deuxième grille. */
.related-list .related-item-cover {
    aspect-ratio: 21 / 9;
}

.related-list .related-item-title {
    font-size: 1.25rem;
}

/* Bloc Auteur */
.block-authorbox {
    display: flex;
    gap: 1rem;
    padding: 1.5rem;
    background: var(--site-bg-alt);
    border-radius: var(--site-radius-sm);
}

.block-authorbox.align-center {
    flex-direction: column;
    align-items: center;
    text-align: center;
}

.authorbox-avatar {
    width: 64px;
    height: 64px;
    border-radius: 50%;
    object-fit: cover;
    flex-shrink: 0;
}

.authorbox-name {
    font-weight: 600;
    margin: 0 0 .35rem;
}

.authorbox-bio {
    margin: 0 0 .5rem;
    color: var(--site-muted);
}

.authorbox-socials {
    display: flex;
    gap: .6rem;
}

.authorbox-socials svg {
    width: 1.1rem;
    height: 1.1rem;
    fill: var(--site-accent);
}

/* Bloc Portes d'entrée (blocks/tiles.twig)
   ------------------------------------------------------------------
   La première question d'un visiteur sur un site d'établissement n'est pas
   « que proposez-vous ? » mais « laquelle de ces entrées est la mienne ? ».
   D'où de grandes cartes illustrées, photo au-dessus et intitulé en serif
   en dessous : le texte garde son contraste quelle que soit la photo. */
.tiles-grid {
    list-style: none;
    display: grid;
    grid-template-columns: var(--tiles-columns);
    gap: 1.5rem;
    margin: 0;
    padding: 0;
}

/* Le gabarit de colonnes passe par une variable, et non directement par ces
   trois règles : en disposition « slider », c'est le ruban intérieur de Swiper
   qui doit le porter, pas la piste. Une variable descend jusqu'à lui, une
   déclaration de grille non. */
.tiles-cols-2 { --tiles-columns: repeat(auto-fit, minmax(320px, 1fr)); }
.tiles-cols-3 { --tiles-columns: repeat(auto-fit, minmax(280px, 1fr)); }
.tiles-cols-4 { --tiles-columns: repeat(auto-fit, minmax(240px, 1fr)); }

.tiles-link {
    display: flex;
    flex-direction: column;
    height: 100%;
    border-radius: var(--site-radius);
    overflow: hidden;
    background: var(--site-bg-card);
    border: 1px solid var(--site-border);
    text-decoration: none;
    color: var(--site-text);
    transition: transform var(--site-transition), box-shadow var(--site-transition);
}

.tiles-link:hover {
    transform: translateY(-4px);
    box-shadow: var(--site-shadow-hover);
}

.tiles-item-media {
    position: relative;
    display: block;
    height: 150px;
    background: var(--site-muted-bg);
    overflow: hidden;
}

/* Sans photo, la bande d'image resterait un aplat crème vide : elle prend le
   bleu nuit, ce qui donne quand même une tuile finie. */
.tiles-link:not(.has-image) .tiles-item-media {
    background: var(--site-night);
}

.tiles-link:not(.has-image) .tiles-item-icon {
    background: rgba(253, 247, 236, .16);
    fill: #fdf7ec;
}

.tiles-item-media img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
    transition: transform .5s ease;
}

.tiles-link:hover .tiles-item-media img {
    transform: scale(1.04);
}

/* L'icône se pose en pastille sur la photo : elle identifie la rubrique d'un
   coup d'œil, y compris quand la photo est encore en cours de chargement. */
.tiles-item-icon {
    position: absolute;
    left: 1rem;
    bottom: 1rem;
    width: 2.5rem;
    height: 2.5rem;
    padding: .5rem;
    border-radius: var(--site-radius-sm);
    background: rgba(253, 247, 236, .92);
    fill: var(--site-accent);
}

.tiles-item-body {
    display: block;
    padding: 1.625rem 1.75rem 1.875rem;
}

.tiles-item-label {
    display: block;
    font-family: var(--site-font-title);
    font-size: 1.75rem;
    line-height: 1.1;
    margin-bottom: .375rem;
}

.tiles-item-description {
    display: block;
    font-size: .9375rem;
    line-height: 1.55;
    color: var(--site-muted);
}

/* Slider de portes d'entrée (disposition « slider »)
   ------------------------------------------------------------------
   Une bande qui défile horizontalement plutôt qu'une grille qui se replie sur
   plusieurs lignes. C'est ce qu'il faut dès que les entrées sont nombreuses et
   de même nature — une série d'articles, une série de niveaux — là où la
   grille dit « voici tout », la bande dit « en voici le début ».

   Le mécanisme est Swiper (vendor/swiper/swiper-bundle.min.css, chargé avant
   cette feuille, initialisé dans theme.js). Ce qui suit ne fait que l'habiller :
   Swiper pose la mécanique de défilement et laisse ses flèches et ses points
   sans forme arrêtée, ce qui tombe bien — le thème a les siennes. */
.tiles-slider {
    position: relative;
}

/* La piste rogne ce qui la déborde : sans ce padding, l'ombre des cartes au
   survol serait coupée en bas et sur les côtés. La marge négative rend au bloc
   la largeur que le padding lui prend, pour que la bande reste alignée sur les
   autres blocs de la page. */
.tiles-track.swiper {
    /* La piste est une fenêtre, pas une mise en page : elle doit lâcher la
       grille héritée de .tiles-grid, sinon le ruban de Swiper se retrouverait
       casé dans une colonne de 280 px au lieu de la largeur entière. */
    display: block;
    padding: .25rem .25rem 1.5rem;
    margin: -.25rem -.25rem -1.5rem;
}

/* Hauteurs égales. Swiper donne à ses diapositives la hauteur de la piste, ce
   qui laisse les cartes à la hauteur de leur contenu : trois cartes aux
   descriptions inégales finissent dépareillées. `height: auto` les étire toutes
   sur la plus haute. */
.tiles-track .swiper-slide {
    height: auto;
}

/* Avant que Swiper n'ait pris la main — et pour toujours si le script ne se
   charge pas —, la piste n'est qu'un conteneur qui rogne, avec un ruban de
   tuiles pleine largeur : une seule serait visible, les autres inatteignables.
   Ces trois règles lui rendent l'allure d'une grille, celle du gabarit en
   disposition « grille ». C'est à la fois le repli sans JavaScript et ce qui
   évite le soubresaut au moment de l'initialisation. */
.tiles-track:not(.swiper-initialized) {
    overflow: visible;
}

.tiles-track:not(.swiper-initialized) .swiper-wrapper {
    display: grid;
    grid-template-columns: var(--tiles-columns);
    gap: 1.5rem;
}

.tiles-track:not(.swiper-initialized) .swiper-slide {
    width: auto;
}

/* Les flèches et les points sont hors de la piste, qui rogne : ils ne
   s'afficheraient pas dedans. Ils restent donc masqués tant que Swiper ne les
   a pas armés — sans lui, ils ne commanderaient rien. */
.tiles-slider-nav,
.tiles-slider-dots {
    display: none;
}

/* Flèches
   ------------------------------------------------------------------
   Posées sur les bords de la bande, à cheval sur les cartes. */
.swiper-initialized ~ .tiles-slider-nav {
    display: flex;
    position: absolute;
    top: 4.6875rem;
    z-index: 3;
    width: 2.75rem;
    height: 2.75rem;
    padding: 0;
    align-items: center;
    justify-content: center;
    border: 1px solid var(--site-border);
    border-radius: 50%;
    background: var(--site-bg-card);
    color: var(--site-text);
    box-shadow: var(--site-shadow-hover);
    cursor: pointer;
    transition: background-color var(--site-transition), color var(--site-transition), opacity var(--site-transition);
}

.tiles-slider-nav.is-prev { left: -1.125rem; }
.tiles-slider-nav.is-next { right: -1.125rem; }

.tiles-slider-nav svg {
    width: 1.25rem;
    height: 1.25rem;
}

.tiles-slider-nav:hover:not(.swiper-button-disabled) {
    background: var(--site-accent);
    border-color: var(--site-accent);
    color: #fff;
}

/* Estompée plutôt que masquée : une flèche qui disparaît au bout de la bande
   décale l'autre et fait sauter la mise en page à chaque saut. */
.tiles-slider-nav.swiper-button-disabled {
    opacity: .35;
    cursor: default;
}

/* `swiper-button-lock` : Swiper la pose quand tout tient dans la largeur —
   trois tuiles affichées sur trois n'ont rien à faire défiler. */
.tiles-slider-nav.swiper-button-lock,
.tiles-slider-dots.swiper-pagination-lock {
    display: none;
}

/* Points
   ------------------------------------------------------------------
   Ils disent combien de vues il reste, ce que les flèches ne disent pas. Des
   barres plutôt que des pastilles : à 8 px, un rond actif et un rond inactif se
   distinguent mal, deux barres de longueurs différentes non. */
.swiper-initialized ~ .tiles-slider-dots {
    display: flex;
    justify-content: center;
    align-items: center;
    gap: .5rem;
    margin-top: 1.25rem;
}

.tiles-slider-dots .swiper-pagination-bullet {
    width: 1.25rem;
    height: .375rem;
    margin: 0;
    border: 0;
    border-radius: var(--site-radius-pill);
    background: var(--site-border-strong);
    opacity: 1;
    cursor: pointer;
    transition: background-color var(--site-transition), width var(--site-transition);
}

.tiles-slider-dots .swiper-pagination-bullet-active {
    width: 2.25rem;
    background: var(--site-accent);
}

.tiles-slider-dots .swiper-pagination-bullet:hover {
    background: var(--site-accent-vivid);
}

/* Sur téléphone, les flèches n'ont plus la place de se poser à cheval sur les
   cartes sans en masquer la moitié : les points et le glissé au doigt
   suffisent. */
@media (max-width: 640px) {
    .tiles-track:not(.swiper-initialized) .swiper-wrapper {
        gap: 1rem;
    }

    .swiper-initialized ~ .tiles-slider-nav {
        display: none;
    }
}

/* Bloc Logos partenaires (blocks/partners.twig)
   Les logos sont désaturés au repos : une rangée de logos multicolores
   attire plus l'œil que le contenu de la page, alors qu'elle n'est qu'une
   mention. La couleur revient au survol. */
.partners-row {
    list-style: none;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: center;
    gap: 2rem 2.5rem;
    margin: 0;
    padding: 0;
}

.partners-item img {
    max-height: 34px;
    max-width: 140px;
    width: auto;
    display: block;
    filter: grayscale(1);
    opacity: .65;
    transition: filter .2s ease, opacity .2s ease;
}

.partners-item:hover img,
.partners-item a:focus-visible img {
    filter: grayscale(0);
    opacity: 1;
}

/* Bloc Agenda (blocks/events.twig)
   ------------------------------------------------------------------
   Le seul bloc de couleur pleine de la page : un agenda se consulte, il ne
   se lit pas comme le reste. Le turquoise le sort du flux crème sans
   reprendre le corail, déjà porteur des appels à l'action. */
.block-events {
    background: var(--site-teal);
    color: #fff;
    border-radius: var(--site-radius-lg);
    padding: 2.25rem 2rem;
}

.block-events .events-title {
    color: #fff;
}

.events-list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
}

.events-item {
    display: flex;
    align-items: center;
    gap: 1.125rem;
    padding: 1.125rem .25rem;
    border-top: 1px solid rgba(255, 255, 255, .22);
}

.events-item:first-child {
    border-top: 0;
}

/* Pastille de date translucide : sur l'aplat turquoise, un fond blanc plein
   ferait tache — la transparence garde l'unité du bloc. */
.events-item-date {
    flex: 0 0 3.875rem;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    padding: .5rem 0;
    border-radius: var(--site-radius-sm);
    background: rgba(255, 255, 255, .14);
    color: #fff;
    line-height: 1.05;
}

.events-item-day {
    font-family: var(--site-font-title);
    font-size: 1.75rem;
    line-height: 1;
}

.events-item-month {
    font-family: var(--site-font-mono);
    font-size: .625rem;
    letter-spacing: .12em;
    text-transform: uppercase;
    color: var(--site-gold);
}

.events-item-title {
    margin: 0;
    font-weight: 600;
    font-size: 1.03125rem;
    line-height: 1.3;
}

.events-item-when {
    margin: .25rem 0 0;
    color: rgba(255, 255, 255, .8);
    font-size: .84375rem;
}

.events-item-description {
    margin: .5rem 0 0;
    font-size: .9375rem;
    color: rgba(255, 255, 255, .88);
}

/* ======================================================================
   Animations et effets
   ======================================================================
   Trois principes, pour que le mouvement reste au service de la lecture :

   1. Rien ne dépend du JavaScript pour être visible. Les apparitions au
      défilement ne sont armées que si `theme.js` a posé `.js-enabled` sur
      <html> ; sans lui, tout s'affiche normalement.
   2. Rien ne bouge pour ceux qui n'en veulent pas : la règle globale
      `prefers-reduced-motion` (tout en haut de ce fichier) neutralise
      transitions et animations, et theme.js n'arme alors aucun observateur.
   3. Le mouvement porte l'attention, il ne la disperse : une seule
      apparition par bloc, jamais d'animation en boucle sur du texte.
   ====================================================================== */

/* Apparition au défilement. `theme.js` pose `.reveal` sur les blocs de la
   page puis `.is-visible` quand ils entrent dans le champ. */
.js-enabled .reveal {
    opacity: 0;
    transform: translateY(28px);
    transition:
        opacity var(--site-reveal-duration) cubic-bezier(.22, .61, .36, 1),
        transform var(--site-reveal-duration) cubic-bezier(.22, .61, .36, 1);
    will-change: opacity, transform;
}

.js-enabled .reveal.is-visible {
    opacity: 1;
    transform: none;
    will-change: auto;
}

/* À l'impression, aucun défilement n'a lieu : tout ce qui attend encore son
   apparition sortirait blanc sur le papier. Le PDF d'une page doit contenir
   la page entière, animations ou pas. */
@media print {
    .js-enabled .reveal,
    .js-enabled .block-width.reveal {
        opacity: 1 !important;
        transform: none !important;
    }

    .js-enabled .block-width.reveal {
        transform: translateX(-50%) !important;
    }
}

/* Les blocs « full » sortent du conteneur avec
   `left: 50%; transform: translateX(-50%)`. Le déplacement de l'apparition
   doit donc s'y ajouter, sinon il remplace le recentrage et le bloc part de
   50 % de l'écran vers la droite — ce qui provoque un défilement horizontal
   sur toute la page. */
.js-enabled .block-width.reveal {
    transform: translateX(-50%) translateY(28px);
}

.js-enabled .block-width.reveal.is-visible {
    transform: translateX(-50%);
}

/* Les enfants d'une grille se révèlent en cascade : chaque carte arrive un
   souffle après la précédente. Le décalage est plafonné à la cinquième,
   sinon une grille de vingt éléments finirait par se remplir trop lentement. */
.js-enabled .reveal.is-visible > .links-grid > li,
.js-enabled .reveal.is-visible > .tiles-grid > li,
.js-enabled .reveal.is-visible > .team-grid > li,
.js-enabled .reveal.is-visible .related-grid > a,
.js-enabled .reveal.is-visible > .stats-grid > li {
    animation: reveal-item .55s cubic-bezier(.22, .61, .36, 1) both;
}

.js-enabled .reveal.is-visible > :is(.links-grid, .tiles-grid, .team-grid, .stats-grid) > li:nth-child(2),
.js-enabled .reveal.is-visible .related-grid > a:nth-child(2) { animation-delay: .08s; }
.js-enabled .reveal.is-visible > :is(.links-grid, .tiles-grid, .team-grid, .stats-grid) > li:nth-child(3),
.js-enabled .reveal.is-visible .related-grid > a:nth-child(3) { animation-delay: .16s; }
.js-enabled .reveal.is-visible > :is(.links-grid, .tiles-grid, .team-grid, .stats-grid) > li:nth-child(4),
.js-enabled .reveal.is-visible .related-grid > a:nth-child(4) { animation-delay: .24s; }
.js-enabled .reveal.is-visible > :is(.links-grid, .tiles-grid, .team-grid, .stats-grid) > li:nth-child(n+5),
.js-enabled .reveal.is-visible .related-grid > a:nth-child(n+5) { animation-delay: .3s; }

@keyframes reveal-item {
    from {
        opacity: 0;
        transform: translateY(20px) scale(.98);
    }
    to {
        opacity: 1;
        transform: none;
    }
}

/* Cartes cliquables : un filet corail se déploie sur le bord haut au survol.
   C'est le signal qui manquait pour dire « cette carte est un lien » sans
   ajouter de texte. */
.links-item,
.news-item,
.documents-item a {
    position: relative;
}

.links-item::before,
.news-item::before,
.documents-item a::before {
    content: '';
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    height: 3px;
    border-radius: var(--site-radius) var(--site-radius) 0 0;
    background: var(--site-accent-vivid);
    transform: scaleX(0);
    transform-origin: left;
    transition: transform .35s cubic-bezier(.22, .61, .36, 1);
}

.links-item:hover::before,
.news-item:hover::before,
.documents-item a:hover::before {
    transform: scaleX(1);
}

/* La pastille d'icône prend la couleur d'accent au survol de sa carte : le
   changement se lit d'un coup d'œil, même en vision périphérique. */
.links-item-icon,
.documents-item svg {
    transition: background-color var(--site-transition), fill var(--site-transition), transform var(--site-transition);
}

.links-item:hover .links-item-icon,
.documents-item a:hover svg {
    background: var(--site-accent-vivid);
    fill: #fff;
    transform: rotate(-6deg) scale(1.06);
}

/* Pilules : le survol les passe au jaune pâle, comme les raccourcis de la
   maquette. */
.block-links.style-pills .links-item {
    transition: transform var(--site-transition), background-color var(--site-transition), border-color var(--site-transition);
}

.block-links.style-pills .links-item::before {
    display: none;
}

.block-links.style-pills .links-item:hover {
    background: var(--site-gold-bg);
    border-color: var(--site-gold);
    color: var(--site-text);
    transform: none;
    box-shadow: none;
}

.block-links.style-pills .links-item:hover .links-item-icon {
    background: none;
    fill: var(--site-accent);
    transform: none;
}

/* Compteurs animés (theme.js) : la valeur est comptée à partir de zéro quand
   le bloc entre dans le champ. `tabular-nums` est posé plus haut, ce qui
   évite que le chiffre gigote pendant le décompte. */
.stats-item-value[data-count-to] {
    display: inline-block;
    min-width: 1ch;
}

/* Images : léger agrandissement au survol pour le bloc « texte + images »,
   qui n'en avait pas. */
.block-text-images .block-text-images-media img {
    transition: transform .5s ease;
}

.block-text-images:hover .block-text-images-media img {
    transform: scale(1.03);
}
