/* ==========================================================================
   Fiche contributeur — cinq gabarits, un seul balisage.
   Ajoutee le 08/09/2026, refondue le 13/09/2026.

   ---------------------------------------------------------------------------
   CE QUI A CHANGE LE 13/09/2026, ET POURQUOI
   ---------------------------------------------------------------------------
   La version precedente ecrivait son texte secondaire en `rgba(255,255,255,…)`,
   c'est-a-dire qu'elle supposait un fond sombre. Or le fond vient du reglage du
   tenant : sur studio.diva-yoga.com il vaut #FAFAFA. Mesure sur la fiche de
   Maryse Lehoux le 13/09/2026 : resume et titres de section sortaient a
   **1,04:1** — du blanc sur blanc. Le seuil est 4,5:1.

   La lecon, et c'est elle qui gouverne tout ce fichier : **fixer une couleur de
   texte suppose qu'on connait le fond, et sur une plateforme multi-tenant on ne
   le connait pas.** Le texte attenue se derive donc de `currentColor` — la
   couleur de texte heritee — et jamais du blanc. Sur fond clair le texte est
   sombre, sa version attenuee reste sombre ; sur fond sombre, l'inverse. Mesure
   sur les deux extremes : 6,3:1 chez Diva Yoga, 9,2:1 sur le repli sombre.

   Corollaire : la branche `prefers-color-scheme` a disparu. Elle repondait a la
   preference du systeme d'exploitation du VISITEUR, alors que le theme est
   choisi par le CLIENT dans ses reglages — elle ne pouvait pas etre juste. Et
   elle se declenchait sur une classe `.cs-light` qu'aucune vue n'a jamais
   ecrite : c'etait du code mort qui donnait l'illusion que le cas etait traite.

   `currentColor` employe dans la propriete `color` elle-meme resout vers la
   valeur HERITEE (specification CSS Color). Il n'y a donc pas de circularite.
   Un navigateur sans `color-mix()` rend la declaration invalide au calcul, et
   la couleur retombe sur la valeur heritee : le texte est alors pleinement
   contraste au lieu d'etre attenue. La degradation est lisible.

   ---------------------------------------------------------------------------
   PORTEE
   ---------------------------------------------------------------------------
   Tout est prefixe par `.contributor-sheet` ou `.contributor-facts`. Aucune
   regle ne sort de ces deux enveloppes, et aucune ne redeclare `:root`.

   Le choix de gabarit pose `contributor-tpl-<cle>` sur les deux enveloppes ;
   ce qui suit ne fait que redistribuer les memes blocs. Aucun contenu n'est
   masque par un gabarit : passer de l'un a l'autre ne fait jamais disparaitre
   une information, ce qui est la promesse faite dans l'ecran d'edition.
   ========================================================================== */

.contributor-sheet,
.contributor-facts {
    /* --- Couleurs : toutes reprises au theme du tenant, aucune en dur. ----- */
    --cs-accent: var(--primary-color, #E05C70);
    --cs-accent-strong: var(--primary-enhanced-color, #ab2546);
    --cs-title: var(--couleur-titre, var(--primary-color, #E05C70));

    /* Deux crans d'attenuation, derives du texte herite (voir l'en-tete). */
    --cs-muted: color-mix(in srgb, currentColor 72%, transparent);
    --cs-faint: color-mix(in srgb, currentColor 66%, transparent);

    /* Filets et surfaces : le token du tenant quand il existe, sinon une
       teinte du texte courant — qui reste visible sur n'importe quel fond. */
    --cs-line: var(--card-border-color, var(--border-color, color-mix(in srgb, currentColor 22%, transparent)));
    --cs-surface: color-mix(in srgb, currentColor 4%, transparent);

    --cs-font-title: var(--font-titles, inherit);
    --cs-font-body: var(--font-paragraphs, inherit);

    /* --- Formes et rythme : des regles de composition, pas des choix de
       marque. Elles ne sont donc pas exposees au reglage du tenant. -------- */
    --cs-radius: 14px;
    --cs-gap: 28px;
}

.contributor-sheet {
    width: 100%;
    display: flex;
    flex-direction: column;
    gap: var(--cs-gap);
    padding: 8px 0 4px;
    font-family: var(--cs-font-body);
}

/* ------------------------------------------------------------------ En-tete */

.contributor-sheet .cs-head {
    display: grid;
    grid-template-columns: minmax(180px, 300px) minmax(0, 1fr);
    gap: var(--cs-gap);
    align-items: start;
}

.contributor-sheet .cs-portrait img {
    width: 100%;
    height: auto;
    max-width: 300px;
    border-radius: var(--cs-radius);
    display: block;
    object-fit: cover;
}

.contributor-sheet .cs-identity { min-width: 0; }

/* Le nom est passe de `h4` a `h1` le 08/09/2026 : la page n'avait aucun titre
   de niveau 1. La taille est fixee ici pour que le changement de niveau ne
   change pas l'apparence — c'est la hierarchie du document qui evolue. */
.contributor-sheet .cs-name {
    font-family: var(--cs-font-title);
    font-size: clamp(26px, 3.4vw, 38px);
    line-height: 1.12;
    margin: 0 0 6px;
    font-weight: 700;
}

.contributor-sheet .cs-job {
    color: var(--cs-accent);
    font-size: 16px;
    font-weight: 600;
    letter-spacing: .01em;
    margin: 0 0 12px;
}

.contributor-sheet .cs-summary {
    font-size: 17px;
    line-height: 1.6;
    color: var(--cs-muted);
    margin: 0 0 16px;
    max-width: 62ch;
}

/* LA CITATION EST UNE EXERGUE, et sa taille n'est pas une coquetterie.

   Sebastien a demande le 13/09/2026 qu'elle sorte en `--primary-color`. Mesure :
   `#E05C70` sur le fond `#FAFAFA` de Diva Yoga ne donne que **3,39:1**, donc sous
   le seuil de 4,5:1 d'un texte courant. Le meme accent sur le fond sombre de
   SymbioPlay donne 4,74:1, qui passe — mais on ne livre pas une regle qui n'est
   juste que sur un tenant.

   La sortie n'est pas de renoncer a la couleur : c'est d'en faire un GRAND texte.
   WCAG 1.4.3 abaisse le seuil a 3:1 des 24px en graisse normale, et 3,39:1 y
   satisfait sur les deux tenants. Une citation mise en avant a de toute facon
   vocation a etre grande : la contrainte d'accessibilite et l'intention
   typographique disent ici la meme chose.

   **Ne pas descendre `font-size` sous 24px** sans changer la couleur : en dessous,
   la regle redevient non conforme sur fond clair. */
/* Elle vit desormais DANS `.cs-lead` (voir la vue). `.cs-lead` est un bloc, pas le
   conteneur flex de la fiche : la gouttiere de 28 px qui la separait de l'en-tete
   n'est plus donnee par le `gap`, elle est rendue ici. Sans cette marge, la
   citation se collerait au portrait sur les quatre gabarits sans bandeau. */
.contributor-sheet .cs-quote {
    border-left: 3px solid var(--cs-accent);
    padding: 2px 0 2px 20px;
    margin: var(--cs-gap) 0 0;
    max-width: 72ch;
}

.contributor-sheet .cs-quote p {
    font-family: var(--cs-font-title);
    font-style: italic;
    font-size: clamp(24px, 2.2vw, 28px);
    line-height: 1.35;
    margin: 0;
    color: var(--cs-accent);
    text-wrap: balance;
}

.contributor-sheet .cs-updated {
    font-size: 13px;
    color: var(--cs-faint);
    margin: 0;
}

/* ------------------------------------------------- Titres de section commune */

/* Ils etaient peints en `--cs-faint` a 40 % de blanc : invisibles sur fond
   clair. Ils prennent maintenant la couleur de titre du tenant, qui est faite
   pour etre lue sur son fond. */
.contributor-sheet .cs-section-title,
.contributor-sheet .cs-bio h2,
.contributor-sheet .cs-embed-title,
.contributor-facts h2 {
    font-family: var(--cs-font-title);
    font-size: 15px;
    font-weight: 700;
    letter-spacing: .08em;
    text-transform: uppercase;
    color: var(--cs-title);
    margin: 0 0 14px;
}

/* ---------------------------------------------------------------- Biographie */

.contributor-sheet .cs-bio-body {
    font-size: 16px;
    line-height: 1.7;
    max-width: 72ch;
    color: var(--cs-muted);
}

.contributor-sheet .cs-bio-body p { margin: 0 0 14px; }
.contributor-sheet .cs-bio-body p:last-child { margin-bottom: 0; }
.contributor-sheet .cs-bio-body ul,
.contributor-sheet .cs-bio-body ol { margin: 0 0 14px; padding-left: 22px; }
.contributor-sheet .cs-bio-body li { margin-bottom: 6px; }
.contributor-sheet .cs-bio-body a { color: var(--cs-accent); }

/* Enveloppe inerte par defaut. Elle ne prend vie que pour « vitrine » avec video,
   plus bas : partout ailleurs, la biographie se rend comme si elle n'existait pas. */
.contributor-sheet .cs-bio-duo { display: block; }

/* Pleine largeur et justifiee sur « classique » et « vitrine » (demande de
   Sebastien du 13/09/2026). Les trois autres gardent leur alignement a gauche :
   « portrait » et « presentation » lisent en colonne etroite, ou le justifie
   creuse des rivieres, et « magazine » est deja en deux colonnes de texte.
   `hyphens: auto` attenue ces rivieres la ou le justifie s'applique. */
/* MESURE DU 13/09/2026, ET C'EST ELLE QUI A TRANCHE : sur une fenetre de 1024 px la
   ligne faisait **109 signes**, la ou l'oeil en suit 65 a 75 sans perdre le debut de
   la ligne suivante. Le `justify` y ajoutait des rivieres et `hyphens: auto` coupait
   les mots (« ex-ploite », « me-thodes »), particulierement visibles sur telephone.

   La colonne est donc bornee et le texte aligne a gauche. `max-width` en `ch` suit la
   taille de police du tenant : si le client grossit son texte, la colonne grossit avec
   lui et le compte de signes reste le meme. */
.contributor-tpl-classique .cs-bio-body,
.contributor-tpl-vitrine .cs-bio-body,
.contributor-tpl-profil .cs-bio-body {
    max-width: 68ch;
    text-align: left;
    hyphens: none;
}

/* La video laterale de « vitrine ». Le `:has()` est ce qui evite d'avoir a poser
   une classe depuis la vue : sans video, aucun `.cs-bio-video` n'est ecrit, la
   regle ne s'applique pas, et la biographie reprend toute la largeur. */
.contributor-tpl-vitrine .cs-bio-duo:has(.cs-bio-video) {
    display: grid;
    grid-template-columns: minmax(0, 1.55fr) minmax(260px, 1fr);
    gap: var(--cs-gap);
    align-items: start;
}

.contributor-sheet .cs-bio-video {
    position: relative;
    width: 100%;
    aspect-ratio: 16 / 9;
    border-radius: var(--cs-radius);
    overflow: hidden;
    background: var(--cs-surface);
    border: 1px solid var(--cs-line);
}

.contributor-sheet .cs-bio-video iframe {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    border: 0;
}

/* ------------------------------------------------------------- Section libre */

.contributor-sheet .cs-custom {
    border-top: 1px solid var(--cs-line);
    padding-top: var(--cs-gap);
}

/* Une section construite dans l'editeur visuel peut porter une image large.
   Sans ce garde-fou, elle deborderait de la page sur petit ecran. */
.contributor-sheet .cs-custom img,
.contributor-sheet .cs-custom video { max-width: 100%; height: auto; }
.contributor-sheet .cs-custom table { width: 100%; }

/* ------------------------------------------------------------- Integrations */

.contributor-sheet .cs-embeds {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
    gap: var(--cs-gap);
}

.contributor-sheet .cs-embed {
    background: var(--cs-surface);
    border: 1px solid var(--cs-line);
    border-radius: var(--cs-radius);
    padding: 18px;
    min-width: 0;
}

/* Rapport 16/9 tenu par le conteneur : sans lui, l'`iframe` prend la hauteur
   par defaut de 150px et la video s'affiche dans un timbre-poste. */
.contributor-sheet .cs-embed-frame {
    position: relative;
    width: 100%;
    aspect-ratio: 16 / 9;
    border-radius: 10px;
    overflow: hidden;
    background: var(--cs-surface);
}

/* Un agenda est haut, pas large : le 16/9 le tronquerait. */
.contributor-sheet .cs-embed-agenda .cs-embed-frame { aspect-ratio: 3 / 4; }

.contributor-sheet .cs-embed-frame iframe {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    border: 0;
}

.contributor-sheet .cs-embed-link {
    margin: 12px 0 0;
    font-size: 14px;
}

.contributor-sheet .cs-embed-link a { color: var(--cs-accent); }

/* ------------------------------------------------- Catalogue : cours, series */

/* Les deux listes etaient un carrousel Owl au vieux balisage `.video-img`. Elles
   sont passees le 13/09/2026 a la carte `.px-card`, d'abord en grille, puis —
   meme jour, sur demande de Sebastien — au CARROUSEL de la page d'accueil, pour
   que la fiche ressemble au catalogue d'ou l'on vient.

   Il n'y a donc plus rien a styler ici : le rail `px-rail-wrap` et le carrousel
   `px-owl` sont habilles par `pages/home/sections/_styles.blade.php`, que
   `details.blade.php` inclut. Les reglages responsive vivent dans
   `partials/catalogue.blade.php`, recopies de l'accueil.

   Corollaire : les jetons `--cs-card-min` ont disparu du bloc de tete. La
   densite du catalogue ne differencie plus les gabarits — c'est voulu, puisque
   les cinq doivent ressembler a l'accueil. Ce sont l'en-tete et la biographie
   qui les distinguent. */
.contributor-sheet .cs-catalogue { min-width: 0; }

/* ============================================================= Les gabarits ==
   Chaque gabarit ne redefinit que ce qui le distingue. Ce qui n'est pas ecrit
   ici est volontairement commun.
   ========================================================================== */

/* --- Portrait : la photo commande, le texte se lit en colonne etroite. ----- */

.contributor-tpl-portrait .cs-head {
    grid-template-columns: minmax(240px, 420px) minmax(0, 1fr);
    align-items: center;
}

.contributor-tpl-portrait .cs-portrait img {
    max-width: 420px;
    aspect-ratio: 4 / 5;
}

.contributor-tpl-portrait .cs-name { font-size: clamp(30px, 4.2vw, 46px); }

/* La lecture passe a une colonne unique et centree ; les grilles de catalogue,
   elles, gardent la pleine largeur — une grille etranglee a 60ch n'aurait plus
   de raison d'etre une grille. */
.contributor-tpl-portrait .cs-bio,
.contributor-tpl-portrait .cs-custom,
.contributor-tpl-portrait .cs-embeds-group {
    max-width: 68ch;
    margin-left: auto;
    margin-right: auto;
    width: 100%;
}

.contributor-tpl-portrait .cs-bio-body { max-width: none; }

/* --- Magazine : bandeau large, identite SUPERPOSEE, deux colonnes. --------- */

/* Jusqu'au 13/09/2026 le commentaire annoncait une identite superposee, mais la
   posait dans un bloc SOUS l'image. Elle l'est reellement maintenant, avec un
   voile degrade qui garantit la lisibilite du nom quelle que soit la photo. */
.contributor-tpl-magazine .cs-head {
    grid-template-columns: 1fr;
    position: relative;
    border-radius: var(--cs-radius);
    overflow: hidden;
    background: var(--cs-surface);
    gap: 0;
}

.contributor-tpl-magazine .cs-portrait img {
    max-width: none;
    width: 100%;
    max-height: 380px;
    object-position: center 22%;
    border-radius: 0;
}

.contributor-tpl-magazine .cs-identity {
    position: absolute;
    inset: auto 0 0 0;
    padding: 64px 26px 22px;
    /* VOILE NOIR ET TEXTE BLANC, EN DUR, ET C'EST VOULU.
       Ce bloc n'est pas pose sur une surface du theme : il est pose sur une
       PHOTOGRAPHIE. Le fond n'est donc pas un token, c'est l'image du
       contributeur, et personne ne sait de quelle couleur elle est.

       J'avais d'abord bati ce voile sur `var(--detail-bg)` en me disant qu'un
       noir en dur trancherait sur un theme clair. Deux erreurs dans cette
       phrase. D'une part le voile tombait alors clair chez un tenant clair,
       donc illisible sur une photo claire. D'autre part le texte, lui,
       heritait de `--primary-text-color` : constate en preproduction le
       13/09/2026, un texte #1d2025 sur un voile #0d0620, soit du sombre sur
       du sombre — le nom du contributeur avait disparu.

       Un degrade sombre plus un texte clair est le seul couple qui tienne sur
       une image quelconque. La fonction garde `--cs-accent`, qui donne 5,6:1
       sur ce voile. */
    background: linear-gradient(
        to top,
        rgba(0, 0, 0, .92) 12%,
        rgba(0, 0, 0, .62) 52%,
        rgba(0, 0, 0, 0)
    );
    color: #fff;
}

.contributor-tpl-magazine .cs-name { color: #fff; }

.contributor-tpl-magazine .cs-name { font-size: clamp(28px, 4vw, 44px); }

/* Seul le RESUME quitte le bandeau : sur une photo, au-dela de deux lignes, plus
   rien n'est lisible. Il ne se perd pas pour autant — `resume()` rend le debut de
   la biographie quand aucun resume n'est saisi, et la biographie est affichee
   juste dessous, en entier.

   La citation, elle, est sortie du bloc d'identite le 13/09/2026 : elle est
   devenue une exergue pleine largeur, commune aux cinq gabarits. Et la date de
   mise a jour reste visible ici, sur le bandeau (demande de Sebastien : elle doit
   figurer quelque part dans TOUS les gabarits, pas seulement quelques-uns). */
.contributor-tpl-magazine .cs-summary { display: none; }

.contributor-tpl-magazine .cs-bio-body {
    max-width: none;
    columns: 2;
    column-gap: 42px;
}

/* Une colonne coupee au milieu d'une liste est illisible : on l'en empeche. */
.contributor-tpl-magazine .cs-bio-body ul,
.contributor-tpl-magazine .cs-bio-body ol { break-inside: avoid; }

@media (max-width: 991.98px) {
    .contributor-tpl-magazine .cs-bio-body { columns: 1; }
}

/* --- Vitrine : le catalogue d'abord, la biographie ensuite. ---------------- */

/* L'ordre des blocs est pose dans la vue, pas ici : c'est un ordre de lecture
   et de document, il doit exister aussi pour qui ne recoit pas le CSS. */
/* LE BANDEAU. C'est `.cs-lead` qui le porte, et non `.cs-head` : la citation est a
   l'interieur de l'enveloppe, pas de l'en-tete, et une enveloppe ne se traverse pas
   en CSS.

   La couleur de fond est celle du client (`--primary-enhanced-color`), jamais une
   valeur ecrite ici. La couleur du TEXTE est calculee en PHP a partir de ce fond et
   servie dans `--band-text-color` : c'est la seule facon de garantir la lisibilite
   sans supposer que le client a choisi un fond sombre. Le repli blanc ne sert que si
   la variable manque. */
.contributor-tpl-vitrine .cs-lead,
.contributor-tpl-profil .cs-lead {
    background: var(--cs-accent-strong);
    color: var(--band-text-color, #fff);
    border-radius: var(--cs-radius);
    padding: 20px 24px;
}

.contributor-tpl-vitrine .cs-head {
    /* Trois colonnes : portrait, identite et mesures, bouton. Le compteur d'origine
       n'est plus rendu sur ce gabarit, les pastilles le remplacent. */
    grid-template-columns: auto minmax(0, 1fr) auto;
    align-items: center;
    gap: 20px;
}

/* Dans le bandeau, tout le texte prend la couleur calculee : le nom et les titres ont
   sinon leur propre jeton, prevu pour le fond de contenu et non pour celui-ci. */
.contributor-tpl-vitrine .cs-name,
.contributor-tpl-profil .cs-name,
.contributor-tpl-vitrine .cs-job,
.contributor-tpl-profil .cs-job { color: inherit; }

.contributor-tpl-vitrine .cs-lead .cs-quote,
.contributor-tpl-profil .cs-lead .cs-quote {
    border-left: 0;
    padding: 0;
    margin: 14px 0 0;
    max-width: none;
    opacity: .92;
}

.contributor-tpl-vitrine .cs-lead .cs-quote p,
.contributor-tpl-profil .cs-lead .cs-quote p {
    color: inherit;
    font-size: clamp(16px, 1.5vw, 19px);
}

/* --- Les mesures, en pastilles. ------------------------------------------- */

.contributor-sheet .cs-stats {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    list-style: none;
    margin: 10px 0 0;
    padding: 0;
}

.contributor-sheet .cs-stat {
    display: inline-flex;
    align-items: baseline;
    gap: 5px;
    font-size: 13px;
    line-height: 1.2;
    padding: 5px 12px;
    border-radius: 999px;
    /* Teintes derivees du texte du bandeau : elles suivent la couleur calculee et
       tiennent donc sur un fond clair comme sur un fond sombre. */
    background: color-mix(in srgb, currentColor 14%, transparent);
    border: 1px solid color-mix(in srgb, currentColor 26%, transparent);
    white-space: nowrap;
}

.contributor-sheet .cs-stat b {
    font-family: var(--cs-font-title);
    font-size: 16px;
    font-weight: 800;
}

.contributor-sheet .cs-star { font-size: 12px; }
.contributor-sheet .cs-stat-sep { opacity: .6; }
.contributor-sheet .cs-stat-date { opacity: .85; }

.contributor-tpl-vitrine .cs-portrait img {
    width: 84px;
    height: 84px;
    max-width: none;
    border-radius: 50%;
    object-fit: cover;
    border: 3px solid color-mix(in srgb, currentColor 55%, transparent);
}

.contributor-tpl-vitrine .cs-name { font-size: clamp(21px, 2.4vw, 27px); margin-bottom: 2px; }
.contributor-tpl-vitrine .cs-job { margin-bottom: 0; }

/* Le bandeau doit rester un bandeau : seul le resume, qui peut faire trois lignes,
   en sort. La citation n'y est plus depuis qu'elle est devenue une exergue pleine
   largeur, et la date y reste — elle doit figurer dans tous les gabarits. */
.contributor-tpl-vitrine .cs-summary { display: none; }

.contributor-tpl-vitrine .cs-updated {
    margin-top: 4px;
}

/* --- Profil collant : l'identite reste a l'ecran pendant qu'on fouille. ----- */

/* Ce gabarit repond a un cas precis : un contributeur au catalogue long. Sur la
   fiche la plus fournie de Diva Yoga, atteindre le dernier cours demandait dix-huit
   clics de carrousel, sans jamais savoir ou l'on en etait. Le rail fige l'identite
   et le bouton d'entree pendant que la colonne de droite defile.

   L'enveloppe passe en grille : c'est la seule maniere d'obtenir une colonne qui
   s'etend sur toute la hauteur du contenu, condition pour que `position: sticky`
   ait de quoi coller. Tous les autres blocs vont en colonne 2, dans leur ordre de
   document — l'ordre de lecture reste celui de la vue. */
.contributor-tpl-profil {
    display: grid;
    grid-template-columns: minmax(230px, 300px) minmax(0, 1fr);
    align-items: start;
    gap: var(--cs-gap);
}

.contributor-tpl-profil > * { grid-column: 2; }

.contributor-tpl-profil > .cs-lead {
    grid-column: 1;
    grid-row: 1 / -1;
    position: sticky;
    /* Un cran sous le haut de la fenetre. La valeur est ici et pas dans une regle
       plus bas pour qu'on sache ou la reprendre si un tenant pose un menu fixe. */
    top: 24px;
}

/* Le rail est etroit : l'en-tete s'y empile au lieu de se poser en deux colonnes. */
.contributor-tpl-profil .cs-head {
    grid-template-columns: minmax(0, 1fr);
    gap: 14px;
}

.contributor-tpl-profil .cs-portrait img {
    width: 100%;
    max-width: none;
    aspect-ratio: 1 / 1;
}

.contributor-tpl-profil .cs-name { font-size: clamp(22px, 2.2vw, 28px); }

/* Meme raison que pour « vitrine » : le resume repete les premieres lignes de la
   biographie, qui est juste a cote. Dans une colonne de 300 px il ferait dix lignes. */
.contributor-tpl-profil .cs-summary { display: none; }


/* --- Le bouton d'entree dans le catalogue. --------------------------------- */

/* Il est **en trait, pas en aplat**, et c'est un choix, pas un oubli. Un bouton
   plein impose une couleur de texte sur une couleur de fond ; les deux viennent du
   reglage du tenant, que rien n'oblige a s'accorder — c'est exactement la panne
   mesuree le 13/09/2026 sur cette meme fiche (1,21:1). Un bouton en trait herite du
   texte de la page : il est lisible sur n'importe quel fond, par construction. */
.contributor-sheet .cs-cta {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 6px;
    min-width: 0;
}

.contributor-sheet .cs-cta-btn {
    display: inline-block;
    padding: 9px 18px;
    border: 1px solid currentColor;
    border-radius: 999px;
    font-family: var(--cs-font-title);
    font-weight: 700;
    font-size: 14px;
    line-height: 1.2;
    color: inherit;
    text-decoration: none;
    background: transparent;
    transition: background-color .18s ease;
}

.contributor-sheet .cs-cta-btn:hover,
.contributor-sheet .cs-cta-btn:focus-visible {
    /* 4 % du texte courant : une teinte qui se voit sur un fond clair comme sur un
       fond sombre, sans jamais supposer lequel. */
    background-color: var(--cs-surface);
    color: inherit;
    text-decoration: none;
}

.contributor-sheet .cs-cta-hint {
    margin: 0;
    font-size: 12px;
    line-height: 1.35;
    color: var(--cs-muted);
    max-width: 220px;
}

/* Dans le bandeau, le bouton est a droite, et il est PLEIN : l'aplat prend la couleur
   du texte calcule et le libelle reprend celle du fond. Les deux viennent du meme
   calcul, donc le contraste est le meme que celui du bandeau, quel que soit le client
   — c'est le seul bouton plein que cette feuille se permet. */
.contributor-tpl-vitrine .cs-cta { align-items: flex-end; text-align: right; }
.contributor-tpl-vitrine .cs-cta-hint,
.contributor-tpl-profil .cs-cta-hint {
    max-width: 200px;
    color: inherit;
    /* .88 et pas .8 : mesure au canvas sur le fond compose, le titre du cours tombait a
       4,85:1 a 12 px — au-dessus du seuil, mais sans marge. A .88 il remonte a 5,6. */
    opacity: .88;
}

.contributor-tpl-vitrine .cs-cta-btn,
.contributor-tpl-profil .cs-cta-btn {
    background: var(--band-text-color, #fff);
    color: var(--cs-accent-strong);
    border-color: transparent;
}

.contributor-tpl-vitrine .cs-cta-btn:hover,
.contributor-tpl-vitrine .cs-cta-btn:focus-visible,
.contributor-tpl-profil .cs-cta-btn:hover,
.contributor-tpl-profil .cs-cta-btn:focus-visible {
    background: color-mix(in srgb, var(--band-text-color, #fff) 88%, transparent);
    color: var(--cs-accent-strong);
}

.contributor-tpl-profil .cs-cta { align-items: stretch; }
.contributor-tpl-profil .cs-cta-btn { justify-content: center; }

/* --- Recherche et tri du catalogue. ---------------------------------------- */

/* La barre reste `hidden` tant que le script ne l'a pas prise en charge : un champ
   de recherche qui ne cherche rien vaut moins que pas de champ. */
.cs-catalogue .cs-toolbar {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 10px;
    margin: 0 0 16px;
}

/* Le champ prend la place disponible, mais pas toute : sans plafond il ecrasait le tri,
   dont le libelle le plus long (« Les plus recents ») sortait coupe et sans sa fleche.
   Constate en preproduction le 14/09/2026 sur une fenetre de 1457 px. */
.cs-catalogue .cs-search {
    position: relative;
    flex: 1 1 220px;
    min-width: 170px;
    max-width: 420px;
}

.cs-catalogue .cs-search-input {
    width: 100%;
    padding: 8px 34px;
    border: 1px solid var(--cs-line);
    border-radius: 999px;
    background: transparent;
    color: inherit;
    font: inherit;
    font-size: 14px;
}

.cs-catalogue .cs-search-input::placeholder { color: var(--cs-faint); opacity: 1; }

.cs-catalogue .cs-search-icon {
    position: absolute;
    left: 13px;
    top: 50%;
    transform: translateY(-50%);
    font-size: 13px;
    color: var(--cs-faint);
    pointer-events: none;
}

.cs-catalogue .cs-search-clear {
    position: absolute;
    right: 5px;
    top: 50%;
    transform: translateY(-50%);
    border: 0;
    background: transparent;
    color: var(--cs-muted);
    font-size: 14px;
    line-height: 1;
    padding: 6px 9px;
    border-radius: 50%;
    cursor: pointer;
}

.cs-catalogue .cs-search-clear:hover { background-color: var(--cs-surface); }

/* Le `select` ne recoit NI couleur de texte NI couleur de fond, deliberement. Le
   navigateur peint la liste deroulante avec les couleurs calculees du champ : un
   fond transparent associe a un texte clair donne, sur plusieurs navigateurs, du
   clair sur clair dans la liste ouverte. Les couleurs du systeme sont toujours
   lisibles ; seules la forme et la taille sont reprises ici. */
.cs-catalogue .cs-sort {
    /* Ni compression ni etirement : la liste se dimensionne sur son libelle le plus long. */
    flex: 0 0 auto;
    width: auto;
    padding: 8px 12px;
    border: 1px solid var(--cs-line);
    border-radius: 999px;
    font: inherit;
    font-size: 14px;
    max-width: 100%;
}

/* Bootstrap pose `outline: 0` sur le focus de plusieurs commandes. Sans la regle
   ci-dessous, la barre serait traversable au clavier SANS que rien ne se voie : on
   ne peut pas ajouter des commandes a une page et laisser le focus invisible. */
.cs-catalogue .cs-search-input:focus-visible,
.cs-catalogue .cs-search-clear:focus-visible,
.cs-catalogue .cs-sort:focus-visible {
    outline: 2px solid currentColor;
    outline-offset: 2px;
}

.cs-catalogue .cs-results-count {
    margin: 0;
    font-size: 13px;
    color: var(--cs-muted);
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

.cs-catalogue .cs-no-result {
    margin: 18px 0 0;
    font-size: 14px;
    color: var(--cs-muted);
}

/* Etiquette reservee aux lecteurs d'ecran : le champ et le tri ont un `label`
   reel, il n'est simplement pas peint. */
.contributor-sheet .cs-visually-hidden {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
    border: 0;
}

/* --- La grille de resultats. ----------------------------------------------- */

/* Le carrousel est detruit des qu'un filtre ou un tri est actif (voir l'en-tete de
   `contributor-catalogue.js`) : le meme conteneur devient alors une grille. Masquer
   une carte a l'interieur d'Owl laisserait un trou de la largeur d'une carte. */
.cs-catalogue .px-owl.cs-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
    gap: 14px;
}

.cs-catalogue[data-cs-catalogue="series"] .px-owl.cs-grid {
    grid-template-columns: repeat(auto-fill, minmax(230px, 1fr));
}

.cs-catalogue .px-owl.cs-grid > [data-cs-item] { width: auto; }

/* Une carte filtree est masquee par l'attribut `hidden`. Il ne suffit PAS : le socle des
   cartes declare `.single-video { display: block }`, une regle d'auteur qui bat la feuille
   du navigateur. Sans la ligne ci-dessous, la recherche reordonnerait les cartes sans
   jamais en cacher une seule — mesure faite au banc le 14/09/2026, avant tout push. La
   specificite suffit, aucun `!important` n'est necessaire. */
.cs-catalogue .px-owl.cs-grid > [data-cs-item][hidden] { display: none; }

/* --- Presentation : la video de presentation en tete de page. -------------- */

/* `.cs-lead` enveloppe TOUJOURS l'en-tete, quel que soit le gabarit : c'est ce qui
   evite d'ecrire deux fois le balisage de l'en-tete dans la vue, une fois avec la
   video et une fois sans. Par defaut elle ne fait rien de plus qu'un bloc — la
   fiche se rend exactement comme si l'en-tete etait la directement. */
.contributor-sheet .cs-lead { display: block; }

/* Elle ne devient la mise en page a deux colonnes que pour le gabarit
   `presentation`, ET seulement si une video a reellement ete rendue. */
.contributor-tpl-presentation .cs-lead:has(.cs-lead-frame) {
    display: grid;
    grid-template-columns: minmax(0, 1.55fr) minmax(260px, 1fr);
    gap: var(--cs-gap);
    align-items: stretch;
}

.contributor-sheet .cs-lead-frame {
    position: relative;
    width: 100%;
    aspect-ratio: 16 / 9;
    border-radius: var(--cs-radius);
    overflow: hidden;
    background: var(--cs-surface);
    border: 1px solid var(--cs-line);
}

.contributor-sheet .cs-lead-frame iframe {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    border: 0;
}

/* Quand la video mene, l'identite devient une carte de cote : portrait en
   medaillon, nom, fonction, resume. */
.contributor-tpl-presentation .cs-head {
    grid-template-columns: 1fr;
    gap: 14px;
    align-content: center;
    background: var(--cs-surface);
    border: 1px solid var(--cs-line);
    border-radius: var(--cs-radius);
    padding: 20px;
}

.contributor-tpl-presentation .cs-portrait img {
    width: 72px;
    height: 72px;
    max-width: none;
    border-radius: 50%;
    object-fit: cover;
}

.contributor-tpl-presentation .cs-name { font-size: clamp(21px, 2.4vw, 28px); }

.contributor-tpl-presentation .cs-bio,
.contributor-tpl-presentation .cs-custom {
    max-width: 68ch;
}

/* Le gabarit `presentation` sans video retombe sur la mise en page classique :
   la vue ne rend alors aucun `.cs-lead`, et ce selecteur remet le portrait a sa
   taille normale. Sans ce repli, la fiche s'ouvrirait sur une carte d'identite
   minuscule et vide de sens. */
.contributor-tpl-presentation:not(:has(.cs-lead-frame)) .cs-head {
    grid-template-columns: minmax(180px, 300px) minmax(0, 1fr);
    background: none;
    border: 0;
    padding: 0;
    gap: var(--cs-gap);
}

.contributor-tpl-presentation:not(:has(.cs-lead-frame)) .cs-portrait img {
    width: 100%;
    height: auto;
    max-width: 300px;
    border-radius: var(--cs-radius);
}

.contributor-tpl-presentation:not(:has(.cs-lead-frame)) .cs-name {
    font-size: clamp(26px, 3.4vw, 38px);
}

/* ========================================= Specialites et coordonnees ======= */

.contributor-facts {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
    gap: var(--cs-gap);
    margin-top: 36px;
    padding-top: 28px;
    border-top: 1px solid var(--cs-line);
    font-family: var(--cs-font-body);
}

.contributor-facts .cf-block { min-width: 0; }

.contributor-facts .cf-subtitle {
    font-family: var(--cs-font-title);
    font-size: 13px;
    font-weight: 700;
    letter-spacing: .06em;
    text-transform: uppercase;
    color: var(--cs-title);
    margin: 20px 0 10px;
}

/* Les specialites sont des etiquettes, pas des puces : ce sont des termes
   courts qu'on parcourt du regard, et une liste verticale les etirerait sur
   dix lignes. */
.contributor-facts .cf-tags {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
}

.contributor-facts .cf-tag {
    border: 1px solid var(--cs-line);
    background: var(--cs-surface);
    border-radius: 999px;
    padding: 6px 14px;
    font-size: 14px;
    line-height: 1.3;
    color: var(--cs-muted);
}

.contributor-facts .cf-list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 10px;
}

.contributor-facts .cf-list li {
    display: flex;
    align-items: baseline;
    gap: 10px;
    font-size: 15px;
    overflow-wrap: anywhere;
    color: var(--cs-muted);
}

.contributor-facts .cf-list a { color: var(--cs-accent); }

.contributor-facts .cf-icon { color: var(--cs-accent); width: 18px; flex: none; }

.contributor-facts .cf-links {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
}

.contributor-facts .cf-links a {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    border: 1px solid var(--cs-line);
    border-radius: 999px;
    padding: 7px 15px;
    font-size: 14px;
    color: var(--cs-muted);
    /* 40px de cible : une pastille de 30px se rate au doigt. Elle passe a 44px
       des qu'on est sur un pointeur grossier, plus bas. */
    min-height: 40px;
    transition: border-color .2s ease-out, background-color .2s ease-out, color .2s ease-out;
}

.contributor-facts .cf-links a:hover,
.contributor-facts .cf-links a:focus-visible {
    border-color: var(--cs-accent);
    color: var(--cs-accent);
    background: var(--cs-surface);
    text-decoration: none;
}

.contributor-facts .cf-empty {
    color: var(--cs-faint);
    font-style: italic;
    margin: 0;
}

/* Le gabarit portrait centre aussi ses deux colonnes de bas de page, pour ne
   pas rompre l'axe central qu'il vient d'installer. */
.contributor-tpl-portrait.contributor-facts { text-align: center; }
.contributor-tpl-portrait.contributor-facts .cf-tags,
.contributor-tpl-portrait.contributor-facts .cf-links { justify-content: center; }
.contributor-tpl-portrait.contributor-facts .cf-list li { justify-content: center; }

/* ================================================================ Ecrans ==== */

@media (pointer: coarse) {
    .contributor-facts .cf-links a { min-height: 44px; }

    /* Mesure au banc le 14/09/2026 : le bouton sortait a 37 px de haut, le champ et le
       tri a 36. Sous le doigt, le seuil est 44. `inline-flex` sert uniquement a centrer
       le libelle une fois la hauteur imposee. */
    .contributor-sheet .cs-cta-btn {
        display: inline-flex;
        align-items: center;
        min-height: 44px;
    }

    .cs-catalogue .cs-search-input,
    .cs-catalogue .cs-sort { min-height: 44px; }

    .cs-catalogue .cs-search-clear { min-width: 36px; min-height: 36px; }
}

@media (max-width: 767.98px) {
    .contributor-sheet .cs-head,
    .contributor-tpl-portrait .cs-head,
    .contributor-tpl-presentation:not(:has(.cs-lead-frame)) .cs-head {
        grid-template-columns: 1fr;
    }

    .contributor-sheet .cs-portrait img,
    .contributor-tpl-portrait .cs-portrait img,
    .contributor-tpl-presentation:not(:has(.cs-lead-frame)) .cs-portrait img {
        max-width: 220px;
        aspect-ratio: 1 / 1;
    }

    /* Le bandeau vitrine se replie en deux lignes plutot que d'ecraser le nom. */
    .contributor-tpl-vitrine .cs-head { grid-template-columns: auto minmax(0, 1fr); }
    .contributor-tpl-vitrine .cs-portrait img,
    .contributor-tpl-presentation .cs-portrait img { aspect-ratio: 1 / 1; }

    .contributor-sheet .cs-lead,
    .contributor-tpl-vitrine .cs-bio-duo:has(.cs-bio-video) { grid-template-columns: 1fr; }

    .contributor-sheet { --cs-gap: 20px; }

    /* Le bandeau vitrine descend le bouton sous le compteur plutot que d'ecraser
       le nom sur quatre colonnes. */
    .contributor-tpl-vitrine .cs-cta {
        grid-column: 1 / -1;
        align-items: flex-start;
        text-align: left;
    }
}

/* Le rail collant n'a plus de place a cote : il redevient un bloc ordinaire, en
   tete de page. Le seuil est celui du gabarit a deux colonnes, pas celui du
   telephone : a 900 px la colonne de droite ne ferait deja plus que 600 px. */
@media (max-width: 991.98px) {
    .contributor-tpl-profil {
        display: flex;
        flex-direction: column;
    }

    .contributor-tpl-profil > *,
    .contributor-tpl-profil > .cs-lead {
        grid-column: auto;
        grid-row: auto;
        position: static;
    }

    .contributor-tpl-profil .cs-head {
        grid-template-columns: auto minmax(0, 1fr);
        align-items: center;
    }

    .contributor-tpl-profil .cs-portrait img { max-width: 140px; }
}

@media (prefers-reduced-motion: reduce) {
    .contributor-facts .cf-links a,
    .contributor-sheet .cs-cta-btn { transition: none; }
}
