/* ══════════════════════════════════════════════════════════════
   List Hero — Hero compact pour pages de listing (ressources, formations…)
   ══════════════════════════════════════════════════════════════ */

.list-hero {
    /* Stacking context dedie : sans cela, le dropdown `_rss_button` (menu
       absolute avec z-index: 50 dans le topbar) est rabattu sous les
       cards suivantes (ex: .article-card du listing /actualites) parce
       que le wrapper feed (z-index: 2 du root body) perd l'arbitrage
       d'ordre DOM contre tout ce qui suit. Position relative + z-index
       eleve elevent l'enveloppe hero au-dessus du contenu de liste. */
    position: relative;
    z-index: 10;
    /* Empilement 3 couches (la 1ere rendue PAR-DESSUS) : linear vertical
       force le blanc en bas (transition douce vers le contenu), linear
       horizontal force le blanc lateral (evite la "boite" centree), radial
       centre haut pour la teinte. Pas de margin-bottom : la couche
       verticale termine en blanc => continuite visuelle. */
    background-color: var(--color-bg);
    background-image:
        linear-gradient(
            180deg,
            transparent 0%,
            transparent 50%,
            var(--color-bg) 90%
        ),
        linear-gradient(
            90deg,
            var(--color-bg) 0%,
            transparent 25%,
            transparent 75%,
            var(--color-bg) 100%
        ),
        radial-gradient(
            ellipse 80% 140% at 50% 0%,
            color-mix(in srgb, var(--color-primary-light) 45%, var(--color-bg)) 0%,
            color-mix(in srgb, var(--color-primary-light) 18%, var(--color-bg)) 50%,
            var(--color-bg) 100%
        );
    padding: var(--spacing-xs) 0 var(--spacing-lg);
}

/* Breadcrumb integre dans le hero : fond transparent + padding compact.
   Le padding vertical est porte par `.list-hero__topbar` (parent) pour
   permettre l'alignement vertical exact des actions a droite (les deux
   enfants - breadcrumb et feed - partagent la meme baseline mediane). */
.list-hero .breadcrumb-bar {
    background: transparent;
    border: 0;
    margin-bottom: 0;
}

.list-hero .breadcrumb__list {
    padding: 0;
}

/* Topbar : breadcrumb a gauche + bouton flux (RSS dropdown) a droite.
   Le breadcrumb porte deja son propre `.container` interne ; on superpose
   un `.container` jumeau pour aligner le bouton sur la meme grille, puis
   on centre le feed verticalement via `top: 50%; translateY(-50%)`. Le
   padding vertical est sur le topbar parent (et plus sur le breadcrumb)
   pour que le milieu vertical = milieu de la ligne de texte breadcrumb. */
.list-hero__topbar {
    position: relative;
    padding: var(--spacing-sm) 0;
}

.list-hero__feed-wrapper {
    display: flex;
    justify-content: flex-end;
    align-items: center;
    position: absolute;
    top: 50%;
    left: 0;
    right: 0;
    z-index: 2;
    padding-top: 0;
    transform: translateY(-50%);
    pointer-events: none;
}

.list-hero__feed {
    pointer-events: auto;
    display: inline-flex;
    align-items: center;
    gap: var(--spacing-xs);
}

/* Sur mobile : le bouton repasse sous le breadcrumb pour eviter
   le chevauchement avec un breadcrumb qui wrappe sur plusieurs lignes. */
@media (max-width: 47.999em) {
    .list-hero__feed-wrapper {
        position: static;
        padding-top: 0;
        transform: none;
        margin-bottom: var(--spacing-sm);
    }
}

/* Bouton « Imprimer » du topbar — icone seule sans bordure ni fond.
   Cohabitation avec le bouton RSS via le meme slot `.list-hero__feed`.
   Label rendu en aria-label/title pour l'accessibilite uniquement. */
.list-hero__print {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 0.25rem;
    color: currentColor;
    background: none;
    border: 0;
    border-radius: var(--radius-sm);
    cursor: pointer;
    opacity: 0.7;
    transition: opacity 0.15s ease, color 0.15s ease;
}

.list-hero__print:hover,
.list-hero__print:focus-visible {
    opacity: 1;
    color: var(--color-primary);
    outline: none;
}

/* Share buttons en topbar : style discret aligne sur `.list-hero__print`,
   pas de cercles outline (qui surchargent visuellement la zone breadcrumb).
   Override du `.share-buttons__btn` global. */
.list-hero__share-buttons {
    gap: 0.125rem;
}

.list-hero__share-buttons .share-buttons__btn {
    width: auto;
    height: auto;
    padding: 0.35rem;
    border: 0;
    background: transparent;
    color: var(--color-text-light);
    border-radius: var(--radius-sm);
    opacity: 0.8;
    transition: opacity 0.15s ease, color 0.15s ease, background-color 0.15s ease;
}

.list-hero__share-buttons .share-buttons__btn:hover,
.list-hero__share-buttons .share-buttons__btn:focus-visible {
    opacity: 1;
    color: var(--color-primary);
    background: transparent;
    border-color: transparent;
}

/* Etat « Lien copie » : feedback discret en couleur primary, pas de fond. */
.list-hero__share-buttons .share-buttons__btn--active {
    opacity: 1;
    color: var(--color-primary);
    background: transparent;
    border-color: transparent;
}

/* Bookmark actif : meme rythme (couleur accent, pas de fond plein). */
.list-hero__share-buttons .share-buttons__btn--bookmark.share-buttons__btn--active {
    color: var(--color-accent);
    background: transparent;
    border-color: transparent;
}

.list-hero__share-buttons .share-buttons__btn--bookmark.share-buttons__btn--active:hover {
    background: transparent;
}

.list-hero__container {
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
    gap: var(--spacing-md);
    padding-top: var(--spacing-lg);
    width: 100%;
}

.list-hero__eyebrow {
    font-size: var(--font-size-xs);
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: var(--color-primary);
    margin: 0;
}

.list-hero__title {
    font-size: clamp(1.875rem, 4vw, 3rem);
    line-height: 1.1;
    font-weight: 700;
    color: var(--color-primary-dark);
    margin: 0;
    letter-spacing: -0.01em;
    max-width: 24ch;
}

.list-hero__lead {
    font-size: var(--font-size-lg);
    color: var(--color-text-light);
    line-height: 1.55;
    margin: 0;
    max-width: 52ch;
}

/* Wrapper title + lead : groupe semantique (le lead complete le titre,
   pas une section autonome). Espacement interne reduit a `--spacing-xs`,
   independant du `gap` parent `.list-hero__content`. Le wrapper se
   comporte lui-meme comme un flex item de `.list-hero__content` et
   herite donc du gap nominal entre lui et les voisins (eyebrow, tags,
   metrics, chips). */
.list-hero__head {
    display: flex;
    flex-direction: column;
    align-items: inherit;
    gap: var(--spacing-xs);
    width: 100%;
}

.list-hero__search {
    width: 100%;
    max-width: 36rem;
    /* L'espacement vertical est porte par le `gap` du `.list-hero__content`
       parent — pas de margin-top override ici, sinon il s'additionne au
       gap et casse l'harmonie avec les autres items (lead, metrics). */
}

/* ─── Tags / thematiques cliquables (rangee 1, juste sous le lead) ──
   Pills outline discretes en couleur primary, optimisees pour
   accueillir N thematiques avec wrap doux. Variante visuelle des
   chips meta (rangee 2), plus discrete, pour permettre une lecture
   rapide "domaine -> titre -> de quoi ca parle". */
.list-hero__tags {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-wrap: wrap;
    gap: 0.4rem;
    justify-content: center;
    max-width: 56rem;
}

.list-hero__tag {
    display: inline-flex;
    align-items: center;
    padding: 0.25rem 0.625rem;
    border-radius: 100px;
    border: 1px solid color-mix(in srgb, var(--color-primary) 28%, transparent);
    background: transparent;
    color: var(--color-primary-dark);
    font-size: var(--font-size-xs);
    font-weight: 500;
    line-height: 1.2;
    text-decoration: none;
    transition: background-color 0.15s ease, border-color 0.15s ease, color 0.15s ease;
}

a.list-hero__tag:hover,
a.list-hero__tag:focus-visible {
    background: color-mix(in srgb, var(--color-primary) 10%, #fff);
    border-color: var(--color-primary);
    outline: none;
}

/* En mode card editoriale, les tags s'alignent a gauche comme le
   reste du contenu. */
.list-hero--with-chips .list-hero__tags {
    justify-content: flex-start;
}

/* ─── Chips compactes sous les tags (rangee 2 meta) ────────────────
   Rangee de chips utilisee pour porter les metadonnees structurelles
   d'une fiche : duree, modalite, capacite, etc. Pills plus marques
   que les tags (fond plein primary 10%), avec icone optionnelle. */
.list-hero__chips {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-wrap: wrap;
    gap: 0.4rem;
    justify-content: center;
    max-width: 56rem;
}

/* En mode card editoriale, les chips s'alignent a gauche. */
.list-hero--with-chips .list-hero__chips {
    justify-content: flex-start;
}

.list-hero__chip {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    padding: 0.3125rem 0.625rem;
    border-radius: 100px;
    background: color-mix(in srgb, var(--color-primary) 10%, #fff);
    border: 1px solid color-mix(in srgb, var(--color-primary) 22%, transparent);
    color: var(--color-primary-dark);
    font-size: var(--font-size-xs);
    font-weight: 500;
    line-height: 1.2;
    text-decoration: none;
    transition: background-color 0.15s ease, border-color 0.15s ease, color 0.15s ease;
}

.list-hero__chip svg {
    flex-shrink: 0;
    opacity: 0.75;
}

.list-hero__chip--link:hover,
.list-hero__chip--link:focus-visible {
    background: color-mix(in srgb, var(--color-primary) 18%, #fff);
    border-color: var(--color-primary);
    color: var(--color-primary-dark);
    outline: none;
}

.list-hero__chip--accent {
    background: var(--color-primary);
    border-color: var(--color-primary);
    color: #fff;
}

.list-hero__chip--accent svg {
    opacity: 1;
}

.list-hero__chip--accent.list-hero__chip--link:hover,
.list-hero__chip--accent.list-hero__chip--link:focus-visible {
    background: var(--color-primary-dark);
    border-color: var(--color-primary-dark);
    color: #fff;
}

.list-hero__chip--ghost {
    background: transparent;
    border-color: color-mix(in srgb, var(--color-primary-dark) 22%, transparent);
    color: var(--color-primary-dark);
}

/* Variante "trust" : badges de certification / verification
   (Qualiopi, DPC, Simulation HAS, accessibilite). Plus poids visuel
   que la pill par defaut : fond vert tendre + icone teintee. Pattern
   "verified seal". */
.list-hero__chip--trust {
    padding: 0.45rem 0.85rem;
    font-size: var(--font-size-sm);
    font-weight: 600;
    background: color-mix(in srgb, #16a34a 12%, #fff);
    border-color: color-mix(in srgb, #16a34a 30%, transparent);
    color: #14532d;
}

.list-hero__chip--trust svg {
    opacity: 1;
    color: #16a34a;
}

.list-hero__chip--trust.list-hero__chip--link:hover,
.list-hero__chip--trust.list-hero__chip--link:focus-visible {
    background: #16a34a;
    border-color: #16a34a;
    color: #fff;
}

.list-hero__chip--trust.list-hero__chip--link:hover svg,
.list-hero__chip--trust.list-hero__chip--link:focus-visible svg {
    color: #fff;
}

.list-hero--background-image .list-hero__chip--trust {
    background: rgba(255, 255, 255, 0.95);
    border-color: rgba(255, 255, 255, 0.95);
    color: #14532d;
}

.list-hero--background-image .list-hero__chip--trust svg { color: #16a34a; }

/* Variante "action" : chips actionnables type call-to-action
   (telephone, site web, itineraire, reseaux sociaux). Padding plus
   genereux, icone plus marquee, hover prononce — pattern Google
   Business / LinkedIn org page. */
.list-hero__chip--action {
    padding: 0.45rem 0.85rem;
    font-size: var(--font-size-sm);
    font-weight: 600;
    background: #fff;
    border-color: color-mix(in srgb, var(--color-primary) 18%, transparent);
    color: var(--color-primary-dark);
}

.list-hero__chip--action svg {
    opacity: 1;
    color: var(--color-primary);
}

.list-hero__chip--action.list-hero__chip--link:hover,
.list-hero__chip--action.list-hero__chip--link:focus-visible {
    background: var(--color-primary);
    border-color: var(--color-primary);
    color: #fff;
}

.list-hero__chip--action.list-hero__chip--link:hover svg,
.list-hero__chip--action.list-hero__chip--link:focus-visible svg {
    color: #fff;
}

.list-hero--background-image .list-hero__chip--action {
    background: rgba(255, 255, 255, 0.95);
    border-color: rgba(255, 255, 255, 0.95);
    color: var(--color-primary-dark);
}

.list-hero--background-image .list-hero__chip--action svg {
    color: var(--color-primary);
}

.list-hero--background-image .list-hero__chip--action.list-hero__chip--link:hover,
.list-hero--background-image .list-hero__chip--action.list-hero__chip--link:focus-visible {
    background: var(--color-primary);
    border-color: var(--color-primary);
    color: #fff;
}

.list-hero--background-image .list-hero__chip--action.list-hero__chip--link:hover svg,
.list-hero--background-image .list-hero__chip--action.list-hero__chip--link:focus-visible svg {
    color: #fff;
}

/* ──────────────────────────────────────────────────────────
   Hero nav chips — bandeau de navigation integre en bas du
   hero card (pattern fiche profile : CESU, RESU, partner).
   Live INSIDE .list-hero, sous le contenu et l'aside, full width.
   Filet superieur subtil pour decoller du contenu hero.
   ────────────────────────────────────────────────────────── */
.list-hero__nav {
    margin-top: var(--spacing-md);
}

.list-hero__nav-list {
    list-style: none;
    margin: 0;
    padding: var(--spacing-sm) 0 0;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: center;
    gap: 4px;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
}

.list-hero__nav-sep {
    width: 1px;
    height: 1.25rem;
    background: color-mix(in srgb, var(--color-primary) 18%, transparent);
    margin: 0 var(--spacing-xs);
    flex-shrink: 0;
}

.list-hero__nav-chip {
    display: inline-flex;
    align-items: center;
    gap: var(--spacing-xs);
    padding: 6px 12px;
    border-radius: 999px;
    font-size: var(--font-size-sm);
    font-weight: 500;
    color: var(--color-text);
    text-decoration: none;
    white-space: nowrap;
    transition: background var(--transition-fast), color var(--transition-fast);
}

.list-hero__nav-chip-icon {
    flex-shrink: 0;
    color: var(--color-text-light);
    transition: color var(--transition-fast);
}

.list-hero__nav-chip-count {
    flex-shrink: 0;
    min-width: 1.25rem;
    padding: 1px 6px;
    background: color-mix(in srgb, var(--color-primary) 8%, #fff);
    border-radius: 999px;
    font-size: var(--font-size-xs);
    font-weight: 600;
    color: var(--color-text-light);
    text-align: center;
}

.list-hero__nav-chip:hover {
    background: color-mix(in srgb, var(--color-primary) 8%, #fff);
    color: var(--color-text);
}

.list-hero__nav-chip:hover .list-hero__nav-chip-icon { color: var(--color-primary); }

.list-hero__nav-chip--active {
    background: var(--color-primary);
    color: #fff;
    font-weight: 600;
}

.list-hero__nav-chip--active .list-hero__nav-chip-icon { color: #fff; }

.list-hero__nav-chip--active .list-hero__nav-chip-count {
    background: rgba(255, 255, 255, 0.22);
    color: #fff;
}

/* Variante hero avec background image : la nav devient blanche tendre. */
.list-hero--background-image .list-hero__nav-chip {
    color: #fff;
}

.list-hero--background-image .list-hero__nav-chip-icon { color: rgba(255, 255, 255, 0.7); }

.list-hero--background-image .list-hero__nav-chip:hover {
    background: rgba(255, 255, 255, 0.12);
}

.list-hero--background-image .list-hero__nav-chip:hover .list-hero__nav-chip-icon { color: #fff; }

.list-hero--background-image .list-hero__nav-chip--active {
    background: #fff;
    color: var(--color-primary-dark);
}

.list-hero--background-image .list-hero__nav-chip--active .list-hero__nav-chip-icon {
    color: var(--color-primary);
}

.list-hero--background-image .list-hero__nav-sep {
    background: rgba(255, 255, 255, 0.25);
}

/* Variante "hero" du search-field : plus grande, plus contrastee.
   Radius `--radius-lg` aligne avec la card editoriale parente (zero
   pill complet) — coherent avec le rythme visuel du hero. */
.search-field--hero .search-field__group {
    border: 1px solid color-mix(in srgb, var(--color-primary) 18%, transparent);
    border-radius: var(--radius-lg);
    box-shadow: 0 4px 18px color-mix(in srgb, var(--color-primary) 12%, transparent);
    background: #fff;
}

.search-field--hero .search-field__group:focus-within {
    border-color: var(--color-primary);
    box-shadow: 0 6px 22px color-mix(in srgb, var(--color-primary) 22%, transparent);
}

.search-field--hero .search-field__input {
    padding: 0.85rem var(--spacing-lg) 0.85rem calc(var(--spacing-lg) + 1.5rem);
    font-size: var(--font-size-base);
    border-radius: var(--radius-lg);
}

.search-field--hero .search-field__icon {
    left: var(--spacing-lg);
}

/* Submit visible : bouton integre a droite du champ, fond primary, blanc.
   Meme radius `--radius-lg` que le groupe parent — coherence stricte
   d'arrondi sur l'ensemble du champ recherche et la card editoriale. */
.search-field--hero .search-field__submit.btn {
    position: relative;
    margin: 0.25rem;
    margin-left: -2.5rem;
    padding: 0.6rem 1.25rem;
    border: 0;
    border-radius: var(--radius-lg);
    background: var(--color-primary);
    color: #fff;
    font-size: var(--font-size-sm);
    font-weight: 600;
    line-height: 1;
    cursor: pointer;
    font-family: inherit;
    transition: background-color 0.15s ease;
    z-index: 1;
}

.search-field--hero .search-field__submit.btn:hover,
.search-field--hero .search-field__submit.btn:focus-visible {
    background: var(--color-primary-dark);
    outline: none;
}

/* Quand un submit est present, on ajoute du padding-right a l'input
   pour eviter que le texte saisi passe sous le bouton. */
.search-field--hero:has(.search-field__submit) .search-field__input {
    padding-right: 7rem;
}

@media (max-width: 47.999em) {
    .list-hero {
        padding-bottom: var(--spacing-xl);
        margin-bottom: var(--spacing-lg);
    }
    .list-hero__container {
        padding-top: var(--spacing-md);
        gap: var(--spacing-sm);
    }
    .search-field--hero .search-field__input {
        padding-block: 0.65rem;
        /* Mobile : pas de loupe a gauche (redondante avec le bouton
           submit a droite qui est aussi une loupe). On retire le
           padding-left dedie a l'icone pour gagner de la place. */
        padding-left: var(--spacing-md);
    }
    .search-field--hero .search-field__icon {
        display: none;
    }
    /* Mobile : bouton submit en icone-only (loupe blanche sur fond
       primary). Le label "Rechercher" est cache visuellement via
       `font-size: 0`, le content text reste expose pour les screen
       readers. L'icone est rendue via `mask-image` (SVG inline)
       pour heriter de la couleur blanche. */
    .search-field--hero .search-field__submit.btn {
        font-size: 0;
        padding: 0;
        width: 2.5rem;
        height: 2.5rem;
        margin: 0.25rem 0.25rem 0.25rem -2.75rem;
        flex-shrink: 0;
        position: relative;
    }
    .search-field--hero .search-field__submit.btn::before {
        content: "";
        position: absolute;
        inset: 0;
        background-color: #fff;
        -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='11' cy='11' r='8'/%3E%3Cline x1='21' y1='21' x2='16.65' y2='16.65'/%3E%3C/svg%3E") center / 18px no-repeat;
                mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='11' cy='11' r='8'/%3E%3Cline x1='21' y1='21' x2='16.65' y2='16.65'/%3E%3C/svg%3E") center / 18px no-repeat;
    }
    .search-field--hero:has(.search-field__submit) .search-field__input {
        padding-right: 3.5rem;
    }
}

/* ══════════════════════════════════════════════════════════════
   Variante hero split — visuel en card a droite, body editorial
   integre a gauche
   ══════════════════════════════════════════════════════════════
   Activee par `aside_image_hash_id` et/ou `lead_body` sur
   `_list_hero.html.twig`. Sur >= 64em, le `.list-hero__container`
   passe en flex row (texte | visuel), texte aligne a gauche. Sur
   mobile, le visuel passe sous le texte en pleine largeur.
   `.list-hero__body` rend le TipTap directement dans la colonne
   gauche pour les pages categorie/taxonomie (ex: /formations/domaines/*).
   ══════════════════════════════════════════════════════════════ */

.list-hero__content {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--spacing-md);
    width: 100%;
}

.list-hero__aside {
    position: relative;
    width: 100%;
    margin-top: var(--spacing-md);
}

.list-hero__aside-image {
    display: block;
    width: 100%;
    aspect-ratio: 16 / 10;
    object-fit: cover;
    border-radius: var(--radius-lg);
    box-shadow: 0 12px 32px rgba(15, 23, 42, 0.16);
}

/* ─── Nuage de thematiques (aside hero alternatif) ──────────────────
   Cloud "badges discrets" : chaque thematique en pastille tres
   legere (fond primary 6%, sans bordure, texte muted), taille de
   police modeste (11→16px) et poids regulier (400 partout, sauf
   le top bucket en 500 pour signaler la frequence). Le rendu reste
   un nuage (gap serre, flex-wrap) mais en mode "etagere de tags"
   plutot qu'en composition typographique massive.
   Pattern signe-faible-couplage : le rendu ne suppose rien sur la
   source des tags (thematiques training, mais reutilisable pour
   library/event si besoin futur). */
.thematique-cloud {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: center;
    gap: 0.35rem 0.4rem;
    line-height: 1.15;
}

.thematique-cloud__item {
    margin: 0;
    display: inline-flex;
}

/* Badge discret : fond primary tres pale (~6%), pas de bordure
   (purete visuelle), padding modere. Le texte reste en muted
   par defaut, ne passe en primary qu'au hover. */
.thematique-tag {
    display: inline-block;
    padding: 0.2em 0.65em;
    border-radius: 999px;
    background: color-mix(in srgb, var(--color-primary) 7%, transparent);
    color: color-mix(in srgb, var(--color-primary) 55%, var(--color-text));
    text-decoration: none;
    line-height: 1.4;
    letter-spacing: 0;
    transition: background-color 0.15s ease, color 0.15s ease;
}

.thematique-tag:hover,
.thematique-tag:focus-visible {
    background: color-mix(in srgb, var(--color-primary) 18%, transparent);
    color: var(--color-primary-dark, var(--color-primary));
    outline: none;
}

/* Echelle 5 buckets — variation modeste sur la taille uniquement
   (11→16px). Le poids reste 400 sur tous les buckets sauf w5 en
   500 pour signaler la frequence sans alourdir la composition.
   Couleurs alignees sur le pattern badge : tous les buckets gardent
   le meme `color`/`background` (defini sur `.thematique-tag`), seule
   la typo varie. */
.thematique-tag--w1 { font-size: 0.7rem;   font-weight: 400; }   /* ~11.2px */
.thematique-tag--w2 { font-size: 0.78rem;  font-weight: 400; }   /* ~12.5px */
.thematique-tag--w3 { font-size: 0.85rem;  font-weight: 400; }   /* ~13.5px */
.thematique-tag--w4 { font-size: 0.93rem;  font-weight: 400; }   /* ~14.8px */
.thematique-tag--w5 { font-size: 1rem;     font-weight: 500; }   /* 16px */

/* Override `align-self: stretch` du parent — voir bloc media query
   `@media (min-width: 64em)` plus bas. Declaree apres cette regle pour
   que la cascade donne raison a `center` a specificite egale. */

/* Body TipTap integre au hero — typo compacte, lisible, en
   continuite avec `.list-hero__lead`. */
.list-hero__body {
    color: var(--color-text);
    font-size: var(--font-size-md);
    line-height: var(--line-height-base);
    max-width: 62ch;
}

.list-hero__body > * + * {
    margin-top: var(--spacing-md);
}

.list-hero__body p {
    margin: 0;
}

.list-hero__body ul,
.list-hero__body ol {
    margin: 0;
    padding-left: 1.25rem;
}

.list-hero__body li + li {
    margin-top: 0.2rem;
}

.list-hero__body h2,
.list-hero__body h3 {
    color: var(--color-primary-dark);
    font-weight: 700;
    font-size: var(--font-size-base);
    line-height: 1.3;
    margin-top: var(--spacing-md);
}

.list-hero__body a {
    color: var(--color-primary);
    text-decoration: underline;
    text-underline-offset: 0.15em;
}

/* En mode split editorial, le `.list-hero__container` devient une card
   centree avec fond bleute subtil, pas de bordure, padding genereux.
   Pattern inspire Branfere : zone editoriale clairement delimitee, sans
   crier visuellement. Le `.container` parent gere les gutters externes.
   Active aussi quand seules les `metrics` sont presentes (page index
   catalogue Training en attente d'une image admin). */
.list-hero--with-aside .list-hero__container,
.list-hero--with-body .list-hero__container,
.list-hero--with-metrics .list-hero__container,
.list-hero--with-chips .list-hero__container,
.list-hero--article .list-hero__container,
.list-hero--page .list-hero__container {
    background: color-mix(in srgb, var(--color-primary) 4%, var(--color-bg));
    border-radius: var(--radius-lg);
    padding: var(--spacing-xl);
    margin-top: var(--spacing-md);
    margin-bottom: var(--spacing-xl);
    text-align: left;
    align-items: flex-start;
    gap: var(--spacing-md);
}

.list-hero--with-aside .list-hero__container .list-hero__title,
.list-hero--with-body .list-hero__container .list-hero__title,
.list-hero--with-metrics .list-hero__container .list-hero__title,
.list-hero--with-chips .list-hero__container .list-hero__title,
.list-hero--article .list-hero__container .list-hero__title,
.list-hero--page .list-hero__container .list-hero__title {
    text-align: left;
}

.list-hero--with-aside .list-hero__content,
.list-hero--with-body .list-hero__content,
.list-hero--with-metrics .list-hero__content,
.list-hero--with-chips .list-hero__content,
.list-hero--article .list-hero__content,
.list-hero--page .list-hero__content {
    align-items: flex-start;
    text-align: left;
    /* Espacement vertical uniforme entre tous les items du content
       (eyebrow, title, lead, body, metrics, search) dans la card
       editoriale — donne plus d'air que le `spacing-md` du mode hero
       centre standard, coherent avec le padding `spacing-2xl` de la
       card au breakpoint desktop. */
    gap: var(--spacing-lg);
}

/* Metriques rapides (formations, sessions a venir, CESUs proposants…)
   rendues sous le body TipTap dans la card editoriale. Pattern Branfere :
   chiffre tres gros navy sobre + label majuscule serre dessous +
   separateurs verticaux entre items. Semantique HTML conservee
   (<dt> label puis <dd> value), ordre visuel inverse via
   `flex-direction: column-reverse`. */
.list-hero__metrics {
    display: flex;
    flex-wrap: wrap;
    gap: var(--spacing-md) 0;
    /* Pas de `margin-top` ici : l'espacement avec l'item precedent (lead /
       body) est porte par le `gap` du `.list-hero__content` parent. Un
       margin-top s'ajouterait au gap et casserait l'harmonie verticale. */
    margin: 0;
    padding: 0;
}

.list-hero__metric {
    display: flex;
    flex-direction: column-reverse;
    gap: 0.4rem;
    padding: 0 var(--spacing-lg);
    border-left: 1px solid var(--color-border);
    min-width: 7rem;
}

.list-hero__metric:first-child {
    padding-left: 0;
    border-left: 0;
}

.list-hero__metric-value {
    margin: 0;
    font-size: clamp(2rem, 4vw, 2.75rem);
    font-weight: 700;
    line-height: 1;
    letter-spacing: -0.02em;
    color: var(--color-primary-dark);
}

/* Variante compacte : pour les fiches qui portent un mix chiffre + texte
   ("Présentiel", "Hybride", "12 personnes"). Le clamp standard
   (2-2.75rem) ferait sortir un mot long du cadre — on reduit la value
   et on serre le padding lateral pour densifier la rangee. */
.list-hero__metrics--compact .list-hero__metric {
    padding: 0 var(--spacing-md);
    min-width: 6rem;
}

.list-hero__metrics--compact .list-hero__metric-value {
    font-size: clamp(1.125rem, 1.6vw, 1.375rem);
    letter-spacing: -0.01em;
}

.list-hero__metrics--compact .list-hero__metric-label {
    font-size: 0.65rem;
    letter-spacing: 0.06em;
}

/* Mobile : abandonne le layout "chiffre saillant + label dessous"
   (les labels se chevauchent sur 375px meme avec font reduite). On
   bascule en format inline "[chiffre] [label]" sur une ligne, items
   separes par un point mediant. Pattern naturel en mobile, occupe
   moins de hauteur verticale et evite tout wrap. */
@media (max-width: 47.999em) {
    .list-hero__metrics {
        gap: 0;
        flex-direction: row;
        flex-wrap: wrap;
        align-items: baseline;
    }
    .list-hero__metric {
        flex-direction: row-reverse;
        align-items: baseline;
        gap: 0.35rem;
        padding: 0 var(--spacing-sm);
        border-left: 0;
        min-width: 0;
        flex: 0 0 auto;
    }
    .list-hero__metric:first-child {
        padding-left: 0;
    }
    .list-hero__metric:not(:first-child)::before {
        content: "·";
        margin-right: var(--spacing-sm);
        color: var(--color-border);
        font-weight: 700;
    }
    .list-hero__metric-value {
        font-size: 1rem;
        font-weight: 700;
    }
    .list-hero__metric-label {
        font-size: 0.85rem;
        text-transform: none;
        letter-spacing: 0;
        font-weight: 400;
        color: var(--color-text-light);
        white-space: nowrap;
    }
}

.list-hero__metric-label {
    margin: 0;
    font-size: var(--font-size-xs);
    text-transform: uppercase;
    letter-spacing: 0.04em;
    font-weight: 600;
    line-height: 1.3;
    color: var(--color-text-light);
}

/* Eyebrow en pill navy/blanc — dynamise le coin haut de la card editoriale
   sans crier (zero bordure, radius mediums). */
.list-hero--with-aside .list-hero__eyebrow,
.list-hero--with-body .list-hero__eyebrow,
.list-hero--with-metrics .list-hero__eyebrow,
.list-hero--with-chips .list-hero__eyebrow,
.list-hero--article .list-hero__eyebrow,
.list-hero--page .list-hero__eyebrow {
    display: inline-block;
    align-self: flex-start;
    margin: 0 0 calc(var(--spacing-md) * -0.7) 0;
    padding: 0.35rem 0.75rem;
    background: var(--color-primary);
    color: #fff;
    border-radius: var(--radius-md);
    font-size: 0.7rem;
    line-height: 1.1;
}

@media (min-width: 64em) {
    /* Padding genereux dans la card editoriale (avec ou sans aside). */
    .list-hero--with-aside .list-hero__container,
    .list-hero--with-body .list-hero__container,
    .list-hero--with-metrics .list-hero__container,
    .list-hero--with-chips .list-hero__container,
    .list-hero--article .list-hero__container,
    .list-hero--page .list-hero__container {
        padding: var(--spacing-2xl);
    }
    /* Split horizontal — uniquement quand une aside (photo) est presente.
       Modifier `--aside-left` inverse l'ordre visuel (photo a gauche) sans
       toucher au DOM : le markup reste content puis aside, le rendu reste
       accessible (lecture lineaire conservee), seul l'axe principal flex
       est inverse. */
    .list-hero--with-aside .list-hero__container {
        flex-direction: row;
        align-items: stretch;
        justify-content: space-between;
        gap: var(--spacing-2xl);
    }
    .list-hero--with-aside.list-hero--aside-left .list-hero__container {
        flex-direction: row-reverse;
    }
    .list-hero--with-aside .list-hero__content {
        flex: 1 1 auto;
        max-width: 44rem;
    }
    .list-hero--with-aside .list-hero__title,
    .list-hero--with-body .list-hero__title,
    .list-hero--with-aside .list-hero__lead,
    .list-hero--with-body .list-hero__lead {
        max-width: none;
    }
    /* Body sans aside : reste en flex column, contenu plus large pour
       remplir la card (pas de colonne photo a droite). */
    .list-hero--with-body:not(.list-hero--with-aside) .list-hero__content {
        max-width: 60rem;
    }
    .list-hero--with-aside .list-hero__aside {
        position: relative;
        flex: 0 0 26rem;
        max-width: 26rem;
        margin-top: 0;
        align-self: stretch;
    }
    /* Image absolue : ne contribue plus a la hauteur du parent, c'est
       donc le content (colonne texte) qui dicte la hauteur de la card.
       Si l'image a un ratio plus haut que le content, elle est cropp.e
       proprement par `object-fit: cover` au lieu d'allonger la card. */
    .list-hero--with-aside .list-hero__aside-image {
        position: absolute;
        inset: 0;
        width: 100%;
        height: 100%;
        aspect-ratio: auto;
    }
    /* Override pour le mode nuage : pas de stretch (qui plaque le nuage
       sur la hauteur totale et fait remonter le contenu en haut), mais
       centrage vertical dans la card pour une composition equilibree.
       Declaree apres le `stretch` pour gagner la cascade a specificite
       egale (2 classes). */
    .list-hero--with-aside .list-hero__aside--cloud {
        align-self: center;
    }
}

/* ══════════════════════════════════════════════════════════════
   Variante hero card avec image de fond plein cadre
   ══════════════════════════════════════════════════════════════
   Activee par `background_image_hash_id` sur `_list_hero.html.twig`.
   La vignette DAM occupe toute la card, sous un overlay sombre qui
   garantit le contraste AA des titres et metriques. Le texte passe
   en blanc, les chips/tags en outline blanc, l'eyebrow en pill
   inverse (fond clair + texte navy).
   ══════════════════════════════════════════════════════════════ */

.list-hero--background-image .list-hero__container {
    position: relative;
    overflow: hidden;
    isolation: isolate; /* contient les z-index dans la card */
    background: var(--color-primary-dark);
    color: #fff;
    min-height: 18rem;
}

.list-hero__background-image {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    z-index: 0;
    border-radius: inherit;
}

/* Overlay : gradient sombre du haut vers le bas, garantit le contraste
   du titre (zone haute) et reste lisible jusqu'aux metrics (zone basse). */
.list-hero--background-image .list-hero__container::after {
    content: '';
    position: absolute;
    inset: 0;
    background:
        linear-gradient(180deg,
            color-mix(in srgb, var(--color-primary-dark) 72%, transparent) 0%,
            color-mix(in srgb, var(--color-primary-dark) 84%, transparent) 100%);
    z-index: 1;
    border-radius: inherit;
}

.list-hero--background-image .list-hero__content {
    position: relative;
    z-index: 2;
}

/* Texte editorial en blanc — titre, lead, body herite. */
.list-hero--background-image .list-hero__title,
.list-hero--background-image .list-hero__lead {
    color: #fff;
}

.list-hero--background-image .list-hero__body,
.list-hero--background-image .list-hero__body * {
    color: rgba(255, 255, 255, 0.9);
}

/* Eyebrow : inverse de l'etat normal — fond clair, texte navy. */
.list-hero--background-image .list-hero__eyebrow {
    background: #fff;
    color: var(--color-primary-dark);
}

/* Tags outline blanc translucide. */
.list-hero--background-image .list-hero__tag {
    border-color: rgba(255, 255, 255, 0.55);
    color: #fff;
    background: rgba(255, 255, 255, 0.08);
}

.list-hero--background-image a.list-hero__tag:hover,
.list-hero--background-image a.list-hero__tag:focus-visible {
    background: rgba(255, 255, 255, 0.18);
    border-color: #fff;
    color: #fff;
}

/* Metriques : value blanc saillant, label clair, separateur clair. */
.list-hero--background-image .list-hero__metric-value,
.list-hero--background-image .list-hero__metric-label {
    color: #fff;
}

.list-hero--background-image .list-hero__metric-label {
    color: rgba(255, 255, 255, 0.85);
}

.list-hero--background-image .list-hero__metric {
    border-left-color: rgba(255, 255, 255, 0.35);
}

/* Chips conservent leur fond couleur primary par defaut, mais on
   adoucit les variantes par defaut pour qu'elles soient lisibles
   sur fond sombre. */
.list-hero--background-image .list-hero__chip {
    background: rgba(255, 255, 255, 0.12);
    border-color: rgba(255, 255, 255, 0.45);
    color: #fff;
}

/* Note : le topbar (breadcrumb + actions share/print/bookmark / RSS)
   conserve volontairement sa position par defaut AU-DESSUS de la
   card hero, sur le gradient navy clair de l'enveloppe `.list-hero`,
   meme quand l'image de fond couvre la card. Pattern aligne sur le
   listing /actualites : la zone breadcrumb + actions reste visuellement
   separee du visuel editorial pour preserver la lisibilite et eviter
   de chevaucher le titre. Pas d'override --background-image sur le
   topbar : laisser le pattern par defaut faire son travail. */

.list-hero--background-image .list-hero__chip svg {
    opacity: 0.95;
}

.list-hero--background-image .list-hero__chip--accent {
    background: #fff;
    border-color: #fff;
    color: var(--color-primary-dark);
}

/* ── Modifier `dossier` : card hero arrondie alignee sur la fiche formation
   (`list-hero--training`). Contrairement a la formation qui porte toujours
   des metriques (`--with-metrics` => mode card editoriale), un dossier peut
   n'avoir ni metrique ni thematique. On force donc le mode card (aligne a
   gauche + eyebrow pastille + padding genereux) directement sur le modifier,
   sans dependre de `--with-chips` / `--with-metrics` qui ne s'activent que
   quand la donnee correspondante est presente. ── */
.list-hero--dossier .list-hero__container {
    border-radius: 1.5rem;
}

/* Enveloppe neutre : on retire le degrade navy clair du `.list-hero` partage
   (qui se lit comme une bande grise derriere le breadcrumb), comme la fiche
   formation le fait sur ses modes card. */
.list-hero--dossier {
    background-image: none;
    background-color: var(--color-bg);
}

/* Contenu / titre alignes a gauche meme sans thematiques (override du
   centrage par defaut de `.list-hero__content` / `.list-hero__container`). */
.list-hero--dossier .list-hero__content {
    align-items: flex-start;
    text-align: left;
    gap: var(--spacing-lg);
}

.list-hero--dossier .list-hero__container .list-hero__title {
    text-align: left;
}

/* Eyebrow en pastille verte ANCESU (fond vert, texte blanc) — coherent avec
   la couleur de section « dossier » et lisible sur le cover sombre. Override
   du fond navy generique (`--with-chips`) et du fond blanc `--background-image`. */
.list-hero--dossier .list-hero__eyebrow {
    display: inline-block;
    align-self: flex-start;
    margin: 0 0 calc(var(--spacing-md) * -0.7) 0;
    padding: 0.35rem 0.75rem;
    background: var(--color-section-ancesu);
    color: #fff;
    border-radius: var(--radius-md);
    font-size: 0.7rem;
    line-height: 1.1;
}

/* Padding genereux dans la card editoriale au breakpoint desktop, comme les
   autres modes card (`--with-chips` / `--with-metrics`). */
@media (min-width: 64em) {
    .list-hero--dossier .list-hero__container {
        padding: var(--spacing-2xl);
    }
}

/* Ligne meta (date de mise a jour) sous le titre/chapo. Texte discret,
   passe en blanc translucide sur le cover sombre. */
.list-hero__meta {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--spacing-md);
    margin: 0;
    font-size: var(--font-size-sm);
    color: var(--color-text-light);
}

.list-hero__meta-item {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
}

.list-hero--background-image .list-hero__meta {
    color: rgba(255, 255, 255, 0.85);
}

/* ══════════════════════════════════════════════════════════════
   Content List — Page de liste générique CMS
   ══════════════════════════════════════════════════════════════ */

.content-list {
    padding: var(--spacing-xl) 0 var(--spacing-3xl);
    /* Offset pour les scroll-anchors (ex: `#catalogue` cible la liste
       paginee depuis le CTA hero) — evite que la section soit masquee
       par la navbar scrolled sticky en haut. */
    scroll-margin-top: calc(var(--header-height) + var(--spacing-md));
}

/* Quand un hero ou un strip de cards precede la page liste, on
   neutralise le padding-top — sinon le `margin-bottom: spacing-xl`
   du strip (cf. zones/trainings.css `.hero-cards-strip`) s'additionne
   au `padding-top: spacing-xl` de la `.content-list` et cree un gros
   espace blanc visible entre les cards et la liste. */
.list-hero + .content-list,
.hero-cards-strip + .content-list {
    padding-top: 0;
}

/* Header */
.content-list__header {
    display: flex;
    align-items: flex-end;
    justify-content: space-between;
    gap: var(--spacing-md);
    margin-bottom: var(--spacing-xl);
    padding-bottom: var(--spacing-lg);
    border-bottom: 1px solid var(--color-border);
}

.content-list__title {
    font-size: var(--font-size-2xl);
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--color-text);
    margin: 0;
}

@media (min-width: 640px) {
    .content-list__title {
        font-size: var(--font-size-3xl);
    }
}

.content-list__subtitle {
    margin-top: var(--spacing-xs);
    font-size: var(--font-size-base);
    color: var(--color-text-light);
}

/* Briques design-system : list_header (composant) */
.content-list__header-top {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: var(--spacing-md);
}

.content-list__header-actions {
    margin-left: auto;
    display: flex;
    flex-wrap: wrap;
    gap: var(--spacing-sm);
}

.list-filters__bar {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--spacing-md);
    margin-bottom: var(--spacing-md);
}

.list-filters__bar .search-field {
    flex: 1 1 18rem;
    min-width: 0;
}

.list-filters__count {
    font-size: var(--font-size-sm);
    color: var(--color-text-light);
    flex-shrink: 0;
}

.list-filters__extra {
    flex-shrink: 0;
    display: flex;
    gap: var(--spacing-sm);
}

.content-list__count {
    margin: 0;
    font-size: var(--font-size-sm);
    color: var(--color-text-light);
    line-height: 1.4;
}

.content-list__count strong {
    color: var(--color-primary-dark);
    font-size: var(--font-size-base);
    font-weight: 700;
    margin-right: 0.25rem;
}

/* Layout 2 colonnes desktop */
.content-list__layout {
    display: flex;
    flex-direction: column;
    gap: var(--spacing-lg);
}

@media (min-width: 1024px) {
    .content-list__layout {
        flex-direction: row;
        gap: var(--spacing-2xl);
    }
}

/* Sidebar filtres (desktop) */
.content-list__sidebar {
    display: none;
}

@media (min-width: 1024px) {
    .content-list__sidebar {
        display: flex;
        flex-direction: column;
        flex-shrink: 0;
        width: 17.5rem;
        position: sticky;
        top: 5rem;
        align-self: flex-start;
        max-height: calc(100vh - 6rem);
        overflow-y: auto;
        /* `overflow-x: hidden` evite que le contenu de 17.5rem deborde
           hors du cadre pendant la transition de width vers 2.5rem.
           Le panel `_facet_multiselect` passe en `position: fixed`
           (coords JS), donc cet overflow ne le clippe pas. */
        overflow-x: hidden;
        /* Easing Material « emphasized » pour une expansion plus
           gracieuse qu'un linear/ease basique. */
        transition: width 320ms cubic-bezier(0.4, 0, 0.2, 1);
        /* Scrollbar discrete cross-browser. */
        scrollbar-width: thin;
        scrollbar-color: color-mix(in srgb, var(--color-text-light) 35%, transparent) transparent;
    }

    .content-list__sidebar::-webkit-scrollbar {
        width: 6px;
        height: 6px;
    }

    .content-list__sidebar::-webkit-scrollbar-track {
        background: transparent;
    }

    .content-list__sidebar::-webkit-scrollbar-thumb {
        background: color-mix(in srgb, var(--color-text-light) 35%, transparent);
        border-radius: 999px;
    }

    .content-list__sidebar::-webkit-scrollbar-thumb:hover {
        background: color-mix(in srgb, var(--color-text-light) 55%, transparent);
    }

    /* Repliée — width reduit a la taille de la card toggle (icone +
       libelle vertical « Filtres »). */
    .content-list__sidebar[data-collapsed="true"] {
        width: 2.5rem;
        overflow: hidden;
    }
}

/* Contenu principal */
.content-list__main {
    flex: 1;
    min-width: 0;
}

/* Toolbar (compteur + tri + chips + toggle filtres)
   Deux rangees verticales :
     - Rangee 1 : compteur a gauche + tri/filtre a droite.
     - Rangee 2 : chips pleine largeur (wrap si nombreux).
   Pas de border-bottom — l'enchainement avec la liste se fait par
   le margin-bottom standard, sans separateur visible. */
.content-list__toolbar {
    display: flex;
    flex-direction: column;
    gap: var(--spacing-sm);
    margin-bottom: var(--spacing-md);
}

.content-list__toolbar-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--spacing-md);
    min-height: 1.75rem;
}

.content-list__toolbar-left {
    display: flex;
    align-items: center;
    gap: var(--spacing-xs);
    min-width: 0;
    flex: 1;
}

/* Conteneur des chips — pleine largeur sous la rangee compteur/tri. */
.content-list__toolbar-chips {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--spacing-xs);
}

.content-list__header-right {
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    gap: var(--spacing-xs);
    flex-shrink: 0;
}

/* .content-list__rss supprime — bouton RSS vit desormais dans
   components/rss-button.css (brique design-system, dropdown 3 formats). */

.content-list__toolbar-right {
    display: flex;
    align-items: center;
    gap: var(--spacing-sm);
    flex-shrink: 0;
}

.content-list__filter-toggle {
    display: flex;
    align-items: center;
    gap: var(--spacing-xs);
    padding: var(--spacing-sm) var(--spacing-md);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-sm);
    font-size: var(--font-size-sm);
    font-weight: 500;
    background: #fff;
    cursor: pointer;
    white-space: nowrap;
    margin-left: auto;
    transition: border-color 0.15s ease, color 0.15s ease;
}

.content-list__filter-toggle:hover {
    border-color: var(--color-primary);
    color: var(--color-primary);
}

@media (min-width: 1024px) {
    .content-list__filter-toggle {
        display: none;
    }
}

.content-list__filter-badge {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 1.25rem;
    height: 1.25rem;
    padding: 0 0.3rem;
    border-radius: 100px;
    font-size: 0.6875rem;
    font-weight: 700;
    line-height: 1;
    background: var(--color-primary);
    color: #fff;
}

/* Grille de cards */
.content-list__grid {
    display: grid;
    grid-template-columns: 1fr;
    gap: var(--spacing-lg);
}

@media (min-width: 640px) {
    .content-list__grid {
        grid-template-columns: repeat(2, 1fr);
    }
}

.content-list__rows {
    display: flex;
    flex-direction: column;
    /* Pas de border-top : la toolbar n'a plus de border-bottom (cf. content-list__toolbar),
       et les cards portent leur propre cadre. Un trait orphelin entre les deux est du
       bruit visuel sans valeur d'enchainement. */
}

/* Header de section quand la liste est regroupee (Twig insere un <h2> au
   changement de groupValue dans la boucle items). Visuellement discret
   pour rester un repere de navigation, pas un titre rivalisant avec le
   hero. */
.content-list__group-header {
    margin: var(--spacing-md) 0 var(--spacing-2xs);
    padding-bottom: var(--spacing-2xs);
    font-size: 0.875rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--color-text-light);
    border-bottom: 1px solid var(--color-border);
}

/* Premier header collé au top, sans la marge supérieure standard. */
.content-list__rows > .content-list__group-header:first-child {
    margin-top: 0;
}

/* État vide */
.content-list__empty {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--spacing-md);
    padding: var(--spacing-3xl) var(--spacing-md);
    color: var(--color-text-light);
    text-align: center;
}

.content-list__empty svg {
    opacity: 0.4;
}

/* ══════════════════════════════════════════════════════════════
   Featured Card — Premier article mis en avant
   ══════════════════════════════════════════════════════════════ */

.content-card-featured {
    margin-bottom: var(--spacing-xl);
    border-radius: var(--radius-md);
    overflow: hidden;
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.06);
    transition: box-shadow 0.2s ease;
}

.content-card-featured:hover {
    box-shadow: 0 6px 24px rgba(0, 0, 0, 0.1);
}

.content-card-featured__link {
    display: flex;
    flex-direction: column;
    text-decoration: none;
    color: inherit;
}

@media (min-width: 640px) {
    .content-card-featured__link {
        flex-direction: row;
    }
}

.content-card-featured__image {
    position: relative;
    aspect-ratio: 16 / 9;
    overflow: hidden;
    background: var(--color-bg-light);
}

@media (min-width: 640px) {
    .content-card-featured__image {
        width: 55%;
        flex-shrink: 0;
        aspect-ratio: auto;
        min-height: 16rem;
    }
}

.content-card-featured__image img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    transition: transform 0.3s ease;
}

.content-card-featured:hover .content-card-featured__image img {
    transform: scale(1.03);
}

.content-card-featured__body {
    display: flex;
    flex-direction: column;
    justify-content: center;
    padding: var(--spacing-lg);
    background: #fff;
}

@media (min-width: 640px) {
    .content-card-featured__body {
        padding: var(--spacing-xl);
        flex: 1;
    }
}

.content-card-featured__title {
    font-size: var(--font-size-xl);
    font-weight: 700;
    line-height: var(--line-height-tight);
    color: var(--color-text);
    margin: var(--spacing-sm) 0;
    display: -webkit-box;
    -webkit-line-clamp: 3;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

@media (min-width: 640px) {
    .content-card-featured__title {
        font-size: var(--font-size-2xl);
    }
}

.content-card-featured__excerpt {
    font-size: var(--font-size-sm);
    color: var(--color-text-light);
    line-height: var(--line-height-base);
    display: -webkit-box;
    -webkit-line-clamp: 3;
    -webkit-box-orient: vertical;
    overflow: hidden;
    margin: 0;
}

.content-card-featured__cta {
    display: inline-flex;
    align-items: center;
    gap: var(--spacing-xs);
    margin-top: var(--spacing-md);
    font-size: var(--font-size-sm);
    font-weight: 600;
    color: var(--color-primary);
    transition: gap 0.2s ease;
}

.content-card-featured:hover .content-card-featured__cta {
    gap: var(--spacing-sm);
}

/* ══════════════════════════════════════════════════════════════
   Sidebar Filters — Facettes en colonne (desktop aside)

   Chaque groupe est presente comme une mini-carte plate (fond bg-light,
   pas de bordure) avec un titre clair et des options aerees. Les counts
   sont des pills neutres qui basculent vers le primary au survol/actif.
   ══════════════════════════════════════════════════════════════ */

.sidebar-filters__search {
    display: flex;
    align-items: center;
    position: relative;
    margin-bottom: var(--spacing-lg);
}

.sidebar-filters__search-icon {
    position: absolute;
    left: var(--spacing-sm);
    color: var(--color-text-light);
    pointer-events: none;
}

.sidebar-filters__search-input {
    width: 100%;
    padding: var(--spacing-sm) var(--spacing-sm) var(--spacing-sm) 2.25rem;
    border: 1px solid var(--color-border);
    border-radius: var(--radius-sm);
    font-size: var(--font-size-sm);
    background: #fff;
    transition: border-color 0.15s ease;
}

.sidebar-filters__search-input:focus {
    outline: none;
    border-color: var(--color-primary);
    box-shadow: 0 0 0 2px var(--color-primary-light);
}

.sidebar-filters__group {
    background: var(--color-bg-light);
    border-radius: var(--radius-md);
    padding: var(--spacing-sm) var(--spacing-md);
    /* L'espacement inter-cards est porte par `.aside-content { gap }` —
       pas de margin-bottom ici sinon double-respiration. */
}

/* La `nav.sidebar-filters__facets` (wrap des templates CMS list comme
   `articles.html.twig`, `default.html.twig`) rassemble les
   `.sidebar-filters__group`. Sans style flex sur ce wrap, les cards
   s'empilent en `display: block` collées — le `gap` du parent
   `.aside-content` ne descend pas à travers le wrap.

   Sur /ressources (library/list.html.twig), les groupes sont posés
   DIRECTEMENT dans `.aside-content` (pas de wrap nav) et bénéficient
   du `gap: var(--spacing-sm)` du parent. On reproduit ici le même
   espacement visuel sur le wrap nav pour aligner les deux pages. */
.sidebar-filters__facets {
    display: flex;
    flex-direction: column;
    gap: var(--spacing-sm);
}

/* Variante dropdown — le composant `_dropdown.html.twig` est inline-flex
   par défaut (label + trigger côte à côte). En sidebar on garde le pattern
   visuel des autres facettes : titre uppercase au-dessus, trigger en
   pleine largeur sous le titre. */
.sidebar-filters__group--dropdown .dropdown {
    display: block;
    width: 100%;
}

.sidebar-filters__group--dropdown .dropdown__wrapper {
    width: 100%;
}

.sidebar-filters__group--dropdown .dropdown__trigger {
    width: 100%;
    justify-content: space-between;
}

.sidebar-filters__group-title {
    display: block;
    font-size: var(--font-size-xs);
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: var(--color-primary-dark);
    margin: 0 0 var(--spacing-sm);
    padding: 0;
    border-bottom: 0;
}

.sidebar-filters__options {
    list-style: none;
    padding: 0;
    margin: 0;
    display: flex;
    flex-direction: column;
    gap: 0.125rem;
}

.sidebar-filters__option {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--spacing-sm);
    padding: 0.3125rem 0.5625rem;
    border-radius: var(--radius-sm);
    font-size: var(--font-size-xs);
    line-height: 1.4;
    text-decoration: none;
    color: var(--color-text);
    transition: background-color 0.15s ease, color 0.15s ease;
}

.sidebar-filters__option:hover {
    background: #fff;
    color: var(--color-primary);
}

/* Indentation hierarchique pour les tags enfants (parent_slug present).
   Visuel : ligne verticale subtile + decalage gauche par niveau. */
.sidebar-filters__option--depth-1 {
    padding-left: 1.25rem;
    position: relative;
}
.sidebar-filters__option--depth-2 {
    padding-left: 2rem;
    position: relative;
}
.sidebar-filters__option--depth-1::before,
.sidebar-filters__option--depth-2::before {
    content: '';
    position: absolute;
    left: 0.625rem;
    top: 50%;
    width: 0.5rem;
    height: 1px;
    background: color-mix(in srgb, var(--color-primary) 30%, transparent);
}
.sidebar-filters__option--depth-2::before {
    left: 1.375rem;
}

.sidebar-filters__option:focus-visible {
    outline: 2px solid var(--color-primary);
    outline-offset: 1px;
}

/* Etat actif : fond teinte primary doux + texte navy. Choix sobre vs
   un fond plein primary : la facette reste un repere de navigation,
   pas un CTA — l'attention focale appartient aux resultats. */
.sidebar-filters__option--active {
    background: color-mix(in srgb, var(--color-primary) 12%, #fff);
    color: var(--color-navy);
    font-weight: 600;
}

.sidebar-filters__option--active:hover {
    background: color-mix(in srgb, var(--color-primary) 18%, #fff);
    color: var(--color-navy);
}

.sidebar-filters__count {
    margin-left: auto;
    flex-shrink: 0;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 1.625rem;
    height: 1.25rem;
    padding: 0 0.4375rem;
    border-radius: 100px;
    font-size: 0.6875rem;
    font-weight: 600;
    line-height: 1;
    color: var(--color-text-light);
    background: #fff;
    border: 1px solid var(--color-border);
    transition: background-color 0.15s ease, color 0.15s ease, border-color 0.15s ease;
}

/* Bloc proximité : code postal + rayon cote a cote (grille 2 colonnes),
   auto-submit en JS au change. Le bouton Appliquer ne sert qu'au fallback
   noscript. */
.sidebar-filters__proximity-form {
    display: flex;
    flex-direction: column;
    gap: var(--spacing-sm);
}

.sidebar-filters__proximity-row {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    gap: var(--spacing-sm);
    align-items: end;
}

.sidebar-filters__field {
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
    min-width: 0;
}

.sidebar-filters__field-label {
    font-size: var(--font-size-xs);
    font-weight: 600;
    color: var(--color-text-light);
}

.sidebar-filters__input {
    width: 100%;
    height: 2.125rem;
    padding: 0 0.5625rem;
    border: 1px solid var(--color-border);
    border-radius: var(--radius-sm);
    background: #fff;
    font-family: inherit;
    font-size: var(--font-size-sm);
    line-height: 1.4;
    color: var(--color-text);
    transition: border-color 0.15s ease, box-shadow 0.15s ease;
    box-sizing: border-box;
    appearance: none;
}

.sidebar-filters__input:focus {
    outline: none;
    border-color: var(--color-primary);
    box-shadow: 0 0 0 2px color-mix(in srgb, var(--color-primary) 25%, transparent);
}

.sidebar-filters__submit {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 0.4375rem 0.875rem;
    border: 0;
    border-radius: var(--radius-sm);
    background: var(--color-primary);
    color: #fff;
    font-size: var(--font-size-xs);
    font-weight: 600;
    cursor: pointer;
    transition: background-color 0.15s ease;
}

.sidebar-filters__submit:hover,
.sidebar-filters__submit:focus-visible {
    background: var(--color-primary-dark);
}

/* Header de groupe avec lien aligne a droite (Proximite -> Trouver votre CESU). */
.sidebar-filters__group-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--spacing-sm);
    margin: 0 0 var(--spacing-sm);
}

.sidebar-filters__group-header .sidebar-filters__group-title {
    margin: 0;
}

.sidebar-filters__group-link {
    display: inline-flex;
    align-items: center;
    gap: 0.25rem;
    padding: 0;
    border: 0;
    background: transparent;
    font-family: inherit;
    font-size: var(--font-size-xs);
    font-weight: 500;
    color: var(--color-primary);
    text-decoration: none;
    cursor: pointer;
    transition: color 0.15s ease;
    white-space: nowrap;
}

.sidebar-filters__group-link:hover,
.sidebar-filters__group-link:focus-visible {
    color: var(--color-primary-dark);
    text-decoration: underline;
}

.sidebar-filters__group-link-icon {
    flex-shrink: 0;
}

/* Override dropdown dans la colonne rayon : pleine largeur, aligne sur l'input CP. */
.sidebar-filters__field--radius .dropdown {
    display: block;
    width: 100%;
}

.sidebar-filters__field--radius .dropdown__wrapper {
    width: 100%;
}

.sidebar-filters__field--radius .dropdown__trigger {
    width: 100%;
    height: 2.125rem;
    justify-content: space-between;
    padding: 0 0.5625rem;
    font-family: inherit;
    font-size: var(--font-size-sm);
    line-height: 1.4;
    box-sizing: border-box;
}

/* Segment control binaire (Toutes / Sessions a venir). Deux boutons colles
   dans un conteneur arrondi a bordure unique. */
.sidebar-filters__segment {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    background: #fff;
    border: 1px solid var(--color-border);
    border-radius: var(--radius-sm);
    overflow: hidden;
    padding: 0;
}

.sidebar-filters__segment-option {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0.375rem;
    padding: 0.4375rem 0.5rem;
    font-size: var(--font-size-xs);
    font-weight: 500;
    line-height: 1.3;
    color: var(--color-text-light);
    text-decoration: none;
    transition: background-color 0.15s ease, color 0.15s ease;
    cursor: pointer;
}

.sidebar-filters__segment-option + .sidebar-filters__segment-option {
    border-left: 1px solid var(--color-border);
}

.sidebar-filters__segment-option:hover {
    background: color-mix(in srgb, var(--color-primary) 6%, transparent);
    color: var(--color-primary);
}

.sidebar-filters__segment-option--active {
    background: var(--color-primary);
    color: #fff;
}

.sidebar-filters__segment-option--active:hover {
    background: var(--color-primary-dark);
    color: #fff;
}

.sidebar-filters__segment-count {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 1.25rem;
    height: 1.125rem;
    padding: 0 0.3rem;
    border-radius: 999px;
    background: color-mix(in srgb, currentColor 18%, transparent);
    font-size: 0.6875rem;
    font-weight: 600;
    line-height: 1;
}

.sidebar-filters__segment-option--active .sidebar-filters__segment-count {
    background: rgba(255, 255, 255, 0.22);
}

.sidebar-filters__option:hover .sidebar-filters__count {
    border-color: color-mix(in srgb, var(--color-primary) 30%, var(--color-border));
    color: var(--color-primary);
}

/* Count d'une option active : bg blanc + texte primary + bordure primary
   plus marquee. Cible aussi `:hover` (specificity 0,2,0 superieure a la
   hover generique 0,2,0 — ordre source apres == gagne) pour eviter le
   bug ou le compteur disparaissait au survol d'une option deja active. */
.sidebar-filters__option--active .sidebar-filters__count,
.sidebar-filters__option--active:hover .sidebar-filters__count {
    background: #fff;
    color: var(--color-primary);
    border-color: color-mix(in srgb, var(--color-primary) 35%, var(--color-border));
}

/* ══════════════════════════════════════════════════════════════
   Filters Overlay — Drawer mobile plein écran
   ══════════════════════════════════════════════════════════════ */

.filters-overlay {
    position: fixed;
    inset: 0;
    z-index: 1100;
}

@media (min-width: 1024px) {
    .filters-overlay {
        display: none !important;
    }
}

.filters-overlay__backdrop {
    position: absolute;
    inset: 0;
    background: rgba(0, 0, 0, 0.4);
}

.filters-overlay__panel {
    position: absolute;
    bottom: 0;
    left: 0;
    right: 0;
    max-height: 85vh;
    background: #fff;
    border-radius: var(--radius-lg) var(--radius-lg) 0 0;
    display: flex;
    flex-direction: column;
    box-shadow: 0 -4px 24px rgba(0, 0, 0, 0.15);
}

.filters-overlay__panel--enter { transition: transform 0.3s ease; }
.filters-overlay__panel--enter-start { transform: translateY(100%); }
.filters-overlay__panel--enter-end { transform: translateY(0); }
.filters-overlay__panel--leave { transition: transform 0.2s ease; }
.filters-overlay__panel--leave-start { transform: translateY(0); }
.filters-overlay__panel--leave-end { transform: translateY(100%); }

.filters-overlay__header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: var(--spacing-md) var(--spacing-lg);
    border-bottom: 1px solid var(--color-border);
    flex-shrink: 0;
}

.filters-overlay__title {
    font-size: var(--font-size-lg);
    font-weight: 700;
    margin: 0;
}

.filters-overlay__close {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 2.5rem;
    height: 2.5rem;
    border-radius: 50%;
    border: none;
    background: var(--color-bg-light);
    cursor: pointer;
    color: var(--color-text);
    transition: background-color 0.15s ease;
}

.filters-overlay__close:hover {
    background: var(--color-border);
}

.filters-overlay__body {
    flex: 1;
    overflow-y: auto;
    padding: var(--spacing-lg);
}

.filters-overlay__footer {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--spacing-md);
    padding: var(--spacing-md) var(--spacing-lg);
    border-top: 1px solid var(--color-border);
    flex-shrink: 0;
}

.filters-overlay__reset {
    font-size: var(--font-size-sm);
    color: var(--color-text-light);
    text-decoration: none;
    transition: color 0.15s ease;
}

.filters-overlay__reset:hover {
    color: var(--color-text);
}

.filters-overlay__apply {
    padding: var(--spacing-sm) var(--spacing-xl);
    border: none;
    border-radius: var(--radius-sm);
    font-size: var(--font-size-sm);
    font-weight: 600;
    background: var(--color-primary);
    color: #fff;
    cursor: pointer;
    transition: background-color 0.15s ease;
}

.filters-overlay__apply:hover {
    background: var(--color-primary-dark);
}

/* ══════════════════════════════════════════════════════════════
   Content Card — Card de contenu réutilisable
   ══════════════════════════════════════════════════════════════ */

.content-card {
    width: 100%;
    background: #fff;
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    overflow: hidden;
    transition: box-shadow 0.2s ease, transform 0.15s ease, border-color 0.2s ease;
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.04);
}

.content-card:hover {
    border-color: transparent;
}

.content-card:hover {
    box-shadow: 0 4px 16px rgba(0, 0, 0, 0.1);
    transform: translateY(-2px);
}

.content-card__link {
    display: flex;
    flex-direction: column;
    height: 100%;
    text-decoration: none;
    color: inherit;
}

/* Image */
.content-card__image {
    position: relative;
    aspect-ratio: 16 / 9;
    overflow: hidden;
    background: var(--color-bg-light);
}

.content-card__image img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    transition: transform 0.3s ease;
}

.content-card:hover .content-card__image img {
    transform: scale(1.03);
}

/* ══════════════════════════════════════════════════════════════
   Resource card — composant dédié pour les listes de ressources
   ══════════════════════════════════════════════════════════════ */
.resource-card { border-bottom: 1px solid var(--color-border); }
.resource-card:last-child { border-bottom: none; }

.resource-card__link {
    display: flex;
    align-items: center;
    gap: var(--spacing-md);
    padding: var(--spacing-md) 0;
    text-decoration: none;
    color: inherit;
    transition: background 0.15s ease;
}
.resource-card__link:hover { background: var(--color-bg-light); margin: 0 calc(-1 * var(--spacing-md)); padding: var(--spacing-md); border-radius: var(--radius-md); }

/* Visual : thumbnail ou icône type */
.resource-card__visual { flex-shrink: 0; width: 5rem; height: 5rem; }

.resource-card__thumb {
    width: 100%;
    height: 100%;
    border-radius: var(--radius-sm);
    overflow: hidden;
    background: linear-gradient(135deg, var(--color-bg-light) 0%, #e8edf3 100%);
    border: 1px solid rgba(0, 0, 0, 0.06);
}
.resource-card__thumb img { width: 100%; height: 100%; object-fit: contain; }

.resource-card__icon {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    height: 100%;
    border-radius: var(--radius-sm);
    background: var(--color-bg-light);
}

.resource-card__icon--pdf { background: #fef2f2; color: #dc2626; }
.resource-card__icon--video { background: #fefce8; color: #ca8a04; }
.resource-card__icon--link { background: #eff6ff; color: #2563eb; }
.resource-card__icon--default { background: var(--color-bg-light); color: var(--color-text-light); }

/* Body */
.resource-card__body { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 0.125rem; }

.resource-card__meta { display: flex; align-items: center; gap: var(--spacing-xs); }

.resource-card__badge {
    display: inline-flex;
    padding: 0.0625rem 0.375rem;
    border-radius: var(--radius-sm);
    font-size: 0.625rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.04em;
}
.resource-card__badge--pdf { background: #fef2f2; color: #dc2626; }
.resource-card__badge--video { background: #fefce8; color: #ca8a04; }
.resource-card__badge--link { background: #eff6ff; color: #2563eb; }

.resource-card__date { font-size: var(--font-size-xs); color: var(--color-text-light); }

.resource-card__title { font-size: var(--font-size-base); font-weight: 600; color: var(--color-text); }
.resource-card__link:hover .resource-card__title { color: var(--color-navy); }

.resource-card__excerpt { font-size: var(--font-size-xs); color: var(--color-text-light); line-height: 1.4; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }

.resource-card__file-info { display: flex; align-items: center; gap: var(--spacing-xs); margin-top: 0.125rem; }
.resource-card__filename { font-size: var(--font-size-xs); color: var(--color-text-light); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 15rem; }
.resource-card__filesize { font-size: var(--font-size-xs); color: var(--color-text-light); white-space: nowrap; }
.resource-card__filename + .resource-card__filesize::before { content: '·'; margin-right: var(--spacing-xs); }

/* Flèche */
.resource-card__action { flex-shrink: 0; color: var(--color-text-light); transition: color 0.15s ease, transform 0.15s ease; }
.resource-card__link:hover .resource-card__action { color: var(--color-navy); transform: translateX(2px); }

@media (max-width: 47.9375em) {
    .resource-card__visual { width: 3.5rem; height: 3.5rem; }
    .resource-card__excerpt { display: none; }
    .resource-card__file-info { display: none; }
}

.content-card__placeholder {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    height: 100%;
    background: linear-gradient(135deg, var(--color-bg-light) 0%, #e8edf3 100%);
    color: var(--color-text-light);
}

/* Badge cadenas posé sur la cover quand l'accès est réservé pour le viewer
   courant (resolvers : isRestricted true). Position absolue → l'image
   conserve son aspect-ratio. */
.content-card__lock {
    position: absolute;
    top: var(--spacing-xs);
    left: var(--spacing-xs);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 1.75rem;
    height: 1.75rem;
    border-radius: 999px;
    background: rgba(0, 0, 0, 0.65);
    color: #fff;
    backdrop-filter: blur(2px);
    z-index: 1;
}

/* Body */
.content-card__body {
    display: flex;
    flex-direction: column;
    flex: 1;
    padding: var(--spacing-md);
}

.content-card__meta-top {
    display: flex;
    align-items: center;
    gap: var(--spacing-sm);
    margin-bottom: var(--spacing-xs);
}

.content-card__type {
    font-size: var(--font-size-xs);
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--color-primary);
}

.content-card__date {
    font-size: var(--font-size-xs);
    color: var(--color-text-light);
}

.content-card__type + .content-card__date::before {
    content: '·';
    margin-right: var(--spacing-sm);
    color: var(--color-border);
}

.content-card__title {
    font-size: var(--font-size-base);
    font-weight: 600;
    line-height: var(--line-height-tight);
    color: var(--color-text);
    display: -webkit-box;
    -webkit-line-clamp: 3;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

@media (min-width: 640px) {
    .content-card__title {
        font-size: var(--font-size-lg);
    }
}

.content-card__excerpt {
    margin-top: var(--spacing-sm);
    font-size: var(--font-size-sm);
    color: var(--color-text-light);
    line-height: var(--line-height-base);
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

/* Variante compact (sans image, card horizontale sur mobile) */
.content-card--compact .content-card__image {
    aspect-ratio: 3 / 2;
}


/* ══════════════════════════════════════════════════════════════
   Content Block Card (`.cb-card`) — items resolus d'un node TipTap
   `contentBlock` rendus en mode `list` (horizontal) ou `grid`
   (vertical). Design unifie : 2 layouts × 2 fonds (media/plain).

   Spec : coins tres arrondis, bouton d'action circulaire centre a
   droite (horizontal) ou pose en bas (vertical), texte blanc force
   sur les variantes media, fallback image plein-fond avec overlay
   gradient.
   ══════════════════════════════════════════════════════════════ */

/* RESET des overrides .prose-content qui leakent dans la card.
   Le contentBlock est imbrique dans `.prose-content` (newsletter,
   article, page CMS), qui applique des styles globaux sur h3 / a /
   p / etc.

   Toutes les regles `.cb-card*` qui doivent battre `.prose-content X`
   (specificite 0,2,1) sont doublees avec le scope newsletter
   `.nl-show__body .prose-content` (specificite 0,X,1+). Pattern
   verbeux mais qui evite le `!important` et garde le cascade
   predictible. */

/* Reset typo + position du titre (sans color : color gere par
   les variantes plain/media plus bas, avec le meme scope). */
.nl-show__body .prose-content .cb-card .cb-card__title,
.cb-card .cb-card__title {
    position: static;
    margin: 0;
    padding: 0;
    font-size: var(--font-size-base);
    font-weight: 600;
    line-height: var(--line-height-tight);
}

.nl-show__body .prose-content .cb-card .cb-card__title::before,
.cb-card .cb-card__title::before {
    content: none;
    display: none;
}

/* Liens internes : pas de soulignement, pas de couleur primary
   heritee de `.prose-content a`. */
.nl-show__body .prose-content .cb-card a,
.cb-card a.cb-card__link,
.cb-card .cb-card__link {
    color: inherit;
    text-decoration: none;
    background: transparent;
    border: none;
}

.nl-show__body .prose-content .cb-card a:hover,
.cb-card .cb-card__link:hover {
    text-decoration: none;
}

/* Reset eventuelles marges parasites entre descendants. */
.nl-show__body .prose-content .cb-card * + *,
.cb-card * + * {
    margin-top: 0;
}


/* Containers ─────────────────────────────────────────────────── */
.cb-card-list {
    display: flex;
    flex-direction: column;
    gap: var(--spacing-md);
    width: 100%;
}

.cb-card-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr));
    gap: var(--spacing-md);
    width: 100%;
}

/* Card base ──────────────────────────────────────────────────── */
.cb-card {
    position: relative;
    display: block;
    width: 100%;
    background: #fff;
    border: 1px solid var(--color-border);
    border-radius: 1rem;
    overflow: hidden;
    transition: border-color 0.2s ease, box-shadow 0.2s ease, transform 0.15s ease;
}

.cb-card:hover {
    border-color: transparent;
    box-shadow: 0 10px 24px rgba(0, 0, 0, 0.12);
    transform: translateY(-2px);
}

.cb-card__link {
    position: relative;
    display: flex;
    text-decoration: none;
    color: inherit;
    width: 100%;
    height: 100%;
}

/* Cover ─ image OU placeholder. Positionnement gere par le layout. */
.cb-card__cover {
    position: relative;
    overflow: hidden;
    background: linear-gradient(135deg, var(--color-bg-light) 0%, #e8edf3 100%);
}

/* Picture / img du cover : fillent integralement le cover (objet-fit
   cover pour cropper sans deformer). Reset margin + border-radius pour
   battre `.prose-content img` (margin-top/bottom: spacing-lg + radius)
   qui injectait un faux padding et faisait ressortir un cadre arrondi
   au milieu de la card. Scope dual newsletter+global pour battre la
   specificite de `.prose-content img` (0,1,1) — sans scope newsletter
   ma regle a meme spec et la cascade gagne sur la derniere declaree,
   ce qui rend la chaine fragile selon l'ordre des feuilles chargees. */
.nl-show__body .prose-content .cb-card .cb-card__cover picture,
.nl-show__body .prose-content .cb-card .cb-card__cover picture img,
.nl-show__body .prose-content .cb-card .cb-card__cover img,
.cb-card__cover picture,
.cb-card__cover picture img,
.cb-card__cover img {
    display: block;
    width: 100%;
    height: 100%;
    margin: 0;
    border-radius: 0;
    object-fit: cover;
}

.cb-card__cover--file-fallback {
    background-image: url("../../images/library-fallback-R5ZIW9z.jpg");
    background-size: cover;
    background-position: center;
    background-repeat: no-repeat;
}

/* Cover en `contain` (vs `cover` par defaut) : utilise pour les events
   dont les thumbnails sont typiquement des banners larges (Header
   JNE2026 etc.) qu'il faut voir integralement. Le ratio image preserve,
   eventuel letterboxing comble par le gradient placeholder dessous. */
.nl-show__body .prose-content .cb-card .cb-card__cover--contain picture,
.nl-show__body .prose-content .cb-card .cb-card__cover--contain picture img,
.nl-show__body .prose-content .cb-card .cb-card__cover--contain img,
.cb-card__cover--contain picture,
.cb-card__cover--contain picture img,
.cb-card__cover--contain img {
    object-fit: contain;
}

/* ──────────────────────────────────────────────────────────────
   Card event horizontale : layout 50/50 — thumbnail gauche, texte
   droite. Permet de mettre en valeur le banner header typique d'un
   evenement (JNE2026_Header, etc.) et place le chevron CTA (bas-droite)
   sur la colonne texte plutot que par-dessus l'image.
   Demande utilisateur 2026-05-22, ajuste 2026-06-03.
   ────────────────────────────────────────────────────────────── */
.cb-card--horizontal.cb-card--event .cb-card__link {
    flex-direction: row;
    min-height: 8rem;
}

.cb-card--horizontal.cb-card--event .cb-card__cover {
    width: 50%;
    flex-shrink: 0;
    display: flex;
    align-items: center;
    justify-content: center;
}

/* Fond transparent sur les events (les deux layouts) : sinon le
   gradient placeholder gris apparait en letterbox autour de l'image
   `contain`, peu esthetique. Le card a un fond blanc qui prend le
   relais visuellement, l'image s'affiche sans bordure parasite. */
.cb-card--event .cb-card__cover {
    background: transparent;
}

.cb-card--horizontal.cb-card--event .cb-card__body {
    padding: var(--spacing-md) var(--spacing-lg) var(--spacing-md) var(--spacing-md);
}

/* Action positionnee bas-droite de la card (= bas-droite de la colonne
   texte, image a gauche). Le bouton vit dans le coin bas-droite du body
   (whitespace sous le texte) sans masquer ni le texte ni l'image. */
.cb-card--horizontal.cb-card--event .cb-card__action {
    top: auto;
    left: auto;
    right: var(--spacing-md);
    bottom: var(--spacing-md);
    transform: none;
}

.cb-card--horizontal.cb-card--event:hover .cb-card__action {
    transform: scale(1.06);
}

@media (max-width: 39.9375em) {
    .cb-card--horizontal.cb-card--event .cb-card__link {
        flex-direction: column;
        min-height: 0;
    }

    .cb-card--horizontal.cb-card--event .cb-card__cover {
        width: 100%;
        min-width: 0;
        aspect-ratio: 16 / 9;
    }
}

.cb-card__placeholder {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    height: 100%;
    color: var(--color-navy);
    opacity: 0.35;
}

/* Body ─ contenu textuel. Positionnement et padding par layout. */
.cb-card__body {
    position: relative;
    z-index: 2;
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
    justify-content: center;
    gap: 0.35rem;
}

.cb-card__eyebrow {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--spacing-sm);
}

.cb-card__type {
    font-size: var(--font-size-xs);
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--color-primary);
    white-space: nowrap;
}

.cb-card__date {
    font-size: var(--font-size-xs);
    color: var(--color-text-light);
    white-space: nowrap;
}

.cb-card__title {
    margin: 0;
    font-size: var(--font-size-base);
    font-weight: 600;
    line-height: var(--line-height-tight);
    color: var(--color-text);
    display: -webkit-box;
    -webkit-line-clamp: 2;
    line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

/* Suffix "(type)" inline dans le titre — Library mode list. */
.cb-card__title-type {
    font-weight: 500;
    color: var(--color-text-light);
    text-transform: none;
    letter-spacing: 0;
}

/* Type entre parentheses dans les listes a puces / numerotees
   (modes `bullets` / `numbered` du contentBlock). */
.cb-list-type {
    color: var(--color-text-light);
    font-weight: 400;
    font-size: 0.92em;
}

.cb-card__format {
    align-self: flex-start;
    font-size: var(--font-size-2xs);
    font-weight: 500;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--color-text-light);
}

/* Sous-titre / thematique sous le titre principal — utilise par
   `_event.html.twig` pour rendre `Event.theme`. Scope dual pour
   battre les regles prose-content sur span (couleur, taille). */
.nl-show__body .prose-content .cb-card .cb-card__subtitle,
.cb-card .cb-card__subtitle {
    display: block;
    font-size: var(--font-size-sm);
    font-weight: 400;
    color: var(--color-text-light);
    line-height: var(--line-height-tight);
}

.nl-show__body .prose-content .cb-card--media .cb-card__subtitle,
.cb-card--media .cb-card__subtitle {
    color: rgba(255, 255, 255, 0.9);
    text-shadow: 0 1px 2px rgba(0, 0, 0, 0.6);
}

/* Variante block de `.cb-card__date` : utilisee en complement quand
   la date doit s'afficher sur sa propre ligne sous le titre
   (ex: range dateStart -> dateEnd sur une event card). Sans ce
   modifier le `.cb-card__date` natif reste inline (ex: dans
   l'eyebrow a cote du type). */
.nl-show__body .prose-content .cb-card .cb-card__date--block,
.cb-card .cb-card__date--block {
    display: block;
    font-size: var(--font-size-sm);
    line-height: var(--line-height-tight);
    margin-top: 0.15rem;
}

.nl-show__body .prose-content .cb-card--media .cb-card__date--block,
.cb-card--media .cb-card__date--block {
    color: rgba(255, 255, 255, 0.9);
    text-shadow: 0 1px 2px rgba(0, 0, 0, 0.6);
}

/* Action ─ bouton rond, centre vertical droite (horizontal) ou
   bas droite (vertical). Pas de bordure parasite. Le SVG enfant
   est centre via flex sur le span ET un reset SVG complet pour
   neutraliser tous les overrides parasites qui pourraient leaker
   depuis prose-content / dam-image / etc. (incident 2026-05-22 :
   line-height heritee de prose-content decalait le SVG du centre
   vertical du span). */
.nl-show__body .prose-content .cb-card .cb-card__action,
.cb-card .cb-card__action {
    position: absolute;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 2.75rem;
    height: 2.75rem;
    border-radius: 999px;
    color: #fff;
    background: var(--color-navy);
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.18);
    z-index: 3;
    margin: 0;
    padding: 0;
    line-height: 1;
    font-size: 0;
    transition: background-color 0.15s ease, transform 0.15s ease;
}

.nl-show__body .prose-content .cb-card .cb-card__action svg,
.cb-card .cb-card__action svg {
    display: block;
    width: 1.5rem;
    height: 1.5rem;
    margin: 0;
    padding: 0;
    flex-shrink: 0;
    vertical-align: middle;
    overflow: visible;
    color: inherit;
    fill: none;
    stroke: currentColor;
}

.cb-card:hover .cb-card__action {
    background: var(--color-primary);
    transform: scale(1.06);
}

/* Lock ─ badge restreint, top-left du card (au-dessus cover). */
.cb-card__lock {
    position: absolute;
    top: var(--spacing-sm);
    left: var(--spacing-sm);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 1.75rem;
    height: 1.75rem;
    border-radius: 999px;
    background: rgba(0, 0, 0, 0.7);
    color: #fff;
    z-index: 3;
    backdrop-filter: blur(2px);
}

/* Glyphe cadenas rendu explicitement (taille, stroke blanc) — sans cette
   regle le badge s'affichait mais le cadenas restait invisible (cercle noir
   vide). Meme remede que `.cb-card__action svg`. S'applique aussi au lock des
   `.content-card` (badge "Reserve" blanc sur fond sombre). */
.nl-show__body .prose-content .cb-card .cb-card__lock svg,
.cb-card .cb-card__lock svg,
.content-card__lock svg {
    display: block;
    width: 0.875rem;
    height: 0.875rem;
    margin: 0;
    padding: 0;
    flex-shrink: 0;
    overflow: visible;
    color: #fff;
    fill: none;
    stroke: currentColor;
}

/* ═══════════════════════════════════════════════════════════════
   Layout HORIZONTAL : image en cover plein-fond OU colonne gauche
   ─────────────────────────────────────────────────────────────── */
.cb-card--horizontal .cb-card__link {
    flex-direction: row;
    align-items: stretch;
    min-height: 7rem;
}

/* PLAIN horizontal : cover plafonne a 50% de la card pour eviter
   qu'un type avec banner large ne mange tout l'horizontal. Le
   `flex-shrink: 0` verrouille en mode auto-content si le contenu
   image est plus petit que 50%. */
.cb-card--horizontal.cb-card--plain .cb-card__cover {
    max-width: 50%;
    flex-shrink: 0;
}

.cb-card--horizontal.cb-card--plain .cb-card__body {
    padding: var(--spacing-md) calc(var(--spacing-lg) + 3rem) var(--spacing-md) var(--spacing-md);
}

/* MEDIA horizontal : image absolute plein-fond + overlay. */
.cb-card--horizontal.cb-card--media .cb-card__cover {
    position: absolute;
    inset: 0;
    z-index: 0;
}

.cb-card--horizontal.cb-card--media .cb-card__body {
    padding: var(--spacing-md) calc(var(--spacing-lg) + 3rem) var(--spacing-md) var(--spacing-lg);
}

/* Action positionnee centree verticale droite en horizontal. */
.cb-card--horizontal .cb-card__action {
    top: 50%;
    right: var(--spacing-md);
    transform: translateY(-50%);
}

.cb-card--horizontal:hover .cb-card__action {
    transform: translateY(-50%) scale(1.06);
}

/* ═══════════════════════════════════════════════════════════════
   Layout VERTICAL : image en haut, body en bas
   ─────────────────────────────────────────────────────────────── */
.cb-card--vertical .cb-card__link {
    flex-direction: column;
    min-height: 0;
}

.cb-card--vertical .cb-card__cover {
    width: 100%;
    aspect-ratio: 16 / 9;
}

/* MEDIA vertical : la cover prend tout en haut, le body reste lisible
   par dessus l'overlay (gradient localise sur la partie basse). */
.cb-card--vertical.cb-card--media .cb-card__cover {
    aspect-ratio: auto;
    min-height: 11rem;
    position: absolute;
    inset: 0;
    z-index: 0;
}

.cb-card--vertical.cb-card--media .cb-card__link {
    min-height: 12rem;
}

.cb-card--vertical .cb-card__body {
    padding: var(--spacing-md) var(--spacing-md) calc(var(--spacing-md) + 1rem);
}

/* En vertical media le body se loge en bas (sous l'overlay gradient). */
.cb-card--vertical.cb-card--media .cb-card__body {
    justify-content: flex-end;
}

/* Action positionnee haut-droite en vertical : evite de masquer
   le titre qui se loge en bas de card (incident 2026-05-22 — bouton
   glass au-dessus du titre rendait celui-ci illisible). */
.cb-card--vertical .cb-card__action {
    top: var(--spacing-md);
    right: var(--spacing-md);
}

.cb-card--vertical:hover .cb-card__action {
    transform: scale(1.06);
}

/* ═══════════════════════════════════════════════════════════════
   Variante MEDIA — overlay + texte blanc force. S'applique aux
   deux orientations.
   ─────────────────────────────────────────────────────────────── */
.cb-card--media {
    border-color: transparent;
    color: #fff;
}

.cb-card__overlay {
    position: absolute;
    inset: 0;
    z-index: 1;
    pointer-events: none;
}

/* Overlay UNIFORME en horizontal — navy ANCESU (#344b8d) avec
   densite forte partout pour garantir la lisibilite du titre quelle
   que soit la zone de l'image. */
.cb-card--horizontal .cb-card__overlay {
    background: rgba(52, 75, 141, 0.78);
}

/* Overlay vertical — gradient navy, plus sombre en bas (le body
   se loge en bas et a besoin du contraste maximal). */
.cb-card--vertical .cb-card__overlay {
    background: linear-gradient(
        180deg,
        rgba(52, 75, 141, 0.55) 0%,
        rgba(52, 75, 141, 0.75) 50%,
        rgba(52, 75, 141, 0.94) 100%
    );
}

/* Scopes doubles pour battre les eventuelles regles
   `.prose-content` sur span / time. */
.nl-show__body .prose-content .cb-card--media .cb-card__type,
.cb-card--media .cb-card__type {
    color: #fff;
    text-shadow: 0 1px 2px rgba(0, 0, 0, 0.4);
}

.nl-show__body .prose-content .cb-card--media .cb-card__date,
.nl-show__body .prose-content .cb-card--media .cb-card__title-type,
.cb-card--media .cb-card__date,
.cb-card--media .cb-card__title-type {
    color: rgba(255, 255, 255, 0.9);
    text-shadow: 0 1px 2px rgba(0, 0, 0, 0.6);
}

/* Color titre — scopes doubles pour battre le reset
   `.nl-show__body .prose-content .cb-card .cb-card__title` (0,4,1)
   qui a une specificite plus elevee que le simple `.cb-card--media
   .cb-card__title` (0,2,0). */
.nl-show__body .prose-content .cb-card--media .cb-card__title,
.cb-card--media .cb-card__title {
    color: #fff;
    font-size: var(--font-size-md);
    font-weight: 700;
    text-shadow: 0 2px 6px rgba(0, 0, 0, 0.6), 0 1px 2px rgba(0, 0, 0, 0.8);
}

.nl-show__body .prose-content .cb-card--plain .cb-card__title,
.cb-card--plain .cb-card__title {
    color: var(--color-text);
}

.cb-card--media:hover .cb-card__title {
    color: #fff;
}

.cb-card--media .cb-card__format {
    align-self: flex-start;
    color: #fff;
    background: rgba(255, 255, 255, 0.18);
    padding: 0.125rem 0.5rem;
    border-radius: var(--radius-sm);
    backdrop-filter: blur(2px);
}

/* Action sur media : blanc semi-transparent avec blur backdrop pour
   un effet "glass" sur l'image. Scope newsletter pour battre la
   specificite du base rule `.nl-show__body .prose-content .cb-card
   .cb-card__action` (0,4,1) qui forcait sinon navy uniforme. */
.nl-show__body .prose-content .cb-card--media .cb-card__action,
.cb-card--media .cb-card__action {
    background: rgba(255, 255, 255, 0.2);
    color: #fff;
    box-shadow: 0 4px 16px rgba(0, 0, 0, 0.3);
    backdrop-filter: blur(6px);
    -webkit-backdrop-filter: blur(6px);
}

.nl-show__body .prose-content .cb-card--media:hover .cb-card__action,
.cb-card--media:hover .cb-card__action {
    background: rgba(255, 255, 255, 0.32);
    color: #fff;
}

/* ═══════════════════════════════════════════════════════════════
   PLAIN — hover sur le titre (la variante media garde son blanc).
   ─────────────────────────────────────────────────────────────── */
.cb-card--plain:hover .cb-card__title {
    color: var(--color-navy);
}

/* ═══════════════════════════════════════════════════════════════
   Responsive — sur mobile, les layouts horizontal et plain
   degradent en vertical pour preserver la lisibilite.
   ─────────────────────────────────────────────────────────────── */
@media (max-width: 39.9375em) {
    .cb-card--horizontal.cb-card--plain .cb-card__link {
        flex-direction: column;
    }

    .cb-card--horizontal.cb-card--plain .cb-card__cover {
        width: 100%;
        min-width: 0;
        aspect-ratio: 16 / 9;
    }

    .cb-card--horizontal.cb-card--plain .cb-card__body {
        padding: var(--spacing-md);
    }

    .cb-card--horizontal .cb-card__action {
        top: auto;
        bottom: var(--spacing-md);
        right: var(--spacing-md);
        transform: none;
    }

    .cb-card--horizontal:hover .cb-card__action {
        transform: scale(1.06);
    }
}

/* ──────────────────────────────────────────────────────────────
   `.cb-card` rendu print — meme apparence visuelle qu'une liste a
   puces classique (`<ul>`) : conteneur indente, puce disc en
   marge, titre + URL inline avec peu d'espace vertical. Permet
   de gagner de la place a l'impression sans perdre la
   lisibilite. Le QR global du cartouche `_print_page` couvre
   l'acces en ligne — pas de QR par-card.
   ────────────────────────────────────────────────────────────── */
@media print {
    /* Reset agressif sur tous les descendants des cards : annule
       text-shadow, box-shadow, background, text-transform,
       letter-spacing, font-family/size/weight herites des regles
       ecran (media variant, h3 prose-content, etc.). Sans ce reset
       le titre traine son text-shadow blanc de la variante media,
       le `.cb-card__type` reste en uppercase tracking 0.05em, etc. */
    .cb-card,
    .cb-card * {
        background: none !important;
        background-color: transparent !important;
        background-image: none !important;
        box-shadow: none !important;
        text-shadow: none !important;
        border: none !important;
        font-family: inherit !important;
        font-size: inherit !important;
        font-weight: inherit !important;
        font-style: inherit !important;
        line-height: inherit !important;
        letter-spacing: normal !important;
        text-transform: none !important;
        color: inherit !important;
        margin: 0 !important;
        padding: 0 !important;
    }

    /* Conteneur : se comporte comme un <ul> — indentation pour les
       puces. */
    .cb-card-list,
    .cb-card-grid {
        display: block !important;
        margin: 0.5em 0 !important;
        padding-left: 1.4em !important;
        list-style: disc;
    }

    /* Card : devient un `<li>` virtuel avec puce disc. */
    .cb-card {
        display: list-item !important;
        list-style-type: disc;
        list-style-position: outside;
        margin: 0.1em 0 !important;
        page-break-inside: avoid;
    }

    /* Image / overlay / action / lock : hors-jeu. */
    .cb-card__cover,
    .cb-card__overlay,
    .cb-card__action,
    .cb-card__lock {
        display: none !important;
    }

    /* Tout le reste (link, body, eyebrow, title, type, date) est
       inline et herite de la typo du document. Seuls quelques
       elements sont masques (subtitle / format / title-type :
       meta secondaires non demandees). */
    .cb-card__link,
    .cb-card__body,
    .cb-card__eyebrow,
    .cb-card__title,
    .cb-card__type,
    .cb-card__date {
        display: inline !important;
    }

    .cb-card__link {
        color: #000 !important;
        text-decoration: underline;
    }

    /* Mention "(voir en ligne)" appendee a chaque card en print :
       en navigation papier/PDF, sans cette indication, l'utilisateur
       ne peut pas reperer que le titre est un lien. Le marqueur est
       inclus dans le `<a>` (clickable en PDF), style en primary
       souligne pour bien ressortir. */
    .cb-card__link::after {
        content: " (voir en ligne)";
        color: #344b8d !important;
        font-style: italic;
        text-decoration: underline;
    }

    .cb-card__type {
        margin-right: 0.3em !important;
    }

    .cb-card__date {
        margin-left: 0.3em !important;
        color: #555 !important;
    }

    .cb-card__subtitle,
    .cb-card__format,
    .cb-card__title-type {
        display: none !important;
    }
}

/* ──────────────────────────────────────────────────────────────
   Variante horizontale legacy (`.content-card--horizontal`)
   ────────────────────────────────────────────────────────────── */
.content-card--horizontal .content-card__link {
    flex-direction: row;
    align-items: stretch;
    min-height: 7.5rem;
}

.content-card--horizontal .content-card__image {
    width: 9.5rem;
    min-width: 9.5rem;
    aspect-ratio: auto;
}

.content-card--horizontal .content-card__body {
    justify-content: center;
    gap: var(--spacing-xs);
    min-width: 0;
}

/* Meta-top : autorise le wrap pour eviter "ÉVÉNEM\nENT" et
   garde chaque libellé sur une ligne entière. */
.content-card--horizontal .content-card__meta-top {
    flex-wrap: wrap;
    margin-bottom: 0;
}

.content-card--horizontal .content-card__type,
.content-card--horizontal .content-card__date {
    white-space: nowrap;
}

/* Quand le type est suivi d'une date wrappée sur la ligne
   suivante, le séparateur "·" historique reste sur l'ancienne
   ligne — masquer pour eviter un point orphelin. */
.content-card--horizontal .content-card__type + .content-card__date::before {
    content: none;
}

.content-card--horizontal .content-card__title {
    -webkit-line-clamp: 2;
    line-clamp: 2;
    font-size: var(--font-size-base);
}

@media (min-width: 640px) {
    .content-card--horizontal .content-card__title {
        font-size: var(--font-size-md);
    }
}

/* Excerpt masqué en horizontal : la card vise la compacité, le
   chevron + titre + meta suffisent. */
.content-card--horizontal .content-card__excerpt {
    display: none;
}

/* Chevron d'accès — affiché uniquement en variante horizontale. */
.content-card__action {
    display: none;
}

.content-card--horizontal .content-card__action {
    display: flex;
    align-items: center;
    flex-shrink: 0;
    padding-right: var(--spacing-md);
    color: var(--color-text-light);
    transition: color 0.15s ease, transform 0.15s ease;
}

.content-card--horizontal:hover .content-card__action {
    color: var(--color-navy);
    transform: translateX(2px);
}

@media (max-width: 639px) {
    .content-card--horizontal .content-card__link {
        flex-direction: column;
        align-items: stretch;
        min-height: 0;
    }

    .content-card--horizontal .content-card__image {
        width: 100%;
        min-width: auto;
        aspect-ratio: 16 / 9;
    }

    .content-card--horizontal .content-card__action {
        display: none;
    }
}

/* ══════════════════════════════════════════════════════════════
   Pagination — Plus aeree, bordures plus douces, etat actif plus marque.
   ══════════════════════════════════════════════════════════════ */

.pagination {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--spacing-md);
    margin-top: var(--spacing-2xl);
    padding-top: var(--spacing-xl);
    border-top: 1px solid var(--color-border);
}

.pagination__info {
    font-size: var(--font-size-sm);
    color: var(--color-text-light);
}

.pagination__list {
    display: flex;
    align-items: center;
    gap: 0.375rem;
    list-style: none;
    padding: 0;
    margin: 0;
}

.pagination__link {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--spacing-xs);
    min-width: 2.5rem;
    height: 2.5rem;
    padding: 0 var(--spacing-sm);
    border: 1px solid transparent;
    border-radius: var(--radius-md);
    font-size: var(--font-size-sm);
    font-weight: 500;
    text-decoration: none;
    color: var(--color-text);
    background: transparent;
    transition: background-color 0.15s ease, color 0.15s ease, border-color 0.15s ease, box-shadow 0.15s ease;
}

.pagination__link:hover:not(.pagination__link--disabled):not(.pagination__link--active) {
    background-color: var(--color-bg-light);
    border-color: var(--color-border);
    color: var(--color-primary);
}

.pagination__link:focus-visible {
    outline: 2px solid var(--color-primary);
    outline-offset: 2px;
}

.pagination__link--active {
    background-color: var(--color-primary);
    border-color: var(--color-primary);
    color: #fff;
    font-weight: 600;
    box-shadow: 0 2px 6px color-mix(in srgb, var(--color-primary) 28%, transparent);
}

/* Pas de border permanente ni de fond blanc sur Précédent/Suivant : on
   reste sur le pattern ghost des chiffres (border-color transparent par
   défaut, hover seul porte l'affordance). Le cadre permanent créait un
   effet « double border » dissonant avec le `border-top` du wrapper
   `.pagination`. Le label texte + chevron suffit à différencier les nav
   des numéros. */
.pagination__link--prev,
.pagination__link--next {
    gap: var(--spacing-xs);
}

.pagination__link--prev:hover:not(.pagination__link--disabled),
.pagination__link--next:hover:not(.pagination__link--disabled) {
    background-color: var(--color-bg-light);
    border-color: var(--color-border);
    color: var(--color-primary);
}

.pagination__link--disabled {
    opacity: 0.35;
    cursor: default;
}

/* Label "Precedent" / "Suivant" : visible >= sm, masque sur mobile. */
.pagination__nav-label {
    display: none;
}

@media (min-width: 640px) {
    .pagination__nav-label {
        display: inline;
    }
}

.pagination__ellipsis {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 2.5rem;
    height: 2.5rem;
    font-size: var(--font-size-sm);
    color: var(--color-text-light);
}

@media (max-width: 639px) {
    .pagination__link {
        min-width: 2.25rem;
        height: 2.25rem;
        font-size: var(--font-size-xs);
    }
    .pagination__ellipsis {
        width: 1.75rem;
        height: 2.25rem;
    }
}

/* Chips filtres actifs */
.content-list__active-filters {
    display: flex;
    flex-wrap: wrap;
    gap: var(--spacing-sm);
    margin-bottom: var(--spacing-lg);
}

/* .filter-chip vit désormais dans components/active-filters.css (global). */

/* Reset link (état vide avec filtres) */
.content-list__reset-link {
    display: inline-flex;
    align-items: center;
    gap: var(--spacing-xs);
    padding: var(--spacing-sm) var(--spacing-lg);
    margin-top: var(--spacing-sm);
    border-radius: var(--radius-sm);
    font-size: var(--font-size-sm);
    font-weight: 500;
    text-decoration: none;
    background: var(--color-primary);
    color: #fff;
    transition: background-color 0.15s ease;
}

.content-list__reset-link:hover {
    background: var(--color-primary-dark);
}

@media (max-width: 639px) {
    .dropdown__label {
        display: none;
    }
}

/* ══════════════════════════════════════════════════════════════
   Dropdown — Composant select custom (remplace <select> natif)
   ══════════════════════════════════════════════════════════════ */

.dropdown {
    display: inline-flex;
    align-items: center;
    gap: var(--spacing-xs);
    position: relative;
}

.dropdown__label {
    font-size: var(--font-size-sm);
    color: var(--color-text-light);
    white-space: nowrap;
}

.dropdown__wrapper {
    position: relative;
}

.dropdown__trigger {
    display: inline-flex;
    align-items: center;
    gap: var(--spacing-sm);
    padding: 0.4375rem 0.75rem;
    border: 1px solid var(--color-border);
    border-radius: var(--radius-sm);
    font-size: var(--font-size-sm);
    font-weight: 500;
    line-height: 1.4;
    color: var(--color-text);
    background: #fff;
    cursor: pointer;
    white-space: nowrap;
    transition: border-color 0.15s ease, box-shadow 0.15s ease;
    appearance: none;
}

.dropdown__trigger:hover {
    border-color: var(--color-primary);
}

.dropdown__trigger:focus-visible {
    outline: none;
    border-color: var(--color-primary);
    box-shadow: 0 0 0 2px var(--color-primary-light);
}

.dropdown__value {
    flex: 1;
    text-align: left;
}

.dropdown__chevron {
    flex-shrink: 0;
    color: var(--color-text-light);
    transition: transform 0.2s ease;
}

.dropdown__chevron--open {
    transform: rotate(180deg);
}

/* Menu déroulant */
.dropdown__menu {
    position: absolute;
    top: calc(100% + 4px);
    right: 0;
    min-width: 100%;
    max-height: 280px;
    overflow-y: auto;
    padding: 0.25rem;
    margin: 0;
    list-style: none;
    background: #fff;
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.12), 0 2px 6px rgba(0, 0, 0, 0.06);
    z-index: 50;
}

/* Menu teleporte vers <body> (coords fixed posees en inline par Alpine) :
   echappe a l'`overflow: auto` de la sidebar qui clipperait le menu absolu
   et declencherait un ascenseur parasite. `right: auto` annule le `right: 0`
   du menu absolu (sinon conflit avec le `left` inline). */
.dropdown__menu--teleported {
    position: fixed;
    right: auto;
    z-index: 200;
}

/* Transitions Alpine.js */
.dropdown__menu--enter {
    transition: opacity 0.15s ease, transform 0.15s ease;
}

.dropdown__menu--enter-start {
    opacity: 0;
    transform: translateY(-4px);
}

.dropdown__menu--enter-end {
    opacity: 1;
    transform: translateY(0);
}

.dropdown__menu--leave {
    transition: opacity 0.1s ease, transform 0.1s ease;
}

.dropdown__menu--leave-start {
    opacity: 1;
    transform: translateY(0);
}

.dropdown__menu--leave-end {
    opacity: 0;
    transform: translateY(-4px);
}

/* Options */
.dropdown__option {
    list-style: none;
}

.dropdown__option-link {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--spacing-md);
    width: 100%;
    padding: 0.5rem 0.75rem;
    border: none;
    border-radius: var(--radius-sm);
    font-size: var(--font-size-sm);
    text-align: left;
    text-decoration: none;
    color: var(--color-text);
    background: transparent;
    cursor: pointer;
    white-space: nowrap;
    transition: background-color 0.1s ease, color 0.1s ease;
}

.dropdown__option-link:hover {
    background: var(--color-bg-light);
    color: var(--color-primary);
}

.dropdown__option--active .dropdown__option-link {
    color: var(--color-primary);
    font-weight: 600;
}

.dropdown__check {
    flex-shrink: 0;
    color: var(--color-primary);
}

/* État loading — spinner + barre de progression */
.dropdown__trigger--loading {
    pointer-events: none;
    opacity: 0.7;
}

.dropdown__spinner {
    flex-shrink: 0;
    color: var(--color-primary);
    animation: dropdown-spin 0.7s linear infinite;
}

@keyframes dropdown-spin {
    to { transform: rotate(360deg); }
}

.dropdown__loading-bar {
    position: absolute;
    bottom: -1px;
    left: 0;
    right: 0;
    height: 2px;
    border-radius: 1px;
    overflow: hidden;
    background: var(--color-primary-light);
}

.dropdown__loading-bar::after {
    content: '';
    display: block;
    width: 40%;
    height: 100%;
    background: var(--color-primary);
    border-radius: 1px;
    animation: dropdown-loading 1s ease-in-out infinite;
}

@keyframes dropdown-loading {
    0%   { transform: translateX(-100%); }
    50%  { transform: translateX(200%); }
    100% { transform: translateX(-100%); }
}

/* Variante sm (compacte) */
.dropdown--sm .dropdown__trigger {
    padding: 0.3125rem 0.625rem;
    font-size: var(--font-size-xs);
}

.dropdown--sm .dropdown__option-link {
    padding: 0.375rem 0.625rem;
    font-size: var(--font-size-xs);
}

/* ══════════════════════════════════════════
   Page header — composant transversal
   ══════════════════════════════════════════ */

.page-header {
    padding: var(--spacing-2xl) 0 0;
    margin-bottom: var(--spacing-xl);
}

.page-header .container {
    padding-bottom: var(--spacing-xl);
    border-bottom: 1px solid var(--color-border);
}

.page-header__meta {
    display: flex;
    align-items: center;
    gap: var(--spacing-sm);
    margin-bottom: var(--spacing-sm);
}

.page-header__badge {
    display: inline-block;
    font-size: var(--font-size-xs);
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--color-primary);
    background: var(--color-primary-light);
    padding: 0.125rem 0.5rem;
    border-radius: var(--radius-sm);
}

.page-header__date {
    font-size: var(--font-size-xs);
    color: var(--color-text-light);
}

.page-header__title {
    font-size: 2rem;
    font-weight: 300;
    text-transform: uppercase;
    letter-spacing: 0.02em;
    margin: 0 0 var(--spacing-sm);
}

.page-header__lead {
    font-size: var(--font-size-lg);
    color: var(--color-text-light);
    line-height: 1.7;
    max-width: 42rem;
    margin: 0;
}

.page-header__eyebrow {
    font-size: var(--font-size-xs);
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: var(--color-primary);
    margin: 0 0 var(--spacing-xs);
}

.page-header__actions {
    display: flex;
    flex-wrap: wrap;
    gap: var(--spacing-sm);
    margin-top: var(--spacing-lg);
}

.page-header--compact {
    padding: var(--spacing-lg) 0 0;
    margin-bottom: var(--spacing-md);
}

.page-header--compact .container {
    padding-bottom: var(--spacing-md);
}

.page-header--compact .page-header__title {
    font-size: 1.5rem;
}

@media (max-width: 47.999em) {
    .page-header {
        padding: var(--spacing-lg) 0 var(--spacing-md);
        margin-bottom: var(--spacing-md);
    }

    .page-header__title {
        font-size: 1.375rem;
    }
}

@media (max-width: 29.999em) {
    .page-header__title {
        font-size: 1.25rem;
    }
}

/* ══════════════════════════════════════════
   Teaser wall — paywall souple
   ══════════════════════════════════════════ */

/* Corps tronqué : masque le débordement */
.article-single__body--teaser,
.page-prose__body--teaser {
    position: relative;
    overflow: hidden;
    max-height: none;
}

/* Bandeau teaser */
.teaser-wall {
    position: relative;
    margin-top: -8rem;
    padding-top: 8rem;
    text-align: center;
}

.teaser-wall__gradient {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    height: 8rem;
    background: linear-gradient(to bottom, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.85) 50%, rgba(255, 255, 255, 1) 100%);
    pointer-events: none;
}

.teaser-wall__content {
    background: var(--color-bg-light);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-lg);
    padding: var(--spacing-xl) var(--spacing-lg);
    max-width: 32rem;
    margin: 0 auto;
}

.teaser-wall__icon {
    color: var(--color-primary);
    margin-bottom: var(--spacing-sm);
}

.teaser-wall__title {
    font-size: 1.125rem;
    font-weight: 700;
    color: var(--color-text);
    margin: 0 0 var(--spacing-xs);
}

.teaser-wall__description {
    font-size: 0.875rem;
    color: var(--color-text-light);
    margin: 0 0 var(--spacing-lg);
    line-height: 1.5;
}

.teaser-wall__actions {
    display: flex;
    gap: var(--spacing-sm);
    justify-content: center;
    flex-wrap: wrap;
}

/* ══════════════════════════════════════════
   Sidebar TOC — composant transversal
   ══════════════════════════════════════════ */

.article-sidebar__toc {
    margin-bottom: 0;
}

.article-sidebar__section-title {
    font-size: var(--font-size-xs);
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: var(--color-text-light);
    margin-bottom: var(--spacing-sm);
}

.article-toc__list {
    list-style: none;
    padding: 0;
    margin: 0;
    border-left: 2px solid var(--color-border);
}

.article-toc__item {
    list-style: none;
}

.article-toc__item--sub .article-toc__link {
    padding-left: 1.625rem;
}

.article-toc__link {
    display: block;
    padding: 0.3125rem 0 0.3125rem 0.875rem;
    margin-left: -2px;
    font-size: var(--font-size-xs);
    line-height: 1.4;
    color: var(--color-text-light);
    text-decoration: none;
    border-left: 2px solid transparent;
    transition: color 0.15s ease, border-color 0.15s ease;
}

.article-toc__link:hover {
    color: var(--color-text);
}

.article-toc__link--active {
    color: var(--color-primary);
    border-left-color: var(--color-primary);
    font-weight: 600;
}

.article-toc__teaser-hint {
    display: flex;
    align-items: center;
    gap: 0.375rem;
    padding: var(--spacing-sm) 0 0 0.875rem;
    font-size: var(--font-size-xs);
    color: var(--color-text-light);
    font-style: italic;
    opacity: 0.7;
}

/* ══════════════════════════════════════════════════════════════
   Bloc EditorJS : crmTeam — grille de personnes
   ══════════════════════════════════════════════════════════════ */

/* Team : grille propre, sans card, juste photo + nom + rôle.
   Mêmes principes que timeline : pas de bordures, air généreux. */
.tiptap-crm-team {
    margin: var(--spacing-3xl) 0;
}

/* Double-classe pour battre .prose-content h3 (spécificité 0,1,1) */
.tiptap-crm-team .tiptap-crm-team__title {
    font-size: var(--font-size-xl);
    font-weight: 700;
    margin: 0 0 var(--spacing-xl);
    padding: 0 0 var(--spacing-sm);
    border-bottom: 1px solid var(--color-border);
    color: var(--color-text);
}

.tiptap-crm-team__list {
    list-style: none;
    padding: 0;
    margin: 0;
    display: grid;
    gap: var(--spacing-2xl) var(--spacing-lg);
    grid-template-columns: 1fr;
}

@media (min-width: 30em) {
    .tiptap-crm-team--grid .tiptap-crm-team__list {
        grid-template-columns: repeat(auto-fill, minmax(11rem, 1fr));
    }
}

.tiptap-crm-team--list .tiptap-crm-team__list {
    grid-template-columns: 1fr;
    gap: var(--spacing-lg);
}

.tiptap-crm-team__card {
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
    gap: var(--spacing-sm);
    padding: 0;
    background: transparent;
    border: none;
    transition: transform var(--transition-fast);
}

.tiptap-crm-team--list .tiptap-crm-team__card {
    flex-direction: row;
    text-align: left;
    align-items: center;
    gap: var(--spacing-md);
}

.tiptap-crm-team__card:hover {
    transform: translateY(-2px);
}

.tiptap-crm-team__photo {
    width: 6.5rem;
    height: 6.5rem;
    border-radius: 50%;
    object-fit: cover;
    background: var(--color-bg-light);
    border: none;
    flex-shrink: 0;
    transition: box-shadow var(--transition-fast);
}

.tiptap-crm-team__card:hover .tiptap-crm-team__photo {
    box-shadow: 0 6px 20px rgba(12, 21, 32, 0.12);
}

.tiptap-crm-team--list .tiptap-crm-team__photo {
    width: 4rem;
    height: 4rem;
}

.tiptap-crm-team__photo--placeholder {
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: var(--font-size-xl);
    font-weight: 700;
    color: var(--color-text-light);
    letter-spacing: 0.05em;
}

.tiptap-crm-team__body {
    display: flex;
    flex-direction: column;
    gap: 2px;
    min-width: 0;
    flex: 1;
}

.tiptap-crm-team__name {
    margin: 0;
    font-size: 1rem;
    font-weight: 700;
    color: var(--color-text);
    line-height: var(--line-height-tight);
}

.tiptap-crm-team__role {
    margin: 0;
    font-size: var(--font-size-sm);
    font-weight: 500;
    color: var(--color-primary);
}

.tiptap-crm-team__org {
    margin: 0;
    font-size: var(--font-size-xs);
    color: var(--color-text-light);
}

.tiptap-crm-team__bio {
    margin: var(--spacing-xs) 0 0;
    font-size: var(--font-size-sm);
    color: var(--color-text-light);
    line-height: 1.55;
}

/* ══════════════════════════════════════════════════════════════
   Bloc EditorJS : timeline — frise chronologique
   Layout 3 colonnes : année | axe (dot) | contenu
   Pas de bordure sur le contenu — juste un rythme vertical propre.
   ══════════════════════════════════════════════════════════════ */

.tiptap-timeline {
    margin: var(--spacing-3xl) 0;
    max-width: 52rem;
}

.tiptap-timeline__title {
    font-size: var(--font-size-xl);
    font-weight: 700;
    margin: 0 0 var(--spacing-lg);
    padding-bottom: var(--spacing-sm);
    border-bottom: 1px solid var(--color-border);
    color: var(--color-text);
}

.tiptap-timeline__list {
    display: flex;
    flex-direction: column;
    gap: var(--spacing-2xl);
    margin: 0;
    padding: 0;
}

.tiptap-timeline__item {
    display: grid;
    grid-template-columns: 5rem 1.5rem 1fr;
    gap: var(--spacing-lg);
    align-items: start;
}

/* Colonne année à gauche, alignée à droite pour "coller" visuellement au dot.
   Même typographie que le titre pour un alignement vertical parfait. */
.tiptap-timeline__year {
    align-self: start;
    font-size: 1rem;
    font-weight: 700;
    line-height: var(--line-height-tight);
    color: var(--color-primary);
    text-align: right;
    letter-spacing: 0.02em;
    white-space: nowrap;
}

/* Colonne axe : ligne verticale continue + dot en haut de chaque item */
.tiptap-timeline__marker {
    position: relative;
    align-self: stretch;
    display: flex;
    justify-content: center;
    min-height: 2rem;
}

.tiptap-timeline__marker::before {
    content: '';
    position: absolute;
    top: 0;
    bottom: calc(-1 * var(--spacing-2xl));
    left: 50%;
    transform: translateX(-50%);
    width: 2px;
    background: var(--color-border);
}

.tiptap-timeline__item:last-child .tiptap-timeline__marker::before {
    bottom: auto;
    height: 0.625rem;
}

.tiptap-timeline__dot {
    position: relative;
    z-index: 1;
    width: 0.875rem;
    height: 0.875rem;
    margin-top: 0.25rem;
    border-radius: 50%;
    background: var(--color-primary);
    box-shadow: 0 0 0 4px #fff, 0 0 0 6px var(--color-primary-light);
}

/* Colonne contenu : pas de card, juste du texte bien hiérarchisé */
.tiptap-timeline__content {
    display: flex;
    flex-direction: column;
    gap: var(--spacing-xs);
}

/* Sélecteur double-classe pour battre .prose-content h4 (spécificité 0,1,1)
   qui sinon force font-size 1.125rem + margin-top, désalignant le titre
   par rapport à l'année. */
.tiptap-timeline .tiptap-timeline__item-title {
    margin: 0;
    padding: 0;
    font-size: 1rem;
    font-weight: 700;
    color: var(--color-text);
    line-height: var(--line-height-tight);
}

/* Responsive : sur mobile étroit, année au-dessus, axe + contenu en dessous */
@media (max-width: 30em) {
    .tiptap-timeline__item {
        grid-template-columns: 1.5rem 1fr;
        grid-template-areas:
            "year year"
            "marker content";
    }

    .tiptap-timeline__year {
        grid-area: year;
        text-align: left;
        padding-top: 0;
    }

    .tiptap-timeline__marker {
        grid-area: marker;
    }

    .tiptap-timeline__content {
        grid-area: content;
    }
}

.tiptap-timeline__image {
    max-width: 100%;
    height: auto;
    border-radius: var(--radius-md);
    margin: var(--spacing-xs) 0;
}

.tiptap-timeline__text {
    font-size: var(--font-size-base);
    color: var(--color-text-light);
    line-height: 1.6;
    margin: 0;
}

.tiptap-timeline__text p { margin: 0 0 var(--spacing-xs); }
.tiptap-timeline__text p:last-child { margin-bottom: 0; }
.tiptap-timeline__text a { color: var(--color-primary); text-decoration: underline; }
.tiptap-timeline__text a:hover { color: var(--color-primary-dark); }
.tiptap-timeline__text strong { font-weight: 700; color: var(--color-text); }

.tiptap-timeline__link {
    display: inline-flex;
    align-items: center;
    gap: var(--spacing-xs);
    margin-top: var(--spacing-xs);
    align-self: flex-start;
    padding: var(--spacing-xs) var(--spacing-sm);
    border-radius: var(--radius-sm);
    font-size: var(--font-size-sm);
    font-weight: 600;
    color: var(--color-navy);
    text-decoration: none;
    transition: color var(--transition-fast), transform var(--transition-fast);
}

.tiptap-timeline__link:hover {
    color: var(--color-primary);
    transform: translateX(2px);
}
