/* --- 1. Les sections respirent -----------------------------------------
   18 px aujourd'hui, contre 64 valides sur le parcours. Le meme jeton, pour
   que les deux pages aient le meme rythme : deux ecrans du meme produit qui
   respirent differemment se lisent comme deux produits.
   ------------------------------------------------------------------------ */
.admin-dashboard {
    display: flex;
    flex-direction: column; 
    gap: var(--espace-section);
}

.admin-dashboard__hero {
    display: flex;
    justify-content: space-between;
    gap: 20px;
    align-items: flex-start;
}

.admin-dashboard__hero-main {
    min-width: 0;
}

.admin-dashboard__hero-stats {
    display: flex;
    flex-wrap: wrap;
    gap: 8px 18px;
    margin-top: 12px;
    font-size: 13px;
    line-height: 1.4;
    color: rgba(var(--white-rgb), 0.74);
}

.admin-dashboard__hero-stats span {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    white-space: nowrap;
}

.admin-dashboard__hero-stats strong {
    color: rgba(var(--white-rgb), 0.96);
    font-weight: 800;
}

/*
 * `admin-eyebrow` REJOINT LA REGLE PLUTOT QUE D'EN AVOIR UNE A ELLE.
 *
 * Quinze gabarits posaient ce surtitre sans qu'aucune feuille ne lui reponde :
 * quinze ecrans affichaient leur surtitre sans mise en forme. La tentation
 * serait d'ecrire une regle pour lui ; ce serait un QUATRIEME traitement de
 * surtitre, alors que le produit en compte deja trois et que le troisieme n'a
 * jamais ete decide. On le rattache donc au canonique.
 */
.admin-eyebrow,
.admin-dashboard__eyebrow {
    font-size: 13px;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    opacity: 0.7;
    margin-bottom: 8px;
}

.admin-dashboard__title {
    margin: 0 0 10px;
}

.admin-dashboard__text {
    margin: 0;
    max-width: 760px;
    opacity: 0.9;
}

.admin-dashboard__hero-actions {
    display: flex;
    gap: 10px;
    flex-wrap: wrap;
    justify-content: flex-end;
}

.admin-dashboard__stats {
    display: grid;
    grid-template-columns: repeat(5, minmax(0, 1fr));
    gap: 16px;
}

.admin-stat {
    display: flex;
    flex-direction: column;
    gap: 8px;
}

.admin-stat__label {
    font-size: 13px;
    opacity: 0.72;
}

.admin-stat__value {
    font-size: 32px;
    font-weight: 700;
    line-height: 1;
}

.admin-stat__note {
    font-size: 12px;
    opacity: 0.7;
}

.admin-dashboard__grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
    gap: 16px;
    align-items: stretch;
}

.admin-dashboard__card {
    display: flex;
    flex-direction: column;
    gap: 12px;
    text-decoration: none;
    color: inherit;
    transition: transform 0.18s ease, box-shadow 0.18s ease;
}

.admin-dashboard__card:hover {
    transform: translateY(-2px);
}

.admin-dashboard__card h2 {
    margin: 0;
    font-size: 22px;
}

.admin-dashboard__card p {
    margin: 0;
    opacity: 0.88;
    line-height: 1.5;
}

.admin-dashboard__card-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
}

.admin-dashboard__icon {
    font-size: 28px;
    line-height: 1;
}

.admin-dashboard__badge {
    display: inline-flex;
    align-items: center;
    padding: 6px 10px;
    border-radius: 999px;
    font-size: 12px;
    background: rgba(var(--green-state-rgb), 0.14);
    color: var(--green-mid);
}

.admin-dashboard__badge--muted {
    background: rgba(var(--white-rgb), 0.08);
    color: inherit;
    opacity: 0.75;
}

.admin-dashboard__link {
    margin-top: auto;
    font-weight: 600;
}

.admin-dashboard__link--muted {
    opacity: 0.7;
}

.admin-dashboard__card--muted {
    opacity: 0.92;
}

.admin-dashboard__section {
    display: grid;
    grid-template-columns: 0.985fr 2.015fr;
    gap: 16px;
}

.admin-quick-actions,
.admin-latest-users {
    display: flex;
    flex-direction: column;
    gap: 14px;
}

.admin-section__head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
}

.admin-messages {
    padding: 10px 38px 10px 12px;
    border: 1px solid rgba(var(--white-rgb), 0.10);
    border-radius: 12px;
    background: rgba(25, 146, 65, 0.2);
}

.admin-section__title {
    margin: 0;
    font-size: 20px;
}

.admin-section__text {
    margin: 0;
    opacity: 0.78;
    font-size: 14px;
}

.admin-users-panel__toolbar {
    display: flex;
    align-items: center;
    gap: 10px;
    flex-wrap: wrap;
}

.admin-users-panel__search-wrap {
    position: relative;
    min-width: 220px;
    flex: 1 1 260px;
    max-width: 360px;
}

/* `input.` et non `.` seule : une classe (0,1,0) ne bat pas
   `input[type="search"]` (0,1,1) de `lk.css:396`, qui impose
   `padding: 12px 14px`. La reserve de 38 px prevue a droite pour la croix
   d'effacement n'existait donc pas, et le texte tape courait jusqu'a 14 px du
   bord, sous le bouton. Trois ecrans d'administration. */
input.admin-users-panel__search {
    width: 100%;
    padding: 10px 38px 10px 12px;
    border: 1px solid rgba(var(--white-rgb), 0.10);
    border-radius: 12px;
    background: rgba(var(--white-rgb), 0.04);
    color: inherit;
    outline: none;
}

.admin-users-panel__search:focus {
    border-color: rgba(var(--white-rgb), 0.24);
    background: rgba(var(--white-rgb), 0.06);
}

.admin-users-panel__clear {
    position: absolute;
    right: 8px;
    top: 50%;
    transform: translateY(-50%);
    width: 24px;
    height: 24px;
    border: 0;
    border-radius: 999px;
    background: transparent;
    color: inherit;
    opacity: 0.65;
    cursor: pointer;
}

.admin-users-panel__clear:hover {
    opacity: 1;
    background: rgba(var(--white-rgb), 0.08);
}

.admin-users-panel__clear.is-hidden {
    display: none;
}

.admin-users-panel__list.is-loading {
    opacity: 0.55;
    pointer-events: none;
}

.admin-quick-actions__grid {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 12px;
}

.admin-quick-action {
    display: flex;
    flex-direction: column;
    gap: 8px;
    padding: 14px;
    border-radius: 16px;
    border: 1px solid rgba(var(--white-rgb), 0.08);
    background: rgba(61, 104, 153, 0.5);
    text-decoration: none;
    color: inherit;
    transition: transform 0.18s ease, background 0.18s ease, border-color 0.18s ease;
}

.admin-quick-action:hover {
    transform: translateY(-2px);
    background: rgba(61, 104, 153, 0.8);
    border-color: rgba(var(--white-rgb), 0.14);
}

.admin-quick-action__title {
    font-weight: 600;
}

.admin-quick-action__text {
    font-size: 14px;
    opacity: 0.8;
    line-height: 1.4;
}

.admin-latest-users__list {
    display: flex;
    flex-direction: column;
    gap: 10px;
}

/*
 * LA MEME LIGNE POUR « Comptes » ET « Support ».
 *
 * C'etait un rectangle gris, sans rien qui dise de quoi il s'agit, quand
 * toutes les autres listes du produit portent un rail de couleur a gauche.
 * La ligne rejoint donc cette grammaire : chaque carte apporte SA teinte par
 * `--row-rgb` et rien d'autre — le type de compte pour l'une, l'attente
 * d'une reponse pour l'autre.
 *
 * Le repli est dans le `var()` : declare a part, il pesait plus lourd que la
 * teinte que la ligne veut poser.
 */
.admin-latest-user {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 14px;

    /* Elle se plie quand le nom n'a plus la place. Le raisonnement et la
       mesure sont sur `.admin-latest-user__main`, qui porte le seuil. */
    flex-wrap: wrap;
    padding: 12px 14px;
    border-radius: 14px;
    box-sizing: border-box;
    border: 1px solid rgba(var(--row-rgb, var(--teinte-bleue)), 0.14);
    border-left: 4px solid rgba(var(--row-rgb, var(--teinte-bleue)), 0.76);
    background: rgba(var(--row-rgb, var(--teinte-bleue)), 0.07);
    background-clip: padding-box;
    transition: background .14s ease, border-color .14s ease;
}

.admin-latest-user:hover {
    background: rgba(var(--row-rgb, var(--teinte-bleue)), 0.12);
}

/* LA LIGNE SE PLIE QUAND LE NOM N A PLUS LA PLACE, ET ELLE DECIDE SEULE.
 *
 * La colonne d'actions -- pastille de role plus trois boutons -- mesure 231 px
 * et refuse de retrecir. Le nom prenait donc ce qui restait : 50 px a 390 px de
 * large, et zero pour l'un d'eux. `text-overflow: ellipsis` faisait son travail
 * et rendait « Chak… », ce qui ne designe personne.
 *
 * PAS DE SEUIL EN PIXELS D ECRAN, parce que le defaut ne depend pas de l'ecran
 * mais de la LARGEUR DE LA LIGNE : la meme carte tombe a 329 px quand la grille
 * du tableau de bord passe a deux colonnes, en plein 780 px. Un `flex-basis` de
 * 180 px fait passer les actions a la ligne des que le nom n'a plus de quoi se
 * lire, a n'importe quelle largeur et dans n'importe quelle grille.
 *
 * 180 px : le plus long nom du releve, « Pierre Praticien (Demo) », mesure
 * 177 px. Un nom plus long reste coupe, et c'est le role de l'ellipse.
 *
 * Mesure de 360 a 1280 px, onze noms : 7 coupes sur 11 a 390 px avant, 0 sur 11
 * a toutes les largeurs apres, sans un pixel de debordement de page. */
.admin-latest-user__main {
    min-width: 0;
    flex: 1 1 180px;
}

.admin-latest-user__name {
    font-weight: 600;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* La seconde ligne dit un fait, pas un nom de champ : elle se lit donc en
   retrait, sans reclamer l'attention du nom au-dessus. */
.admin-latest-user__meta {
    margin-top: 3px;
    font-size: 12.5px;
    /* Une opacite se multiplie a tout voile pose ensuite ; ce retrait-la est
       une encre, il s'ecrit comme une encre. 0,62 rendait 3,22 en clair. */
    color: rgba(var(--white-rgb), var(--voile-mention, 0.62));
}

/* La pastille de role et les pastilles d'action sur une meme ligne d'axe.

   `align-items` sur le conteneur ne suffisait pas : la pastille porte son
   propre `align-self: flex-start`, pose pour qu'elle epouse son texte dans
   les cartes du parcours. C'est donc elle qu'il faut recentrer, ici et
   nulle part ailleurs. Mesure avant : dix pixels au-dessus. */
.admin-latest-user__actions {
    align-items: center;
    display: flex;
    gap: 8px;
    flex-wrap: wrap;
    justify-content: flex-end;

    /* Une fois passees a la ligne, elles prennent toute la largeur : sans quoi
       le `space-between` de la ligne les collerait au bord gauche, sous le
       nom, au lieu de les laisser a droite ou elles sont partout ailleurs. */
    flex: 1 1 auto;
}

.admin-latest-user__actions .journey-pill {
    align-self: center;
}

.admin-empty {
    opacity: 0.7;
}

.admin-dashboard__card-stats {
    display: flex;
    gap: 12px;
    flex-wrap: wrap;
    font-size: 13px;
    opacity: 0.82;
}

@media (max-width: 1180px) {
    .admin-dashboard__stats {
        grid-template-columns: repeat(3, minmax(0, 1fr));
    }

    .admin-dashboard__section {
        grid-template-columns: 1fr;
    }
}

@media (max-width: 980px) {
    .admin-dashboard__hero {
        flex-direction: column;
    }

    .admin-dashboard__hero-actions {
        justify-content: flex-start;
    }

    .admin-dashboard__hero-stats span {
        white-space: normal;
    }

    .admin-dashboard__stats,
    .admin-quick-actions__grid {
        grid-template-columns: 1fr;
    }

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

@media (max-width: 640px) {
    .admin-dashboard__grid {
        grid-template-columns: 1fr;
    }
}

.admin-email-stats {
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: 16px;
    margin-bottom: 20px;
}

.admin-email-stat {
    padding: 18px;
    min-height: 86px;
}

.admin-email-stat__label {
    font-size: 14px;
    opacity: 0.82;
    font-weight: 700;
}

.admin-email-stat__value {
    margin-top: 6px;
    font-size: 30px;
    line-height: 1;
    font-weight: 800;
}

@media (max-width: 1180px) {
    .admin-email-stats {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }
}

@media (max-width: 640px) {
    .admin-email-stats {
        grid-template-columns: 1fr;
    }
}

.partner-dashboard__hero {
    align-items: flex-start;
}

.partner-dashboard__hero-main {
    min-width: 0;
}

.partner-dashboard__hero-actions {
    margin-left: auto;
    padding-top: 6px;
    align-items: flex-start;
}

.partner-dashboard__stages {
    display: grid;
    grid-template-columns: repeat(6, minmax(0, 1fr));
    gap: 16px;
    align-items: stretch;
}

.partner-dashboard__stages .admin-dashboard__card {
    min-width: 0;
}

.partner-dashboard__stages .admin-dashboard__icon {
    font-size: 24px;
}

.partner-dashboard__stages .admin-dashboard__card h2 {
    font-size: 18px;
    line-height: 1.2;
}

.partner-dashboard__stages .admin-dashboard__card p {
    font-size: 14px;
    line-height: 1.45;
}

.partner-dashboard__body {
    display: grid;
    grid-template-columns: 0.985fr 2.015fr;
    gap: 16px;
    align-items: start;
}

.partner-dashboard__sidebar {
    display: grid;
    gap: 16px;
}

.partner-dashboard-clients {
    display: flex;
    flex-direction: column;
    gap: 14px;
    padding: 18px;
}

/* Le lien d'invitation sur sa ligne, le titre et ses boutons sur la
   suivante : cote a cote, le lien n'avait plus la place de s'afficher en
   entier, et un lien tronque ne se verifie pas. */
.partner-dashboard-clients__head {
    display: flex;
    flex-direction: column;
    align-items: stretch;
    gap: 18px;
}

.partner-dashboard-clients__head-main {
    min-width: 0;
    display: flex;
    align-items: center;
    gap: 12px;
    flex-wrap: wrap;
}

/* Le titre annonce la liste qui le suit : il vient donc apres le lien, et
   ne pousse pas les boutons vers le bas en s'elargissant. */
.partner-dashboard-clients__head-main .admin-section__title {
    margin: 0;
    margin-right: auto;
}

.partner-dashboard-clients__copy-link-btn {
    background: rgba(19, 172, 27, 0.788);
    border: 1px solid rgba(var(--white-rgb), 0.10);
    color: rgba(var(--white-rgb), 0.88);
    white-space: nowrap;
}

.partner-dashboard-clients__copy-link-btn:hover {
    background: rgba(23, 207, 32, 0.788);
    border-color: rgba(var(--white-rgb), 0.18);
    color: var(--white);
}

.partner-dashboard-clients-layout {
    display: grid;
    grid-template-columns: minmax(0, 2fr) minmax(340px, 1fr);
    gap: 16px;
    align-items: start;
}

.partner-dashboard-clients__list-pane {
    min-width: 0;
    display: grid;
    gap: 12px;
    max-height: 850px;
    overflow-y: auto;
    padding-right: 6px;
    scrollbar-width: thin;
    scrollbar-color: var(--barre-pouce) var(--barre-piste);
}

.partner-dashboard-clients__list-pane,
.partner-client-card,
.partner-client-expert__scroll {
    scrollbar-width: thin;
    scrollbar-color: var(--barre-pouce) var(--barre-piste);
}

.partner-dashboard-clients__list-pane::-webkit-scrollbar,
.partner-client-card::-webkit-scrollbar,
.partner-client-expert__scroll::-webkit-scrollbar {
    width: 10px;
    height: 10px;
}

.partner-dashboard-clients__list-pane::-webkit-scrollbar-track,
.partner-client-card::-webkit-scrollbar-track,
.partner-client-expert__scroll::-webkit-scrollbar-track {
    background: transparent;
}

.partner-dashboard-clients__list-pane::-webkit-scrollbar-button,
.partner-client-card::-webkit-scrollbar-button,
.partner-client-expert__scroll::-webkit-scrollbar-button {
    display: none;
    width: 0;
    height: 0;
}

.partner-dashboard-clients__list-pane::-webkit-scrollbar-thumb,
.partner-client-card::-webkit-scrollbar-thumb,
.partner-client-expert__scroll::-webkit-scrollbar-thumb {
    background: linear-gradient(
        180deg,
        rgba(var(--white-rgb), 0.18),
        rgba(var(--white-rgb), 0.08)
    );
    border-radius: 999px;
    border: 2px solid transparent;
    background-clip: padding-box;
}

.partner-dashboard-clients__list-pane::-webkit-scrollbar-thumb:hover,
.partner-client-card::-webkit-scrollbar-thumb:hover,
.partner-client-expert__scroll::-webkit-scrollbar-thumb:hover {
    background: linear-gradient(
        180deg,
        rgba(var(--white-rgb), 0.28),
        rgba(var(--white-rgb), 0.14)
    );
    border: 2px solid transparent;
    background-clip: padding-box;
}

.partner-dashboard-clients .table-toolbar {
    margin: 0;
}

.partner-dashboard-clients #users-table-container {
    min-width: 0;
}

.partner-dashboard-clients #users-table-container.is-loading {
    opacity: 0.55;
    pointer-events: none;
}

.partner-dashboard-notifications-row {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
}

.partner-dashboard-notifications-row .partner-client-notifications {
    max-width: none;
}

/* -------------------------------------------------------------------------
   LA LIGNE-CARTE : une grammaire, trois listes
   -------------------------------------------------------------------------

   Trois ecrans posent la meme forme : une liste de personnes ou chaque ligne
   se lit comme une carte horizontale, avec un rail colore a gauche, un fond
   teinte et des bouts arrondis. Elle etait ecrite deux fois, une par ecran, et
   la troisieme copie allait suivre.

   ELLE VIT DONC ICI, en une seule fois. Chaque liste apporte SA COULEUR par
   `--row-rgb` et rien d'autre : l'etape du client, le violet du parcours, le
   type de compte. C'est la seule chose qui les distingue.

   LE REPLI EST DANS LE `var()`, PAS DANS UNE REGLE. Declare sur la ligne
   generique, il pesait `.liste-carte tbody tr.liste-carte__ligne`, soit plus
   lourd que le `.admin-partner-journey-row` qui voulait le remplacer : le
   suivi des parcours repassait au bleu sans que rien ne le signale. Un repli
   ecrit dans le `var()` ne se bat contre personne.

   `--row-solide` est la variante opaque du rail, pour la ligne choisie. A
   defaut, le rail choisi reprend la meme teinte, en plein.

   EN DESSOUS DE 640 PX, la carte passe de la CELLULE a la LIGNE : empilees,
   les cellules gardaient chacune un morceau du decor, le rail sur la
   premiere et l'arrondi de droite tout en bas.
   ------------------------------------------------------------------------- */

/* L'ECARTEMENT FAIT PARTIE DE LA GRAMMAIRE, pas de chaque liste.
   Deux des trois listes le declaraient chacune de leur cote ; la troisieme,
   celle des utilisateurs, ne l'avait pas et ses lignes restaient collees, ce
   qui les faisait lire comme un tableau la ou les deux autres lisent comme
   des cartes. C'est ce qui restait de la difference entre /users et
   /clients. */
.liste-carte {
    width: 100%;
    border-collapse: separate;
    border-spacing: 0 10px;
}

.liste-carte tbody tr.liste-carte__ligne td {
    background: rgba(var(--row-rgb, var(--teinte-bleue)), 0.09);
    border-top: 1px solid rgba(var(--row-rgb, var(--teinte-bleue)), 0.14);
    border-bottom: 1px solid rgba(var(--row-rgb, var(--teinte-bleue)), 0.14);
}

.liste-carte tbody tr.liste-carte__ligne:hover td,
.liste-carte tbody tr.liste-carte__ligne.is-selected td {
    background: rgba(var(--row-rgb, var(--teinte-bleue)), 0.15);
}

.liste-carte tbody tr.liste-carte__ligne.is-selected td {
    border-top-color: rgba(var(--row-rgb, var(--teinte-bleue)), 0.34);
    border-bottom-color: rgba(var(--row-rgb, var(--teinte-bleue)), 0.34);
}

.liste-carte tbody tr.liste-carte__ligne td:first-child {
    border-left: 4px solid rgba(var(--row-rgb, var(--teinte-bleue)), 0.76);
    border-radius: 14px 0 0 14px;
}

.liste-carte tbody tr.liste-carte__ligne.is-selected td:first-child {
    border-left-color: var(--row-solide, rgb(var(--row-rgb, var(--teinte-bleue))));
}

.liste-carte tbody tr.liste-carte__ligne td:last-child {
    border-right: 1px solid rgba(var(--row-rgb, var(--teinte-bleue)), 0.14);
    border-radius: 0 14px 14px 0;
}

/*
 * 880 px : LA MEME BORNE QUE LA BASCULE ELLE-MEME.
 *
 * C'est ce bloc qui fait la CARTE : le cadre, le rembourrage, le rail de
 * couleur, le nom en tete et la date en pied. Il attendait 640 quand
 * `.responsive-table` empile des 880 (lk.css). Entre les deux, la ligne etait
 * demontee sans etre remontee : bandes pleine largeur, bordures de cellules
 * restees en place, et la date d'inscription en premier au lieu du nom.
 *
 * Les trois autres blocs de cette bascule ont deja ete ramenes a 880 ; celui-ci
 * etait le dernier.
 */
@media (max-width: 880px) {
    .liste-carte tbody tr.liste-carte__ligne {
        box-sizing: border-box;
        display: flex;
        flex-direction: column;
        padding: var(--espace-l);
        border: 1px solid rgba(var(--row-rgb, var(--teinte-bleue)), 0.14);
        border-left: 4px solid rgba(var(--row-rgb, var(--teinte-bleue)), 0.76);
        border-radius: var(--rayon-l);
        background: rgba(var(--row-rgb, var(--teinte-bleue)), 0.09);
    }

    .liste-carte tbody tr.liste-carte__ligne.is-selected {
        border-color: rgba(var(--row-rgb, var(--teinte-bleue)), 0.34);
        border-left-color: var(--row-solide, rgb(var(--row-rgb, var(--teinte-bleue))));
        background: rgba(var(--row-rgb, var(--teinte-bleue)), 0.15);
    }

    /*
     * `td:first-child` ET `td:last-child` SONT NOMMES EXPRESSEMENT : ils
     * portent le rail et les arrondis, et leurs selecteurs pesent plus lourd
     * qu'un `td` seul. Sans les nommer, le rail restait accroche a la
     * premiere cellule DE LA SOURCE, que l'ordre visuel peut envoyer
     * ailleurs : un bout de rail arrondi flottait au milieu de la carte.
     */
    .liste-carte tbody tr.liste-carte__ligne td,
    .liste-carte tbody tr.liste-carte__ligne.is-selected td,
    .liste-carte tbody tr.liste-carte__ligne:hover td,
    .liste-carte tbody tr.liste-carte__ligne td:first-child,
    .liste-carte tbody tr.liste-carte__ligne.is-selected td:first-child,
    .liste-carte tbody tr.liste-carte__ligne td:last-child {
        border: none;
        border-radius: 0;
        background: none;
    }

    /*
     * LE TITRE EN TETE, LE PIED EN BAS.
     *
     * L'ordre des colonnes est celui d'un TABLEAU : on le lit colonne par
     * colonne, et la premiere sert souvent a trier. Une liste empilee se lit
     * carte par carte, et c'est le NOM qu'on cherche. Empilee telle quelle,
     * chaque carte s'ouvrait sur une date ou un identifiant.
     *
     * LES CELLULES SONT MARQUEES, PAS COMPTEES : la meme liste n'a pas
     * toujours le meme nombre de colonnes selon l'ecran qui l'affiche, et un
     * `nth-child` designait alors la mauvaise.
     */
    .liste-carte tbody tr.liste-carte__ligne .cellule--titre {
        order: -1;
    }

    .liste-carte tbody tr.liste-carte__ligne .cellule--titre .responsive-table__label {
        display: none;
    }

    .liste-carte tbody tr.liste-carte__ligne .cellule--pied {
        order: 1;
        margin-bottom: 0;
        margin-top: var(--espace-s);
        padding-top: var(--espace-s);
        border-top: 1px solid rgba(var(--white-rgb), 0.08);
        opacity: .72;
        font-size: var(--taille-legende);
    }
}

.partner-clients-table th,
.partner-clients-table td {
    vertical-align: middle;
}

.partner-clients-table th {
    padding-bottom: 6px;
}

/* Le decor de la ligne vient de la grammaire commune (`liste-carte`) : ce
   tableau n'apporte que SA couleur, celle de l'etape ou en est le client. */
.partner-clients-table tbody tr.partner-client-row {
    --row-rgb: var(--journey-accent-rgb);
    --row-solide: var(--journey-accent-solid);
    cursor: pointer;
}

.partner-client-date {
    font-weight: 500;
    color: rgba(var(--white-rgb), 0.94);
    white-space: nowrap;
}

.partner-client-date__time {
    display: block;
    margin-top: 3px;
    font-size: 12px;
    color: rgba(var(--white-rgb), var(--voile-mention, 0.58));
    white-space: nowrap;
}

/*
 * LE NOM SE LIT, IL NE CRIE PAS.
 *
 * Il etait trace en 18 px de graisse 100, un filet : plus grand que tout ce
 * qui l'entoure et plus pale a la fois. Sur une liste, le nom est le point
 * d'ancrage — il doit se detacher par le POIDS, pas par la taille. 15 px en
 * 600, comme dans la liste des comptes, pour que les deux ecrans se
 * ressemblent.
 */
/*
 * LE NOM SE LIT, IL NE CRIE PAS.
 *
 * Il etait trace en 18 px de graisse 100, un filet : plus grand que tout
 * ce qui l entoure et plus pale a la fois. Sur une liste, le nom est le
 * point d ancrage, il doit se detacher par le POIDS et non par la taille.
 * 15 px en 600, comme dans la liste des comptes, pour que les deux ecrans
 * se ressemblent.
 *
 * La regle portait QUATRE declarations pour deux proprietes, chacune
 * annulant la precedente. C est ce qui m avait fait croire a un echec : ma
 * valeur etait bien la, ecrasee trois lignes plus bas.
 */
.partner-client-name {
    font-size: 15px;
    font-weight: 600;
    color: rgba(var(--white-rgb), 0.96);
}

.partner-clients-table tbody tr.partner-client-row .journey-pill--theme {
    background: rgba(var(--row-rgb, var(--teinte-bleue)), 0.18);
    border-color: rgba(var(--row-rgb, var(--teinte-bleue)), 0.34);
    color: rgba(var(--white-rgb), 0.94);
}

.partner-client-message-state {
    display: inline-flex;
    align-items: center;
    min-height: 26px;
    padding: 0 9px;
    border-radius: 999px;
    font-size: 12px;
    line-height: 1;
    font-weight: 800;
    white-space: nowrap;
}

.partner-client-message-state--new {
    color: var(--amber-soft);
    background: rgba(var(--amber-deep-rgb), 0.14);
    border: 1px solid rgba(var(--amber-deep-rgb), 0.28);
}

.partner-client-message-state--ok {
    color: var(--couleur-succes-doux);
    background: rgba(var(--share-bright-rgb), 0.12);
    border: 1px solid rgba(var(--share-bright-rgb), 0.22);
}

.partner-client-message-state--muted {
    color: rgba(var(--white-rgb), var(--voile-mention, 0.62));
    background: rgba(var(--white-rgb), 0.06);
    border: 1px solid rgba(var(--white-rgb), 0.08);
}

.partner-client-activity-state {
    display: inline-flex;
    align-items: center;
    min-height: 26px;
    padding: 0 9px;
    border-radius: 999px;
    font-size: 12px;
    line-height: 1;
    font-weight: 400;
    white-space: nowrap;
}

.partner-client-activity-state--recent {
    color: var(--couleur-succes-doux);
    background: rgba(var(--share-bright-rgb), 0.12);
    border: 1px solid rgba(var(--share-bright-rgb), 0.22);
}

.partner-client-activity-state--month {
    color: var(--blue-mist);
    background: rgba(var(--blue-rgb), 0.12);
    border: 1px solid rgba(var(--blue-rgb), 0.22);
}

.partner-client-activity-state--old {
    color: var(--amber-soft);
    background: rgba(var(--amber-deep-rgb), 0.12);
    border: 1px solid rgba(var(--amber-deep-rgb), 0.24);
}

.partner-client-activity-state--none {
    color: rgba(var(--white-rgb), var(--voile-mention, 0.62));
    background: rgba(var(--white-rgb), 0.06);
    border: 1px solid rgba(var(--white-rgb), 0.08);
}

.partner-client-activity-note {
    margin-top: 5px;
    color: rgba(var(--white-rgb), var(--voile-mention, 0.58));
    font-size: 12px;
    line-height: 1.25;
}

.journey-theme--courses-completed {
    --journey-accent-rgb: 34, 197, 94;
    --journey-accent-solid: var(--couleur-succes);
}

.partner-client-stage-note {
    margin-top: 5px;
    color: rgba(var(--white-rgb), var(--voile-mention, 0.58));
    font-size: 12px;
    line-height: 1.25;
    font-weight: 400;
}

.partner-client-stage-note__sub {
    margin-top: 3px;
    color: rgba(var(--white-rgb), 0.52);
    font-size: 12px;
    line-height: 1.25;
    font-weight: 400;
}

.partner-client-stage-note--completed .partner-client-stage-note__sub {
    color: rgba(var(--couleur-succes-doux-rgb), 0.72);
}

.partner-client-stage-note--completed {
    color: var(--couleur-succes-doux);
}

.partner-client-row--courses-completed td {
    background: rgba(var(--share-bright-rgb), 0.10);
    border-top-color: rgba(var(--share-bright-rgb), 0.18);
    border-bottom-color: rgba(var(--share-bright-rgb), 0.18);
}

.partner-client-row--courses-completed:hover td,
.partner-client-row--courses-completed.is-selected td {
    background: rgba(var(--share-bright-rgb), 0.16);
}

.ligne-actions {
    display: flex;
    align-items: center;
    gap: 8px;
    flex-wrap: nowrap;
}

/* LA BOITE DE LA PASTILLE : 46 x 42, et le repere pour son compteur.
   Le DESSIN de la pastille (rembourrage, rayon, taille de police, dessin du
   glyphe) vit dans `base/elements-retenus.css`, chargee apres celle-ci. Y
   redire la meme chose ici ne peignait rien et faisait croire le contraire :
   une taille de police de 17 px y a dormi des semaines pendant que la page
   en rendait 13. */
.ligne-action {
    position: relative;
    width: 46px;
    height: 42px;
    min-width: 46px;
    line-height: 1;
}
.ligne-action__compte {
    position: absolute;
    top: -7px;
    right: -7px;
    min-width: 20px;
    height: 20px;
    padding: 0 6px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border-radius: 999px;
    background: rgb(var(--amber-deep-rgb));
    color: var(--texte-fort);
    border: 1px solid rgba(var(--ink-900-rgb), 0.96);
    font-size: 11px;
    line-height: 1;
    font-weight: 900;
}

.partner-client-card {
    position: sticky;
    top: 18px;
    width: 100%;
    min-width: 0;
    box-sizing: border-box;
    overflow-x: hidden;
    max-height: calc(100vh - 210px);
    overflow-y: auto;
    padding: 18px;
    border-radius: 18px;
    background: radial-gradient(circle at top right, rgba(var(--journey-accent-rgb), 0.14), transparent 38%),
        rgba(var(--slate-mid-rgb), 0.58);
    border: 1px solid rgba(var(--journey-accent-rgb), 0.24);
    box-shadow: 0 18px 44px rgba(var(--black-rgb), 0.18),
        inset 0 1px 0 rgba(var(--white-rgb), 0.06);
    backdrop-filter: blur(10px);
}

.partner-client-card__empty {
    color: rgba(var(--white-rgb), 0.68);
    line-height: 1.5;
}

.partner-client-card__content {
    display: grid;
    gap: 16px;
}

.partner-client-card__head {
    display: grid;
    gap: 10px;
}

.partner-client-card__eyebrow {
    /* 0,54 est calibre sur un sol sombre ; sur la carte claire il rend 3,76 a
       12 px (mesure, reproduite). Le jeton porte la bascule par theme. */
    color: rgba(var(--white-rgb), var(--voile-mention, 0.54));
    font-size: 12px;
    line-height: 1;
    font-weight: 800;
    text-transform: uppercase;
    letter-spacing: 0.06em;
}

.partner-client-card__name {
    margin: 0;
    color: rgba(var(--white-rgb), 0.96);
    font-size: 23px;
    line-height: 1.2;
}

.partner-client-card__title-area {
    min-width: 0;
    display: grid;
    gap: 7px;
}

.partner-client-card__title-row {
    display: flex;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
    min-width: 0;
}

.partner-client-card__title-row .partner-client-card__name {
    flex: 1 1 auto;
    min-width: 0;
}

.partner-client-card__request-inline {
    flex: 0 0 auto;
    margin: 0;
}

.partner-client-card__request-mini-btn {
    appearance: none;
    min-height: 30px;
    padding: 0 10px;
    border-radius: 18px;

    display: inline-flex;
    align-items: center;
    justify-content: center;

    border: 1px solid rgba(var(--white-rgb), 0.10);

    /* LE MEME VERT QUE PARTOUT AILLEURS, ET C EST UNE CORRECTION DE CONTRASTE.
       `rgba(19, 172, 27, 0.788)` etait ecrit en dur, comme sur le bouton
       « Choisir » de l'ecran expert, et rendait 3,62 pour 4,5 exiges.
       `--share-fill-rgb` est le vert sur lequel le produit pose deja du blanc ;
       le survol reste plus clair, puisque le voile se pose sur une surface
       sombre. */
    background: rgba(var(--share-fill-rgb), 0.92);
    color: var(--white);

    font: inherit;
    font-size: 13px;
    line-height: 1;
    font-weight: 400;
    white-space: nowrap;

    cursor: pointer;
    transition:
        background .18s ease,
        border-color .18s ease,
        color .18s ease,
        transform .18s ease;
}

.partner-client-card__request-mini-btn:hover {
    background: rgb(var(--share-fill-rgb));
    border-color: rgba(var(--white-rgb), 0.18);
    color: var(--white);
    transform: translateY(-1px);
}

.partner-client-card__request-inline.is-disabled {
    opacity: 0.42;
}

.partner-client-card__request-inline.is-disabled .partner-client-card__request-mini-btn,
.partner-client-card__request-mini-btn:disabled {
    cursor: not-allowed;
    transform: none;
    opacity: 0.7;
    filter: grayscale(0.25);
}

@media (max-width: 460px) {
    .partner-client-card__request-inline,
    .partner-client-card__request-mini-btn {
        width: 100%;
    }
}

.partner-client-card__meta {
    display: grid;
    gap: 10px;
}

.partner-client-card__meta-item {
    display: grid;
    gap: 4px;
    padding: 12px;
    border-radius: 14px;
    background: rgba(var(--white-rgb), 0.04);
    border: 1px solid rgba(var(--white-rgb), 0.08);
}

.partner-client-card__meta-item span {
    color: rgba(var(--white-rgb), var(--voile-mention, 0.56));
    font-size: 12px;
    line-height: 1.3;
}

.partner-client-card__meta-item strong {
    color: rgba(var(--white-rgb), 0.92);
    font-size: 14px;
    line-height: 1.35;
}

.partner-client-card__courses {
    display: grid;
    gap: 10px;
    padding: 12px;
    border-radius: 16px;
    background: rgba(var(--white-rgb), 0.04);
    border: 1px solid rgba(var(--white-rgb), 0.075);
}

.partner-client-card__section-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
}

.partner-client-card__section-head span {
    color: rgba(var(--white-rgb), var(--voile-mention, 0.58));
    font-size: 12px;
    line-height: 1.3;
    font-weight: 800;
    text-transform: uppercase;
    letter-spacing: 0.04em;
}

/* `box-sizing` EXPLICITE : sans lui, la pastille est en `content-box` et les
   26 px de largeur minimale s'ajoutent aux 16 px de marge interne et au filet.
   Un compte a un chiffre occupait donc 44 px de large pour 26 de haut : une
   gelule couchee, avec son chiffre cale d'un cote, qui se lisait comme un
   interrupteur plutot que comme un nombre. */
.partner-client-card__section-head strong {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    box-sizing: border-box;
    min-width: 26px;
    height: 24px;
    padding: 0 8px;
    border-radius: 999px;
    background: rgba(var(--journey-accent-rgb), 0.18);
    border: 1px solid rgba(var(--journey-accent-rgb), 0.28);
    color: rgba(var(--white-rgb), 0.92);
    font-size: 12px;
    font-weight: 900;
}

.partner-client-card__courses-list {
    display: grid;
    gap: 8px;
}

.partner-client-card__course-item {
    display: grid;
    gap: 5px;
    padding: 10px;
    border-radius: 12px;
    background: rgba(var(--white-rgb), 0.04);
    border: 1px solid rgba(var(--white-rgb), 0.08);
}

.partner-client-card__course-title {
    color: rgba(var(--white-rgb), 0.94);
    font-size: 14px;
    line-height: 1.3;
    font-weight: 800;
}

.partner-client-card__course-organ {
    color: rgba(var(--white-rgb), 0.72);
    font-size: 13px;
    line-height: 1.35;
}

.partner-client-card__course-meta,
.partner-client-card__courses-empty {
    color: rgba(var(--white-rgb), var(--voile-mention, 0.56));
    font-size: 12px;
    line-height: 1.35;
}

.partner-client-card__advice-btn {
    width: 100%;
    justify-content: center;
}

.partner-client-card__actions {
    display: grid;
    gap: 10px;
}

.partner-client-card__actions .btn,
.partner-client-card__actions form {
    width: 100%;
    max-width: 100%;
    min-width: 0;
    box-sizing: border-box;
}

.partner-client-card__actions form .btn {
    width: 100%;
}

.partner-client-card__actions .btn {
    justify-content: center;
}

.partner-client-card__actions form {
    margin: 0;
}

.partner-client-card__actions form.is-disabled {
    opacity: 0.2;
    cursor: not-allowed;
}

.partner-client-card__actions form.is-disabled .btn,
.partner-client-card__actions form.is-disabled button {
    cursor: not-allowed;
}

.partner-client-card__hint {
    margin: -4px 0 0;
    color: rgba(var(--white-rgb), var(--voile-mention, 0.62));
    font-size: 13px;
    line-height: 1.45;
}

/* =========================================
   Partner dashboard: экспертная работа
   ========================================= */

.partner-client-card__expert-work {
    display: grid;
    gap: 12px;
    padding: 12px;
    border-radius: 16px;
    overflow: hidden;
    background: radial-gradient(circle at 100% 0%, rgba(var(--amber-bright-rgb), 0.18), transparent 38%),
        radial-gradient(circle at 0% 0%, rgba(var(--amber-deep-rgb), 0.10), transparent 42%),
        linear-gradient(180deg, rgba(92, 66, 18, 0.38), rgba(var(--slate-mid-rgb), 0.72));
    border: 1px solid rgba(var(--amber-bright-rgb), 0.24);
    box-shadow: 0 12px 28px rgba(var(--black-rgb), 0.16),
        0 0 0 1px rgba(var(--amber-bright-rgb), 0.06) inset,
        inset 0 1px 0 rgba(var(--white-rgb), 0.08);
}

.partner-client-card__expert-work .partner-client-card__section-head span {
    color: rgba(var(--amber-pale-rgb), 0.92);
}

.partner-client-card__expert-work .partner-client-card__section-head strong {
    background: rgba(var(--amber-bright-rgb), 0.16);
    border-color: rgba(var(--amber-bright-rgb), 0.32);
    color: rgba(254, 249, 195, 0.96);
}

.partner-client-expert {
    display: grid;
    gap: 12px;
    min-width: 0;
}

.partner-client-expert__top {
    display: grid;
    gap: 10px;
    min-width: 0;
}

.partner-client-expert__back {
    appearance: none;
    width: fit-content;
    min-height: 30px;
    padding: 0 10px;
    border-radius: 999px;
    border: 1px solid rgba(var(--white-rgb), 0.08);
    background: rgba(var(--white-rgb), 0.06);
    color: rgba(var(--white-rgb), 0.82);
    font: inherit;
    font-size: 12px;
    line-height: 1;
    font-weight: 400;
    cursor: pointer;
}

.partner-client-expert__back[hidden] {
    display: none;
}

.partner-client-expert__back:hover {
    background: rgba(var(--white-rgb), 0.09);
    color: var(--white);
}

.partner-client-expert__intro {
    display: grid;
    gap: 5px;
    min-width: 0;
}

.partner-client-expert__title {
    color: rgba(var(--white-rgb), 0.94);
    font-size: 15px;
    line-height: 1.25;
    font-weight: 400;
}

.partner-client-expert__text {
    color: rgba(var(--white-rgb), var(--voile-mention, 0.62));
    font-size: 12px;
    line-height: 1.4;
}

.partner-client-expert__scroll {
    min-width: 0;
    max-height: 360px;
    overflow-y: auto;
    overflow-x: hidden;
    padding-right: 6px;
    scrollbar-width: thin;
    scrollbar-color: var(--barre-pouce) var(--barre-piste);
}

.partner-client-expert__scroll::-webkit-scrollbar {
    width: 10px;
}

.partner-client-expert__scroll::-webkit-scrollbar-track {
    background: transparent;
}

.partner-client-expert__scroll::-webkit-scrollbar-thumb {
    background: linear-gradient(
        180deg,
        rgba(var(--white-rgb), 0.18),
        rgba(var(--white-rgb), 0.08)
    );
    border-radius: 999px;
    border: 2px solid transparent;
    background-clip: padding-box;
}

.partner-client-expert__scroll::-webkit-scrollbar-thumb:hover {
    background: linear-gradient(
        180deg,
        rgba(var(--white-rgb), 0.28),
        rgba(var(--white-rgb), 0.14)
    );
    border: 2px solid transparent;
    background-clip: padding-box;
}

.partner-client-expert__grid {
    display: grid;
    grid-template-columns: 1fr;
    gap: 8px;
    min-width: 0;
}

.partner-client-expert__grid[hidden] {
    display: none;
}

.partner-client-expert__choice {
    appearance: none;
    width: 100%;
    min-width: 0;
    min-height: 40px;
    display: grid;
    gap: 4px;
    align-content: center;
    box-sizing: border-box;
    padding: 9px 10px;
    border-radius: 12px;
    border: 1px solid rgba(var(--white-rgb), 0.08);
    border-color: rgba(var(--amber-bright-rgb), 0.11);
    background: rgba(var(--slate-rgb), 0.32);
    color: inherit;
    text-align: left;
    cursor: pointer;
    transition:
        transform .18s ease,
        background .18s ease,
        border-color .18s ease,
        box-shadow .18s ease;
}

.partner-client-expert__choice:hover {
    background: rgba(var(--amber-deep-rgb), 0.13);
    border-color: rgba(var(--amber-bright-rgb), 0.28);
}

.partner-client-expert__choice.is-active {
    background:
        linear-gradient(135deg, rgba(180, 83, 9, 0.54), rgba(var(--amber-bright-rgb), 0.22));
    border-color: rgba(var(--amber-pale-rgb), 0.46);
    box-shadow:
        0 0 0 1px rgba(var(--amber-pale-rgb), 0.10) inset,
        0 10px 22px rgba(180, 83, 9, 0.18);
}

.partner-client-expert__choice-title {
    color: rgba(var(--white-rgb), 0.94);
    font-size: 15px;
    line-height: 1.25;
    font-weight: 400;
    white-space: normal;
    overflow-wrap: anywhere;
}

.partner-client-expert__choice-meta {
    color: rgba(var(--ink-300-rgb), 0.64);
    font-size: 11px;
    line-height: 1.25;
}

.partner-client-expert__footer {
    min-width: 0;
    padding-top: 10px;
    border-top: 1px solid rgba(var(--white-rgb), 0.08);
}

.partner-client-expert__open {
    width: 100%;
    max-width: 100%;
    min-width: 0;
    min-height: 42px;
    box-sizing: border-box;

    display: inline-flex;
    align-items: center;
    justify-content: center;

    border-radius: 12px;
    border: 1px solid rgba(255, 242, 178, 0.58);
    background: linear-gradient(135deg, #b7791f, var(--amber-bright) 58%, rgb(var(--portal-gold-clair-rgb)));

    color: #1f1603;
    text-align: center;
    text-decoration: none;
    font-size: 15px;
    line-height: 1.15;
    font-weight: 400;

    box-shadow: 0 12px 26px rgba(var(--amber-deep-rgb), 0.24),
        inset 0 1px 0 rgba(var(--white-rgb), 0.38);

    transition:
        transform .18s ease,
        background .18s ease,
        border-color .18s ease,
        box-shadow .18s ease;
}

.partner-client-expert__open:hover {
    color: var(--texte-fort);
    background:
        linear-gradient(135deg, #d49425, #fde047 58%, #fff7bd);
    border-color: rgba(255, 242, 178, 0.88);
    box-shadow: 0 14px 30px rgba(var(--amber-deep-rgb), 0.32),
        inset 0 1px 0 rgba(var(--white-rgb), 0.46);
}

.partner-client-expert__open.is-disabled {
    opacity: 0.46;
    cursor: not-allowed;
    pointer-events: none;
    filter: grayscale(0.22);
    transform: none;
    box-shadow: none;
}

body.has-partner-course-advice-modal {
    overflow: hidden;
}

.partner-course-advice-modal[hidden] {
    display: none;
}

.partner-course-advice-modal {
    position: fixed;
    inset: 0;
    z-index: 9999;
    display: grid;
    place-items: center;
    padding: 28px;
}

.partner-course-advice-modal__backdrop {
    position: absolute;
    inset: 0;
    background: rgba(var(--black-rgb), 0.74);
    backdrop-filter: blur(8px);
}

.partner-course-advice-modal__dialog {
    position: relative;
    z-index: 1;
    width: min(980px, 100%);
    max-height: min(860px, calc(100vh - 56px));
    display: flex;
    flex-direction: column;
    overflow: hidden;
    border-radius: 18px;
    background:
        radial-gradient(circle at top right, rgba(111, 145, 255, 0.16), transparent 34%),
        rgba(var(--slate-mid-rgb), 0.96);
    border: 1px solid rgba(var(--white-rgb), 0.12);
    box-shadow: 0 28px 90px rgba(var(--black-rgb), 0.48),
        inset 0 1px 0 rgba(var(--white-rgb), 0.08);
}

.partner-course-advice-modal__head {
    flex: 0 0 auto;
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 18px;
    padding: 20px 22px;
    border-bottom: 1px solid rgba(var(--white-rgb), 0.08);
    background: rgba(var(--slate-rgb), 0.28);
}

.partner-course-advice-modal__eyebrow {
    color: rgba(var(--white-rgb), var(--voile-mention, 0.58));
    font-size: 12px;
    line-height: 1.2;
    font-weight: 900;
    text-transform: uppercase;
    letter-spacing: 0.07em;
}

.partner-course-advice-modal__title {
    margin: 6px 0 0;
    color: rgba(var(--white-rgb), 0.98);
    font-size: 24px;
    line-height: 1.2;
}

.partner-course-advice-modal__client {
    margin-top: 5px;
    color: rgba(var(--white-rgb), 0.70);
    font-size: 14px;
    line-height: 1.35;
}

.partner-course-advice-modal__close {
    width: 40px;
    height: 40px;
    min-width: 40px;
    border: 1px solid rgba(var(--white-rgb), 0.10);
    border-radius: 14px;
    background: rgba(var(--white-rgb), 0.06);
    color: rgba(var(--white-rgb), 0.88);
    font-size: 28px;
    line-height: 1;
    cursor: pointer;
}

.partner-course-advice-modal__close:hover {
    background: rgba(var(--white-rgb), 0.11);
    color: var(--white);
}

.partner-course-advice-modal__body {
    min-height: 0;
    overflow-y: auto;
    padding: 18px 22px 22px;
    scrollbar-width: thin;
    scrollbar-color: var(--barre-pouce) var(--barre-piste);
}

.partner-course-advice-modal__body::-webkit-scrollbar {
    width: 10px;
}

.partner-course-advice-modal__body::-webkit-scrollbar-track {
    background: transparent;
}

.partner-course-advice-modal__body::-webkit-scrollbar-thumb {
    background: rgba(var(--white-rgb), 0.16);
    border-radius: 999px;
    border: 2px solid transparent;
    background-clip: padding-box;
}

.partner-course-advice-modal__loading,
.partner-course-advice-modal__empty,
.partner-course-advice-empty {
    padding: 16px;
    border-radius: 16px;
    background: rgba(var(--white-rgb), 0.04);
    border: 1px solid rgba(var(--white-rgb), 0.08);
    color: rgba(var(--white-rgb), 0.74);
    font-size: 14px;
    line-height: 1.5;
}

.partner-course-advice-modal .journey-course-advice {
    display: grid;
    gap: 16px;
    padding: 0;
    margin: 0;
    border: 0;
    border-radius: 0;
    background: transparent;
    box-shadow: none;
}

.partner-course-advice-modal .journey-course-advice__title {
    margin: 0;
    color: rgba(var(--white-rgb), 0.96);
    font-size: 22px;
    line-height: 1.25;
}

.partner-course-advice-modal .journey-course-advice__intro {
    margin: 0;
    color: rgba(var(--white-rgb), 0.72);
    font-size: 14px;
    line-height: 1.55;
}

.partner-course-advice-modal .journey-course-advice__groups,
.partner-course-advice-modal .journey-course-advice-themes {
    display: grid;
    gap: 12px;
}

.partner-course-advice-modal .journey-course-advice-group,
.partner-course-advice-modal .journey-course-advice-theme {
    padding: 14px;
    border-radius: 18px;
    background: rgba(var(--white-rgb), 0.04);
    border: 1px solid rgba(var(--white-rgb), 0.08);
}

.partner-course-advice-modal .journey-course-advice-group__title,
.partner-course-advice-modal .journey-course-advice-theme__title {
    margin: 0;
    color: rgba(var(--white-rgb), 0.94);
    font-size: 17px;
    line-height: 1.35;
}

.partner-course-advice-modal .journey-course-advice-group__meta,
.partner-course-advice-modal .journey-course-advice-theme__lead,
.partner-course-advice-modal .journey-course-advice-theme__period-label,
.partner-course-advice-modal .journey-course-advice-theme__list {
    color: rgba(var(--white-rgb), 0.72);
    font-size: 14px;
    line-height: 1.5;
}

.partner-course-advice-modal .journey-course-advice-theme__summary {
    cursor: pointer;
}

@media (max-width: 1180px) {
    .partner-dashboard-clients-layout {
        grid-template-columns: 1fr;
    }

    .partner-dashboard-clients__list-pane,
    .partner-client-card {
        max-height: none;
        overflow: visible;
    }

    .partner-client-card {
        position: static;
    }
}

@media (max-width: 780px) {
    .partner-dashboard-clients {
        padding: 14px;
    }

    .partner-dashboard-clients__head {
        flex-direction: column;
    }

    .partner-dashboard-clients__head .btn {
        width: 100%;
        justify-content: center;
    }

    .ligne-actions {
        flex-wrap: wrap;
    }
}

@media (max-width: 1280px) {
    .partner-dashboard__stages {
        grid-template-columns: repeat(3, minmax(0, 1fr));
    }
}

@media (max-width: 980px) {
    .partner-dashboard__hero-actions {
        margin-left: 0;
        padding-top: 0;
    }
    .partner-dashboard__body {
        grid-template-columns: 1fr;
    }

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

@media (max-width: 640px) {
    .partner-dashboard__copy-link-btn {
        width: 100%;
    }
    .partner-dashboard__ref-input-wrap {
        flex: 1 1 calc(100% - 62px);
        min-width: 0;
    }

    .partner-dashboard__icon-btn {
        width: 52px;
    }

    .partner-dashboard__stages {
        grid-template-columns: 1fr;
    }

    .partner-dashboard__icon-btn {
        width: 52px;
    }
}

.partner-stage-filters {
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
    margin: 0 0 16px;
}

.partner-stage-filter {
    text-decoration: none;
    color: inherit;
    transition: transform 0.18s ease, opacity 0.18s ease;
}

/*
 * UN DEPLACEMENT SEUL N EST PAS UN RETOUR AU POINTEUR.
 *
 * Le filtre se contentait de monter d'un pixel. Mesure a l'ecart au fond, son
 * survol valait zero : la couleur ne bougeait pas d'un iota, et sous
 * `prefers-reduced-motion` il ne restait litteralement rien.
 *
 * L ANNEAU EST ECRIT EN `--white-rgb`, donc il s'inverse tout seul : blanc sur
 * le theme sombre, encre sur le theme clair. Une seule regle, deux themes, et
 * aucune chance qu'un jour l'un des deux soit oublie.
 */
.partner-stage-filter:hover {
    transform: translateY(-1px);
}

.partner-stage-filter:hover .journey-pill {
    box-shadow: 0 0 0 1px rgba(var(--white-rgb), 0.26);
}

@media (prefers-reduced-motion: reduce) {
    .partner-stage-filter:hover { transform: none; }
}

.partner-stage-filter.is-active .journey-pill {
    box-shadow: 0 0 0 2px rgba(var(--white-rgb), 0.08) inset;
}

/*
 * TOUTES LES PUCES DE FILTRE A LA MEME HAUTEUR.
 *
 * Deux styles cohabitaient dans la meme rangee : « Toutes les etapes » est un
 * `__clear` (32 px de haut, texte de 13), les autres sont des `journey-pill`
 * (22 px, texte herite de 15). Sur une ligne large, la difference passait ;
 * repliees sur trois lignes en telephone, les puces montaient et descendaient
 * d'une ligne a l'autre et la rangee ressemblait a un escalier.
 *
 * On aligne les pastilles d'etape sur la premiere, qui est la reference :
 * c'est elle qui porte l'etat « aucun filtre ». Les mesures sont copiees de
 * `__clear` a dessein, pour que les deux se corrigent ensemble.
 *
 * Cible restreinte aux filtres : `journey-pill` sert ailleurs a dire l'etape
 * d'un client, ou ces mesures n'ont rien a faire.
 */
.partner-stage-filters .journey-pill {
    min-height: 32px;
    padding: 0 12px;
    font-size: 13px;
    font-weight: 600;
    box-sizing: border-box;
}

/*
 * EN TELEPHONE, LA RANGEE DEFILE AU LIEU DE SE REPLIER.
 *
 * Repliees, les sept puces prenaient quatre lignes, soit 152 px : la liste
 * de clients commencait sous la ligne de flottaison, et l'ecran s'ouvrait
 * sur ses filtres plutot que sur son contenu. Une rangee qui defile tient
 * sur 32 px.
 *
 * LE BORD DROIT S'ESTOMPE, et c'est ce qui dit qu'il y a une suite. Coupee
 * net, une rangee ressemble a une rangee complete et personne ne pense a la
 * faire glisser. C'est un masque et non un degrade pose par-dessus : un
 * degrade aurait demande un element de plus, place en absolu au-dessus des
 * puces, donc a exclure des clics.
 */
@media (max-width: 640px) {
    .partner-stage-filters {
        gap: 8px;
        flex-wrap: nowrap;
        overflow-x: auto;
        scrollbar-width: none;

        /*
         * `min-width: 0` ET `width: 100%` : sans eux, la rangee prenait la
         * largeur de ses sept puces, soit 613 px, et c'est la PAGE ENTIERE
         * qui defilait au lieu de la rangee. Un enfant de flex ou de grille
         * vaut `min-width: auto` par defaut, donc il refuse de passer sous sa
         * largeur naturelle : `overflow-x` ne sert a rien tant qu'on ne l'a
         * pas autorise a retrecir.
         */
        min-width: 0;
        width: 100%;
        box-sizing: border-box;
        /* La puce sur laquelle on s'arrete se cale au bord, plutot que de
           rester coupee en deux. */
        scroll-snap-type: x proximity;
        /* Le rail de defilement mangerait le bas ; on le cache et on rend la
           place au contenu. */
        padding-bottom: 2px;

        -webkit-mask-image: linear-gradient(to right, #000 calc(100% - 28px), transparent 100%);
        mask-image: linear-gradient(to right, #000 calc(100% - 28px), transparent 100%);
    }

    .partner-stage-filters::-webkit-scrollbar {
        display: none;
    }

    .partner-stage-filters .partner-stage-filter {
        flex: 0 0 auto;
        scroll-snap-align: start;
    }

    /* Le survol soulevait la puce d'un pixel ; dans un conteneur qui defile,
       cela declenche un saut de defilement au premier effleurement. */
    .partner-stage-filters .partner-stage-filter:hover {
        transform: none;
    }
}

.partner-stage-filter__clear {
    display: inline-flex;
    align-items: center;
    /* Sans cela, la bordure s'ajoute aux 32 px et cette puce mesure 34 quand
       les autres en font 32 : l'ecart de deux pixels se voit des que la
       rangee se replie. */
    box-sizing: border-box;
    min-height: 32px;
    padding: 0 12px;
    border-radius: 999px;
    text-decoration: none;
    font-size: 13px;
    font-weight: 600;
    background: rgba(var(--white-rgb), 0.08);
    border: 1px solid rgba(var(--white-rgb), 0.08);
    color: inherit;
}

.partner-stage-filter__clear:hover {
    background: rgba(var(--white-rgb), 0.12);
}

.partner-stage-filter__summary {
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
    margin: 0 0 16px;
}

.admin-settings-card {
    display: flex;
    flex-direction: column;
    gap: 18px;
}

.admin-settings-options {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 14px;
}

.admin-settings-option {
    display: flex;
    gap: 12px;
    align-items: flex-start;
    padding: 16px;
    border-radius: 16px;
    border: 1px solid rgba(var(--white-rgb), 0.08);
    background: rgba(var(--white-rgb), 0.04);
    cursor: pointer;
    transition: background 0.18s ease, border-color 0.18s ease, transform 0.18s ease;
}

.admin-settings-option:hover {
    transform: translateY(-1px);
    background: rgba(var(--white-rgb), 0.04);
    border-color: rgba(var(--white-rgb), 0.14);
}

.admin-settings-option.is-active {
    background: rgba(var(--green-state-rgb), 0.10);
    border-color: rgba(var(--green-state-rgb), 0.32);
}

.admin-settings-option input {
    margin-top: 4px;
}

.admin-settings-option__body {
    display: flex;
    flex-direction: column;
    gap: 6px;
}

.admin-settings-option__title {
    font-weight: 700;
}

.admin-settings-option__text {
    font-size: 14px;
    line-height: 1.5;
    opacity: 0.82;
}

.admin-settings-actions {
    display: flex;
    justify-content: flex-start;
    gap: 10px;
    flex-wrap: wrap;
}

@media (max-width: 780px) {
    .admin-settings-options {
        grid-template-columns: 1fr;
    }
}

.partner-client-notifications {
    display: flex;
    flex-direction: column;
    gap: 12px;
}

.partner-client-notifications__success {
    padding: 10px 12px;
    border-radius: 12px;
    background: rgba(var(--green-state-rgb), 0.12);
    border: 1px solid rgba(var(--green-state-rgb), 0.24);
    font-size: 13px;
    line-height: 1.4;
}

.partner-client-notifications__form {
    display: flex;
    flex-direction: column;
    gap: 12px;
}

.partner-client-notifications__list {
    display: grid;
    gap: 8px;
}

.partner-client-notifications__option {
    display: flex;
    align-items: flex-start;
    gap: 9px;
    padding: 9px 10px;
    border-radius: 12px;
    border: 1px solid rgba(var(--white-rgb), 0.08);
    background: rgba(var(--white-rgb), 0.04);
    cursor: pointer;
}

.partner-client-notifications__option:hover {
    background: rgba(var(--white-rgb), 0.04);
    border-color: rgba(var(--white-rgb), 0.14);
}

.partner-client-notifications__option input {
    margin-top: 3px;
    accent-color: var(--green-mid);
}

.partner-client-notifications__option-body {
    display: flex;
    flex-direction: column;
    gap: 2px;
    min-width: 0;
}

/* LE TITRE DE L OPTION PREND L ENCRE PLEINE. Il l'heritait de sa carte, ou elle
   vaut 0,82 : sur la surface plus claire du bloc de notifications, cela rendait
   4,43 pour 4,5 exiges. C'est le libelle qu'on lit en premier dans ce bloc ; il
   n'a aucune raison d'etre le plus eteint des trois. */
.partner-client-notifications__option-title {
    font-size: 13px;
    font-weight: 700;
    line-height: 1.25;
    color: rgba(var(--white-rgb), var(--voile-12, 0.94));
}

/* UNE ENCRE, PAS UNE OPACITE. `opacity` eteint tout ce que l'element porte --
   un lien, une valeur, un signe -- et se multiplie a ce que la couleur avait
   deja de voile : le texte rendait 3,07 pour 4,5 exiges sur la carte de
   notifications (mesure `contraste.py`, les deux themes). Une couleur dit ce
   qu'on veut : le cran de mention du produit, avec le repli du sombre. */
.partner-client-notifications__option-text {
    font-size: 12px;
    line-height: 1.35;
    color: rgba(var(--white-rgb), var(--voile-mention, 0.76));
}

.partner-client-notifications__actions {
    display: flex;
    align-items: center;
    gap: 10px;
    flex-wrap: wrap;
}

/* Meme raison, meme remede : 3,1 mesure a 0,68 d'opacite. */
.partner-client-notifications__hint {
    font-size: 12px;
    line-height: 1.35;
    color: rgba(var(--white-rgb), var(--voile-mention, 0.76));
}

.admin-email-page-head {
    align-items: flex-start;
}

.admin-email-notice {
    padding: 14px;
    border-left: 4px solid #6d5dfc;
}

.admin-email-notice--error {
    border-left-color: var(--couleur-danger);
    color: var(--couleur-danger-doux);
}

.admin-email-layout {
    display: grid;
    grid-template-columns: 0.985fr 2.015fr;
    gap: 16px;
    align-items: start;
}

.admin-email-card {
    padding: 18px;
    min-width: 0;
}

.admin-email-card--log {
    position: sticky;
    top: 18px;
    display: flex;
    flex-direction: column;
    max-height: calc(100vh - 36px);
    overflow: hidden;
}

.admin-email-card--log .admin-section__head {
    flex: 0 0 auto;
    padding-bottom: 12px;
    margin-bottom: 12px;
    border-bottom: 1px solid rgba(var(--white-rgb), 0.08);
}

.admin-email-card--log .admin-email-feed {
    min-height: 0;
    overflow-y: auto;
    padding-right: 6px;
    scrollbar-width: thin;
    scrollbar-color: var(--barre-pouce) var(--barre-piste);
}

.admin-email-card--log .admin-email-feed::-webkit-scrollbar {
    width: 10px;
}

.admin-email-card--log .admin-email-feed::-webkit-scrollbar-track {
    background: transparent;
}

.admin-email-card--log .admin-email-feed::-webkit-scrollbar-thumb {
    background: linear-gradient(
        180deg,
        rgba(var(--white-rgb), 0.18),
        rgba(var(--white-rgb), 0.08)
    );
    border-radius: 999px;
    border: 2px solid transparent;
    background-clip: padding-box;
}

.admin-email-card--log .admin-email-feed::-webkit-scrollbar-thumb:hover {
    background: linear-gradient(
        180deg,
        rgba(var(--white-rgb), 0.28),
        rgba(var(--white-rgb), 0.14)
    );
    border: 2px solid transparent;
    background-clip: padding-box;
}

.admin-email-card__link {
    font-size: 13px;
    font-weight: 700;
    text-decoration: none;
    color: inherit;
    opacity: 0.78;
}

.admin-email-card__link:hover {
    opacity: 1;
}

.admin-email-feed {
    display: flex;
    flex-direction: column;
    gap: 10px;
}

.admin-email-feed-item {
    display: flex;
    flex-direction: column;
    gap: 8px;
    padding: 12px;
    border-radius: 14px;
    border: 1px solid rgba(var(--white-rgb), 0.08);
    background: rgba(var(--white-rgb), 0.04);
}

.admin-email-feed-item__top {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 10px;
}

.admin-email-feed-item__date {
    font-size: 12px;
    opacity: 0.68;
    white-space: nowrap;
}

.admin-email-feed-item__to {
    display: flex;
    flex-direction: column;
    gap: 2px;
    font-size: 13px;
    font-weight: 700;
    line-height: 1.3;
    word-break: break-word;
}

.admin-email-feed-item__to span {
    font-size: 12px;
    font-weight: 500;
    opacity: 0.68;
}

.admin-email-feed-item__template {
    font-size: 13px;
    line-height: 1.35;
    opacity: 0.78;
}

.admin-email-feed-item__error {
    padding: 8px 10px;
    border-radius: 10px;
    background: rgba(var(--red-rgb), 0.10);
    border: 1px solid rgba(var(--red-rgb), 0.18);
    color: var(--couleur-danger-doux);
    font-size: 12px;
    line-height: 1.35;
}

.admin-email-status {
    display: inline-flex;
    align-items: center;
    min-height: 24px;
    padding: 0 9px;
    border-radius: 999px;
    font-size: 12px;
    font-weight: 800;
    line-height: 1;
    border: 1px solid rgba(var(--white-rgb), 0.08);
    background: rgba(var(--white-rgb), 0.08);
}

.admin-email-status--pending {
    background: rgba(var(--amber-deep-rgb), 0.12);
    border-color: rgba(var(--amber-deep-rgb), 0.26);
    color: var(--amber-soft);
}

.admin-email-status--processing {
    background: rgba(var(--blue-rgb), 0.12);
    border-color: rgba(var(--blue-rgb), 0.26);
    color: var(--blue-soft);
}

.admin-email-status--sent {
    background: rgba(var(--green-state-rgb), 0.12);
    border-color: rgba(var(--green-state-rgb), 0.26);
    color: var(--green-mid);
}

.admin-email-status--failed {
    background: rgba(var(--red-rgb), 0.12);
    border-color: rgba(var(--red-rgb), 0.26);
    color: var(--couleur-danger-doux);
}

.admin-email-status--cancelled {
    background: rgba(var(--white-rgb), 0.08);
    border-color: rgba(var(--white-rgb), 0.12);
    color: rgba(var(--white-rgb), 0.72);
}

.admin-email-templates-head {
    align-items: flex-start;
    margin-bottom: 16px;
}

.admin-email-template-groups {
    display: flex;
    flex-direction: column;
    gap: 18px;
}

.admin-email-template-group {
    display: flex;
    flex-direction: column;
    gap: 12px;
}

.admin-email-template-group__head {
    position: relative;
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 12px;
    flex-wrap: wrap;
    margin: 0 0 2px;
    padding: 8px 14px 8px 16px;
    border-radius: 14px;
    background: rgba(var(--slate-rgb), 0.26);
    border: 1px solid rgba(var(--white-rgb), 0.08);
    color: rgba(var(--white-rgb), 0.96);
    box-shadow: inset 0 1px 0 rgba(var(--white-rgb), 0.04);
}

.admin-email-template-group__head::before {
    content: "";
    position: absolute;
    inset: 8px auto 8px 0;
    width: 4px;
    border-radius: 0 8px 8px 0;
    background: linear-gradient(180deg, rgba(var(--blue-light-rgb), 0.9), rgba(var(--blue-rgb), 0.55));
}

.admin-email-template-group__head h3 {
    flex: 1 1 auto;
    min-width: 0;
    margin: 0;
    padding-left: 2px;
    font-size: 20px;
    font-weight: 700;
    line-height: 1.25;
    color: rgba(var(--white-rgb), 0.96);
}

.admin-email-template-group__head span {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 28px;
    height: 28px;
    padding: 0 9px;
    border-radius: 999px;
    background: rgba(var(--white-rgb), 0.08);
    border: 1px solid rgba(var(--white-rgb), 0.08);
    color: rgba(var(--white-rgb), 0.82);
    font-size: 12px;
    font-weight: 800;
    line-height: 1;
}

.admin-email-template-list {
    display: flex;
    flex-direction: column;
    gap: 8px;
}

.admin-email-template-item {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    gap: 14px;
    align-items: center;
    padding: 12px 14px;
    border-radius: 14px;
    border: 1px solid rgba(var(--white-rgb), 0.08);
    background: rgba(var(--white-rgb), 0.04);
}

.admin-email-template-item:hover {
    background: rgba(var(--white-rgb), 0.04);
    border-color: rgba(var(--white-rgb), 0.14);
}

.admin-email-template-item__main {
    min-width: 0;
}

.admin-email-template-item__name {
    font-size: 18px;
    font-weight: 400;
    line-height: 1.3;
}

.admin-email-template-item__meta {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    margin-top: 6px;
    font-size: 12px;
    font-weight: 400;
    color: rgba(var(--white-rgb), var(--voile-mention, 0.58));
}

.admin-email-template-item__actions {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap: 8px;
    flex-wrap: wrap;
}

.admin-email-template-item__actions form {
    margin: 0;
}

.admin-email-template-state {
    display: inline-flex;
    align-items: center;
    min-height: 30px;
    padding: 0 10px;
    border-radius: 999px;
    font-size: 12px;
    font-weight: 800;
    white-space: nowrap;
}

.admin-email-template-state.is-active {
    background: rgba(var(--green-state-rgb), 0.12);
    color: var(--green-mid);
}

.admin-email-template-state.is-disabled {
    background: rgba(var(--white-rgb), 0.08);
    color: rgba(var(--white-rgb), 0.68);
}

@media (max-width: 1180px) {
    .admin-email-layout {
        grid-template-columns: 1fr;
    }

    .admin-email-card--log {
        order: 2;
        position: static;
        max-height: 520px;
    }

    .admin-email-card--templates {
        order: 1;
    }
}

@media (max-width: 640px) {
    .admin-email-card--log {
        max-height: none;
        overflow: visible;
    }

    .admin-email-card--log .admin-email-feed {
        overflow: visible;
        padding-right: 0;
    }
}

@media (max-width: 780px) {
    .admin-email-template-item {
        grid-template-columns: 1fr;
    }

    .admin-email-template-item__actions {
        justify-content: flex-start;
    }
}

.admin-email-table-wrap {
    overflow: auto;
}

.admin-email-table {
    width: 100%;
    border-collapse: collapse;
    min-width: 860px;
}

.admin-email-table th,
.admin-email-table td {
    padding: 11px 10px;
    border-bottom: 1px solid rgba(var(--white-rgb), 0.08);
    text-align: left;
    vertical-align: top;
}

.admin-email-table th {
    font-size: 12px;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    opacity: 0.62;
}

.admin-email-table td {
    font-size: 13px;
    line-height: 1.4;
}

.admin-email-table__date {
    white-space: nowrap;
    opacity: 0.82;
}

.admin-email-table__error {
    color: var(--couleur-danger-doux);
    max-width: 340px;
}

.admin-email-pagination {
    margin-top: 16px;
}

.partner-dashboard-flash {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 14px 16px;
    border-radius: 18px;
    border: 1px solid rgba(var(--white-rgb), 0.12);
    box-shadow: 0 18px 46px rgba(var(--black-rgb), 0.24),
        inset 0 1px 0 rgba(var(--white-rgb), 0.10);
    backdrop-filter: blur(10px);
}

.partner-dashboard-flash--success {
    background: linear-gradient(135deg, rgba(var(--share-bright-rgb), 0.34), rgba(21, 128, 61, 0.52)),
        rgba(20, 83, 45, 0.74);
    border-color: rgba(var(--green-soft-rgb), 0.32);
}

.partner-dashboard-flash--error {
    background: linear-gradient(135deg, rgba(var(--red-rgb), 0.34), rgba(var(--red-mid-rgb), 0.56)),
        rgba(var(--red-deep-rgb), 0.78);
    border-color: rgba(var(--red-soft-rgb), 0.36);
}

.partner-dashboard-flash__icon {
    width: 32px;
    height: 32px;
    min-width: 32px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border-radius: 999px;
    background: rgba(var(--white-rgb), 0.16);
    border: 1px solid rgba(var(--white-rgb), 0.16);
    font-weight: 900;
    line-height: 1;
}

.partner-dashboard-flash__text {
    font-size: 14px;
    line-height: 1.4;
    font-weight: 700;
    color: rgba(var(--white-rgb), 0.96);
}

.partner-pending-diagnostics.card {
    position: relative;
    display: flex;
    flex-direction: column;
    gap: 14px;
    overflow: hidden;
    padding: 20px;
    border: 1px solid rgba(var(--amber-rgb), 0.42);
    background:
        radial-gradient(circle at 18% 0%, rgba(var(--gold-soft-rgb), 0.30), transparent 34%),
        linear-gradient(135deg, rgba(180, 83, 9, 0.86), rgba(120, 53, 15, 0.92)),
        rgba(120, 53, 15, 0.92);
    box-shadow: 0 20px 56px rgba(var(--black-rgb), 0.30),
        inset 0 1px 0 rgba(var(--white-rgb), 0.14);
}

.partner-pending-diagnostics::before {
    content: "";
    position: absolute;
    inset: 0 auto 0 0;
    width: 5px;
    background: linear-gradient(180deg, rgb(var(--amber-rgb)), var(--orange));
}

.partner-pending-diagnostics .admin-section__head {
    position: relative;
    z-index: 1;
}

.partner-pending-diagnostics .admin-section__title {
    color: rgba(var(--white-rgb), 0.98);
    text-shadow: 0 1px 2px rgba(var(--halo-texte-rgb, var(--black-rgb)), 0.28);
}

.partner-pending-diagnostics .admin-section__text {
    color: rgba(var(--white-rgb), 0.86);
    opacity: 1;
}

.partner-pending-diagnostics .admin-dashboard__badge {
    background: rgba(var(--white-rgb), 0.18);
    border: 1px solid rgba(var(--white-rgb), 0.18);
    color: #fff7ed;
}

.partner-pending-diagnostics__list {
    position: relative;
    z-index: 1;
    display: grid;
    gap: 10px;
}

.partner-pending-diagnostic {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 14px;
    padding: 14px 16px;
    border-radius: 16px;
    border: 1px solid rgba(var(--white-rgb), 0.18);
    background: rgba(30, 24, 18, 0.34);
    box-shadow: inset 0 1px 0 rgba(var(--white-rgb), 0.08);
}

.partner-pending-diagnostic__main {
    min-width: 0;
}

.partner-pending-diagnostic__name {
    font-weight: 800;
    color: rgba(var(--white-rgb), 0.98);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.partner-pending-diagnostic__meta {
    margin-top: 4px;
    font-size: 13px;
    color: rgba(var(--white-rgb), 0.76);
}

.partner-pending-diagnostic__testing-time {
    display: flex;
    flex-wrap: wrap;
    gap: 6px 12px;
    margin-top: 8px;
    font-size: 13px;
    line-height: 1.35;
    color: rgba(var(--white-rgb), 0.82);
}

.partner-pending-diagnostic__testing-time span {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    padding: 5px 9px;
    border-radius: 999px;
    background: rgba(var(--white-rgb), 0.08);
    border: 1px solid rgba(var(--white-rgb), 0.10);
}

.partner-pending-diagnostic__testing-time em {
    margin-left: 4px;
    font-style: normal;
    font-size: 12px;
    font-weight: 800;
    opacity: 0.92;
}

.partner-pending-diagnostic__time-pill--normal {
    background: rgba(var(--share-bright-rgb), 0.14) !important;
    border-color: rgba(var(--share-bright-rgb), 0.30) !important;
}

.partner-pending-diagnostic__time-pill--fast,
.partner-pending-diagnostic__time-pill--slow {
    background: rgba(var(--red-rgb), 0.16) !important;
    border-color: rgba(var(--teinte-rouge), 0.34) !important;
}

.partner-pending-diagnostic__time-pill--unknown {
    background: rgba(var(--white-rgb), 0.08) !important;
    border-color: rgba(var(--white-rgb), 0.10) !important;
}

.partner-pending-diagnostic__testing-time strong {
    color: #fff7ed;
    font-weight: 900;
}

.partner-pending-diagnostic__actions {
    display: flex;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
    justify-content: flex-end;
}

.partner-pending-diagnostic__actions form {
    margin: 0;
}

.partner-pending-diagnostic__actions .btn {
    min-height: 42px;
    border-radius: 12px;
}

.partner-pending-diagnostic__actions .btn-primary {
    background: #fff7ed;
    border-color: rgba(var(--white-rgb), 0.72);
    color: #7c2d12;
}

.partner-pending-diagnostic__actions .btn-primary:hover {
    background: #ffedd5;
    color: #7c2d12;
}

.partner-pending-diagnostic__actions .btn-secondary {
    background: rgba(var(--ink-900-rgb), 0.72);
    border-color: rgba(var(--white-rgb), 0.16);
    color: rgba(var(--white-rgb), 0.94);
}

.partner-pending-diagnostic__actions .btn-secondary:hover {
    background: rgba(var(--ink-900-rgb), 0.88);
}

@media (max-width: 720px) {
    .partner-pending-diagnostic {
        align-items: flex-start;
        flex-direction: column;
    }

    .partner-pending-diagnostic__actions {
        justify-content: flex-start;
    }
}

.processing-layout {
    display: grid;
    grid-template-columns: minmax(0, 1.6fr) minmax(360px, 0.9fr);
    gap: 16px;
    align-items: start;
}

.processing-layout__main,
.processing-layout__side,
.processing-card,
.processing-stack {
    display: flex;
    flex-direction: column;
    gap: 14px;
}

.processing-card {
    padding: 18px;
}

.processing-muted {
    margin-top: 4px;
    font-size: 12px;
    line-height: 1.35;
    opacity: 0.68;
}

.processing-inline-form {
    display: flex;
    gap: 8px;
    align-items: center;
    flex-wrap: wrap;
}

.processing-input {
    min-height: 42px;
    padding: 8px 10px;
    border: 1px solid rgba(var(--white-rgb), 0.10);
    border-radius: 12px;
    background: rgba(var(--white-rgb), 0.04);
    color: inherit;
    outline: none;
}

.processing-input:focus {
    border-color: rgba(var(--white-rgb), 0.24);
    background: rgba(var(--white-rgb), 0.06);
}

/*
 * LE MENU DEROULANT DE CES CHAMPS SUIT LE THEME.
 *
 * `color-scheme: dark` est bien pose a la racine, mais il ne suffit PAS quand
 * le champ porte un fond personnalise : le navigateur reprend alors la main et
 * dessine sa liste en clair. C'est le cas ici, `.processing-input` peint son
 * fond en `rgba(white, 0.04)`.
 *
 * Resultat vu a l'ecran, sur « Ouvrir l'essai aux nouveaux praticiens » : liste
 * blanche, option non retenue en gris pale sur blanc, illisible.
 *
 * Le remede est celui deja pose deux fois ailleurs dans cette feuille
 * (`.landing-presentation-field select`, `.admin-partner-journey-select`) : les
 * options portent leurs couleurs, EN OPAQUE. Un fond translucide ne
 * conviendrait pas non plus, le systeme le composerait sur du blanc.
 */
select.processing-input {
    color-scheme: dark;
}

select.processing-input option {
    background: var(--slate-mid);
    color: var(--ink-50);
}

select.processing-input option:checked {
    background: #4056c9;
    color: var(--white);
}

select.processing-input option:disabled {
    color: rgba(var(--white-rgb), 0.48);
}

.processing-input--small {
    width: 92px;
}

.processing-rule-row {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    gap: 12px;
    align-items: center;
    padding: 12px;
    border-radius: 14px;
    border: 1px solid rgba(var(--white-rgb), 0.08);
    background: rgba(var(--white-rgb), 0.04);
}

.processing-rule-row__controls {
    display: flex;
    align-items: center;
    gap: 8px;
}

/* UNE ENCRE, PAS UNE OPACITE -- meme raison que le bloc de notifications.
   `opacity: 0.84` eteint le libelle ET la case qu'il porte, et se multiplie au
   voile que la couleur avait deja : 4,24 mesure pour 4,5 exiges sur la carte de
   traitement et sur les reglages. Le libelle d'un interrupteur est ce qu'on lit
   AVANT de basculer ; il prend l'encre pleine, et la case garde sa teinte. */
.processing-checkbox {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-size: 13px;
    color: rgba(var(--white-rgb), var(--voile-12, 0.94));
    white-space: nowrap;
}

.processing-checkbox input {
    accent-color: var(--green-mid);
}

.processing-field {
    display: flex;
    flex-direction: column;
    gap: 6px;
    font-size: 13px;
    font-weight: 700;
}

.processing-preset {
    display: flex;
    flex-direction: column;
    gap: 12px;
    padding: 12px;
    border-radius: 14px;
    border: 1px solid rgba(var(--white-rgb), 0.08);
    background: rgba(var(--white-rgb), 0.04);
}

.processing-preset__head {
    display: flex;
    justify-content: space-between;
    gap: 12px;
    align-items: flex-start;
}

/* --- L'interrupteur se range en colonne ------------------------------------
   -------------------------------------------------------------------------
   `space-between` REPARTIT, IL N ALIGNE PAS. L'en-tete porte quatre enfants :
   le bloc de texte, la case cachee, l'interrupteur, le chevron. L'espace
   restant se distribuant EGALEMENT entre les intervalles, et le bloc de texte
   n'ayant pas de largeur fixe -- 284 px sur une ligne, 233 sur la suivante --,
   la moitie de cet ecart deplacait l'interrupteur. Releve a l'ecran : 856,
   831, 838, 831, puis 986 pixels. Cinq interrupteurs, cinq positions.

   POUR QU UNE COLONNE EXISTE, UN SEUL ENFANT DOIT ABSORBER LE JEU. Le bloc de
   texte pousse, l'interrupteur et le chevron gardent leur taille : l'un se
   range alors toujours a la meme distance de l'autre, quelle que soit la
   longueur du libelle.

   `min-width: 0` VA AVEC. Sans lui, un enfant de flex refuse de descendre sous
   la largeur de son contenu, et un libelle long repousserait l'interrupteur au
   lieu de se replier -- le defaut reviendrait par l'autre bout.
   ------------------------------------------------------------------------- */

.processing-preset__head > :first-child {
    flex: 1 1 auto;
    min-width: 0;
}

.processing-preset__head > .processing-checkbox,
.processing-preset__head > .processing-preset__chevron {
    flex: 0 0 auto;
}

/* --- 12. Les rangees de reglages se serrent sur leur contenu --------------
   -------------------------------------------------------------------------
   `.processing-preset__grid` pose DEUX COLONNES DE 565 px fixes, et elle sert
   neuf fois sur la page. Tant que les champs remplissaient leur colonne, ca ne
   se voyait pas. Des qu'on leur a rendu leur vraie largeur, le defaut est
   apparu : « Jours d'acces complet » occupe un sixieme de sa colonne et
   « Relances par jour » flotte au milieu de la page, a cinq cents pixels de son
   voisin.

   UNE COLONNE FIXE EST UN PARI SUR LE CONTENU. Elle suppose que tous les champs
   ont la meme importance et la meme taille, ce qui n'est vrai sur aucune de ces
   neuf rangees : on y trouve un nom de trente caracteres a cote d'un nombre a
   un chiffre.

   La rangee devient un FLUX : chaque champ prend sa largeur, ils se suivent
   avec un ecart constant, et passent a la ligne quand la place manque. Rien a
   declarer par cas, et une rangee de cinq champs courts tient desormais sur une
   ligne au lieu de deux.

   ALIGNES PAR LE HAUT, et j'ai essaye l'inverse d'abord. `flex-end` alignait
   les champs sur leur ligne de saisie, ce qui parait juste tant que les libelles
   font la meme hauteur. Des qu'une rangee melange « Jours d'acces complet » et
   « Ouvrir l'essai aux nouveaux praticiens », le second passe sur deux lignes,
   et le premier champ se retrouve pousse vers le bas, seul, sous son voisin.

   Par le haut, ce sont les LIBELLES qui s'alignent. Les champs peuvent alors se
   decaler entre eux, ce qui se lit comme deux colonnes de hauteurs differentes,
   et non comme un champ egare.
   ------------------------------------------------------------------------- */
.processing-preset__grid {
    display: flex;
    grid-template-columns: repeat(auto-fit, minmax(116px, 1fr));
    gap: 12px 28px;
    flex-wrap: wrap;
    align-items: flex-start;
}

/* Deux colonnes : a gauche ce qui est a soi, a droite le bareme commun.
   La colonne de gauche prend la largeur de son contenu, la droite le reste :
   c'est le bareme qui a des lignes a faire tenir. */
.processing-balance-card {
    display: grid;
    grid-template-columns: minmax(220px, auto) minmax(0, 1fr);
    align-items: start;
    gap: 14px 32px;
    padding: 18px;
}

.processing-balance-card__mine {
    display: flex;
    flex-direction: column;

    /* Le lien s'arrete a son intitule : dans une colonne, il s'etirait sur
       toute la largeur de la carte. */
    align-items: flex-start;
    gap: 10px;
}

.processing-balance-card__mine .admin-section__title {
    margin: 0;
}

@media (max-width: 860px) {
    .processing-balance-card {
        grid-template-columns: minmax(0, 1fr);
    }
}

.processing-balance-card__bar {
    height: 12px;
    border-radius: 999px;
    overflow: hidden;
    background: rgba(var(--white-rgb), 0.08);
    border: 1px solid rgba(var(--white-rgb), 0.08);
}

.processing-balance-card__bar-fill {
    height: 100%;
    border-radius: inherit;
    background: linear-gradient(90deg, rgba(var(--green-state-rgb),0.95), rgba(var(--green-mid-rgb),0.78));
}

.processing-balance-card__stats {
    display: flex;
    flex-wrap: wrap;
    gap: 10px 14px;
    font-size: 13px;
    opacity: 0.86;
}

/* Le bareme se consulte ligne par ligne : en phrase continue, il fallait
   relire pour retrouver quel prix allait avec quel traitement. */
.processing-balance-card__products-title {
    margin: 0 0 8px;
    font-size: 13px;
    font-weight: 500;
    opacity: 0.7;
}

/* Le prix est cale a droite de la LISTE, pas de la carte : sur 690 px, l'oeil
   perdait la ligne entre l'intitule et son cout. */
.processing-balance-card__tarifs {
    margin: 0;
    padding: 0;
    list-style: none;
    font-size: 13px;

    /* La liste se taille sur sa ligne la plus longue : cadrer sur la carte
       laissait 190 px de vide entre un intitule court et son cout. */
    width: max-content;
    max-width: 100%;
}

.processing-balance-card__tarifs li {
    display: flex;
    align-items: baseline;
    gap: 12px;
    padding: 5px 0;
    border-bottom: 1px solid rgba(var(--white-rgb), 0.06);
}

.processing-balance-card__tarifs li:last-child {
    border-bottom: none;
}

.processing-balance-card__tarifs span {
    opacity: 0.8;
}

/* Les points s'alignent a droite : c'est la colonne qu'on parcourt du regard
   quand on compare deux traitements. */
.processing-balance-card__tarifs strong {
    margin-left: auto;
    font-weight: 600;
    white-space: nowrap;
    font-variant-numeric: tabular-nums;
}

@media (max-width: 1180px) {
    .processing-layout {
        grid-template-columns: 1fr;
    }
}

@media (max-width: 760px) {
    .processing-rule-row,
    .processing-preset__grid {
        grid-template-columns: 1fr;
    }

    .processing-inline-form {
        align-items: stretch;
    }

    .processing-inline-form .processing-input,
    .processing-inline-form .btn {
        width: 100%;
    }
}

/* =========================================
   Баллы и операции обработки
   ========================================= */

.processing-settings-grid {
    display: grid;
    grid-template-columns: minmax(0, 1.35fr) minmax(320px, 0.65fr);
    gap: 16px;
    align-items: start;
}

.processing-card--operations {
    min-width: 0;
}

.processing-section-head {
    align-items: flex-start;
}

.processing-transactions-search {
    flex: 1 1 320px;
    justify-content: flex-end;
}

.processing-transactions-search .admin-users-panel__search-wrap {
    width: 100%;
    max-width: 420px;
}

.processing-page .admin-email-table-wrap {
    overflow-x: auto;
}

.processing-page .processing-table--operations {
    width: 100%;
    min-width: 1180px;
    table-layout: fixed;
}

.processing-page .processing-table--operations th,
.processing-page .processing-table--operations td {
    padding: 11px 10px;
    overflow-wrap: anywhere;
    vertical-align: middle;
}

.processing-page .processing-table--operations th:nth-child(1),
.processing-page .processing-table--operations td:nth-child(1) {
    width: 10%;
}

.processing-page .processing-table--operations th:nth-child(2),
.processing-page .processing-table--operations td:nth-child(2) {
    width: 16%;
}

.processing-page .processing-table--operations th:nth-child(3),
.processing-page .processing-table--operations td:nth-child(3) {
    width: 13%;
}

.processing-page .processing-table--operations th:nth-child(4),
.processing-page .processing-table--operations td:nth-child(4) {
    width: 12%;
}

.processing-page .processing-table--operations th:nth-child(5),
.processing-page .processing-table--operations td:nth-child(5) {
    width: 17%;
}

.processing-page .processing-table--operations th:nth-child(6),
.processing-page .processing-table--operations td:nth-child(6) {
    width: 17%;
}

.processing-page .processing-table--operations th:nth-child(7),
.processing-page .processing-table--operations td:nth-child(7) {
    width: 15%;
}

.processing-table-scroll {
    min-height: 0;
    overflow-y: auto;
    padding-right: 6px;
    scrollbar-width: thin;
    scrollbar-color: var(--barre-pouce) var(--barre-piste);
}

.processing-table-scroll--operations {
    max-height: 760px;
}

.processing-table-scroll .processing-table {
    margin-bottom: 0;
    /*
     * `border-collapse: collapse` ET UNE ENTETE COLLANTE NE VONT PAS ENSEMBLE.
     *
     * Bordures fusionnees, les fonds de cellules d'en-tete sont peints dans la
     * couche du TABLEAU, pas dans celle de la cellule : le `z-index` de la
     * cellule ne les fait pas remonter, et les lignes defilaient PAR-DESSUS
     * l'entete. On lisait les deux l'un sur l'autre.
     *
     * En bordures separees, chaque cellule peint son propre fond et l'entete
     * couvre ce qui passe dessous. L'espacement est remis a zero pour que rien
     * ne bouge visuellement.
     */
    border-collapse: separate;
    border-spacing: 0;
}

.processing-table-scroll .processing-table thead th {
    position: sticky;
    top: 0;
    z-index: 3;
    /*
     * FOND OPAQUE, ET PAS DE FLOU. Les 3 % de transparence laissaient deviner
     * la ligne qui passe dessous, et le flou d'arriere-plan etendait ce halo
     * au-dela de l'entete. Une entete qui laisse voir le contenu n'est plus
     * une entete : elle se lit comme une ligne de plus.
     */
    background: rgb(var(--slate-mid-rgb));
    /* En bordures separees, le trait du bas doit etre porte par la cellule. */
    border-bottom: 1px solid rgba(var(--white-rgb), 0.12);
}

.processing-table-scroll::-webkit-scrollbar {
    width: 10px;
    height: 10px;
}

.processing-table-scroll::-webkit-scrollbar-track {
    background: transparent;
}

.processing-table-scroll::-webkit-scrollbar-thumb {
    background: linear-gradient(
        180deg,
        rgba(var(--white-rgb), 0.18),
        rgba(var(--white-rgb), 0.08)
    );
    border-radius: 999px;
    border: 2px solid transparent;
    background-clip: padding-box;
}

.processing-table-scroll::-webkit-scrollbar-thumb:hover {
    background: linear-gradient(
        180deg,
        rgba(var(--white-rgb), 0.28),
        rgba(var(--white-rgb), 0.14)
    );
    border: 2px solid transparent;
    background-clip: padding-box;
}

.processing-operation-partner {
    min-width: 0;
}

.processing-operation-partner strong {
    color: rgba(var(--white-rgb), 0.94);
    font-size: 14px;
    line-height: 1.3;
    font-weight: 400;
}

.processing-transaction-type {
    display: inline-flex;
    align-items: center;
    min-height: 28px;
    padding: 0 9px;
    border-radius: 999px;
    background: rgba(var(--blue-light-rgb), 0.12);
    border: 1px solid rgba(var(--blue-light-rgb), 0.22);
    color: var(--blue-mist);
    font-size: 12px;
    line-height: 1;
    font-weight: 400;
}

.processing-values-list {
    display: grid;
    gap: 7px;
}

.processing-values-list > div {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
}

.processing-values-list span,
.processing-balance-state span {
    color: rgba(var(--white-rgb), var(--voile-mention, 0.58));
    font-size: 12px;
    line-height: 1.25;
}

.processing-values-list strong {
    font-size: 14px;
    line-height: 1;
    font-weight: 400;
    white-space: nowrap;
}

.processing-value--positive {
    color: var(--green-soft);
}

.processing-value--negative {
    color: var(--red-soft);
}

.processing-value--reserved {
    color: var(--amber-soft);
}

.processing-value--muted {
    color: rgba(var(--white-rgb), var(--voile-mention, 0.58));
}

/* Trois colonnes imposees dans une cellule de tableau etroite ne tenaient pas :
   138 px pour trois cases, moins les ecarts et les marges interieures, laissent
   26 px de texte, et « Reserve » comme « Disponible » se coupaient en plein
   milieu d'un mot. `auto-fit` avec un minimum reel garde les trois cases cote a
   cote quand la place existe, et les empile quand elle manque : un mot entier
   sur deux lignes se lit, un mot coupe en deux ne se lit pas. */
.processing-balance-state {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(84px, 1fr));
    gap: 6px;
}

/* Le libelle ne se coupe plus au milieu : s'il manque vraiment la place, c'est
   la case qui passe a la ligne, pas le mot qui se brise. */
.processing-balance-state span {
    white-space: nowrap;
}

.processing-balance-state > div {
    display: grid;
    gap: 4px;
    padding: 8px;
    border-radius: 12px;
    background: rgba(var(--white-rgb), 0.04);
    border: 1px solid rgba(var(--white-rgb), 0.08);
}

.processing-balance-state strong {
    color: rgba(var(--white-rgb), 0.92);
    font-size: 15px;
    line-height: 1;
    font-weight: 400;
}

.processing-balance-state__available {
    background: rgba(var(--share-bright-rgb), 0.08) !important;
    border-color: rgba(var(--share-bright-rgb), 0.18) !important;
}

.processing-balance-state__available strong {
    color: var(--couleur-succes-doux);
}

.processing-operation-description {
    color: rgba(var(--white-rgb), 0.82);
    line-height: 1.4;
}

.processing-transaction-adjustment {
    width: 100%;
    min-width: 0;
    max-width: 100%;
    box-sizing: border-box;
}

.processing-transaction-adjustment > summary {
    list-style: none;
}

.processing-transaction-adjustment > summary::-webkit-details-marker {
    display: none;
}

.processing-transaction-adjustment__toggle {
    display: inline-flex;
    align-items: center;
    justify-content: center;

    width: 100%;
    max-width: 100%;
    min-width: 0;
    min-height: 36px;
    box-sizing: border-box;

    padding: 0 10px;
    line-height: 1;
    white-space: nowrap;
    cursor: pointer;
}

.processing-page .processing-table--operations td:last-child {
    overflow: hidden;
}

.processing-transaction-adjustment[open]
.processing-transaction-adjustment__toggle {
    margin-bottom: 9px;
}

.processing-transaction-adjustment__form {
    display: grid;
    gap: 8px;
}

.processing-transaction-adjustment__form .processing-field {
    gap: 4px;
    font-weight: 400;
}

.processing-transaction-adjustment__form .processing-input,
.processing-transaction-adjustment__form .btn {
    width: 100%;
    min-width: 0;
    box-sizing: border-box;
}

.processing-transaction-adjustment__form .processing-input {
    min-height: 42px;
    padding: 7px 9px;
}

.processing-transaction-adjustment__form .btn {
    /* Ce bouton se pose au bout d'une ligne de saisie : il prend la hauteur du
       champ, pas celle des boutons compacts. Dans une ligne de formulaire,
       c'est le voisinage qui commande, pas la famille du composant. */
    min-height: 42px;
    justify-content: center;
}

.processing-page tr.is-hidden {
    display: none;
}

@media (max-width: 1180px) {
    .processing-settings-grid {
        grid-template-columns: 1fr;
    }
}

@media (max-width: 780px) {
    .processing-section-head {
        flex-direction: column;
    }

    .processing-transactions-search {
        width: 100%;
        justify-content: stretch;
    }

    .processing-transactions-search .admin-users-panel__search-wrap {
        max-width: none;
    }

    .processing-table-scroll--operations {
        max-height: 560px;
    }
}

/* ===== Admin help articles ===== */

.admin-help-form-grid {
    display: grid;
    grid-template-columns: minmax(0, 1.45fr) minmax(320px, 0.55fr);
    gap: 18px;
    align-items: start;
}

.admin-help-form-main,
.admin-help-form-side {
    padding: 18px;
}

.admin-help-form-side {
    position: sticky;
    top: 18px;
    display: flex;
    flex-direction: column;
    gap: 14px;
}

.admin-help-field-hint {
    margin: -8px 0 16px;
    font-size: 13px;
    line-height: 1.45;
}

.admin-help-field-hint code {
    padding: 2px 6px;
    border-radius: 8px;
    background: rgba(var(--white-rgb), 0.06);
    color: var(--couleur-accent-doux);
}

.admin-help-body-field {
    min-height: 360px;
    font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", monospace;
    line-height: 1.5;
}

.admin-help-checkbox {
    margin: 2px 0 0;
}

.admin-help-side-note {
    padding: 12px;
    border-radius: 14px;
    background: rgba(var(--blue-rgb), 0.10);
    border: 1px solid rgba(var(--blue-rgb), 0.22);
    color: rgba(var(--blue-mist-rgb), 0.86);
    font-size: 13px;
    line-height: 1.45;
}

/*
 * Les versions de la fiche dans les autres langues.
 *
 * Bloc a part sous le formulaire principal, et non une colonne : les textes
 * d'aide sont longs, et l'admin compare sa traduction au socle en lisant de
 * haut en bas.
 */
.admin-help-translations {
    margin-top: 18px;
    padding: 18px;
    display: flex;
    flex-direction: column;
    gap: 14px;
}

.admin-help-translation {
    padding: 16px;
    border-radius: 14px;
    border: 1px solid rgba(var(--slate-light-rgb), 0.18);
    background: rgba(var(--slate-rgb), 0.28);
    display: flex;
    flex-direction: column;
    gap: 10px;
}

.admin-help-translation__head {
    display: flex;
    align-items: baseline;
    gap: 10px;
    flex-wrap: wrap;
    margin-bottom: 4px;
}

.admin-help-translation .admin-help-body-field {
    min-height: 220px;
}

.admin-help-locale-pill {
    display: inline-block;
    margin-right: 6px;
    padding: 2px 8px;
    border-radius: 999px;
    border: 1px solid rgba(var(--blue-rgb), 0.28);
    background: rgba(var(--blue-rgb), 0.12);
    color: rgba(var(--blue-mist-rgb), 0.9);
    font-size: 12px;
    letter-spacing: 0.04em;
}

@media (max-width: 900px) {
    .admin-help-form-grid {
        grid-template-columns: 1fr;
    }

    .admin-help-form-side {
        position: static;
    }
}

/* ===== Admin help media ===== */

.admin-help-media-layout {
    display: grid;
    grid-template-columns: minmax(320px, 0.75fr) minmax(0, 1.45fr);
    gap: 18px;
    align-items: start;
}

.admin-help-media-upload,
.admin-help-media-list-card {
    padding: 18px;
}

.admin-help-media-upload {
    position: sticky;
    top: 18px;
}

.admin-help-media-list-head {
    margin-bottom: 14px;
}

.admin-help-media-filter {
    margin-bottom: 16px;
}

.admin-help-media-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
    gap: 14px;
}

.admin-help-media-card {
    display: flex;
    flex-direction: column;
    overflow: hidden;
    border-radius: 18px;
    background: rgba(var(--white-rgb), 0.04);
    border: 1px solid rgba(var(--white-rgb), 0.08);
}

.admin-help-media-card__preview {
    position: relative;
    overflow: hidden;
    background: rgb(var(--black-rgb));
    aspect-ratio: 16 / 9;
}

.admin-help-media-card__preview img,
.admin-help-media-card__preview video {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.admin-help-media-card__body {
    display: grid;
    gap: 8px;
    padding: 12px;
}

.admin-help-media-card__title {
    color: var(--ink-50);
    font-size: 15px;
    font-weight: 800;
    line-height: 1.25;
}

.admin-help-media-card__meta,
.admin-help-media-card__caption {
    font-size: 12px;
    line-height: 1.35;
}

.admin-help-media-code {
    display: block;
    padding: 7px 8px;
    border-radius: 10px;
    background: rgba(var(--slate-rgb), 0.68);
    color: var(--couleur-accent-doux);
    font-size: 12px;
    overflow-x: auto;
}

.admin-help-media-card__actions {
    display: flex;
    gap: 8px;
    flex-wrap: wrap;
    margin-top: 4px;
}

.admin-help-media-card__actions form {
    margin: 0;
}

.admin-help-media-card__actions .btn {
    width: auto;
}

.admin-help-media-picker {
    padding: 12px;
    border-radius: 14px;
    background: rgba(var(--slate-rgb), 0.26);
    border: 1px solid rgba(var(--white-rgb), 0.08);
}

.admin-help-media-picker__head {
    display: flex;
    justify-content: space-between;
    align-items: flex-start;
    gap: 10px;
    margin-bottom: 10px;
}

.admin-help-media-picker__title {
    color: var(--ink-50);
    font-size: 14px;
    font-weight: 800;
    line-height: 1.25;
}

.admin-help-media-picker__hint {
    margin-top: 3px;
    font-size: 12px;
    line-height: 1.35;
}

.admin-help-media-picker__link {
    width: auto;
    padding: 7px 10px;
    font-size: 13px;
}

.admin-help-media-picker__list {
    display: grid;
    gap: 8px;
    max-height: 340px;
    overflow-y: auto;
    padding-right: 4px;
}

.admin-help-media-picker__item {
    appearance: none;
    width: 100%;
    display: grid;
    gap: 4px;
    padding: 9px 10px;
    border-radius: 12px;
    border: 1px solid rgba(var(--white-rgb), 0.08);
    background: rgba(var(--white-rgb), 0.04);
    color: inherit;
    text-align: left;
    cursor: pointer;
}

.admin-help-media-picker__item:hover {
    background: rgba(var(--blue-rgb), 0.12);
    border-color: rgba(var(--blue-light-rgb), 0.24);
}

.admin-help-media-picker__type {
    color: rgba(var(--blue-pale-rgb), 0.72);
    font-size: 11px;
    font-weight: 800;
    line-height: 1.2;
    text-transform: uppercase;
    letter-spacing: 0.04em;
}

.admin-help-media-picker__name {
    color: var(--ink-50);
    font-size: 13px;
    line-height: 1.3;
    font-weight: 700;
}

.admin-help-media-picker__item code {
    color: var(--couleur-accent-doux);
    font-size: 12px;
    overflow-wrap: anywhere;
}

.admin-help-media-picker__empty {
    font-size: 13px;
    line-height: 1.4;
}

@media (max-width: 980px) {
    .admin-help-media-layout {
        grid-template-columns: 1fr;
    }

    .admin-help-media-upload {
        position: static;
    }
}

@media (max-width: 640px) {
    .admin-help-media-card__actions {
        align-items: stretch;
        flex-direction: column;
    }

    .admin-help-media-card__actions .btn,
    .admin-help-media-card__actions form {
        width: 100%;
    }
}

.admin-dashboard__top-grid {
    display: grid;
    grid-template-columns: minmax(0, 1.35fr) minmax(320px, 0.65fr);
    gap: 16px;
    align-items: start;
}

.admin-processing-orders {
    display: flex;
    flex-direction: column;
    gap: 14px;
}

.admin-processing-table-wrap {
    overflow-x: auto;
}

.admin-processing-table {
    width: 100%;
    min-width: 650px;
    border-collapse: collapse;
}

.admin-processing-table th,
.admin-processing-table td {
    padding: 10px 9px;
    border-bottom: 1px solid rgba(var(--white-rgb), 0.08);
    text-align: left;
    vertical-align: top;
    font-size: 13px;
    line-height: 1.35;
}

.admin-processing-table th {
    font-size: 11px;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    opacity: 0.62;
}

.admin-processing-table__date {
    white-space: nowrap;
    opacity: 0.8;
}

.admin-dashboard__activity {
    display: grid;
    grid-template-columns: 0.985fr 2.015fr;
    gap: 16px;
    align-items: start;
}

.admin-support-card {
    display: flex;
    flex-direction: column;
    gap: 14px;
}

@media (max-width: 1180px) {
    .admin-dashboard__top-grid,
    .admin-dashboard__activity {
        grid-template-columns: 1fr;
    }
}

/* =========================================
   Admin: лендинг-презентация
   ========================================= */

.landing-presentation-admin {
    gap: 18px;
}

.landing-presentation-slide {
    display: grid;
    gap: 20px;
    padding: 20px;
}

.landing-presentation-slide__head {
    align-items: flex-start;
}

.landing-presentation-form {
    display: grid;
    gap: 16px;
}

.landing-presentation-grid {
    display: grid;
    gap: 14px;
}

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

.landing-presentation-grid--option-meta {
    grid-template-columns: minmax(0, 1fr) 120px;
}

.landing-presentation-field {
    display: grid;
    gap: 7px;
    min-width: 0;
    font-size: 13px;
    font-weight: 800;
    color: rgba(var(--white-rgb), 0.82);
}

.landing-presentation-field--wide {
    grid-column: 1 / -1;
}

.landing-presentation-field input,
.landing-presentation-field textarea,
.landing-presentation-field select {
    width: 100%;
    min-height: 42px;
    padding: 10px 12px;
    border: 1px solid rgba(var(--white-rgb), 0.10);
    border-radius: 12px;
    background: rgba(var(--white-rgb), 0.04);
    color: inherit;
    outline: none;
}

.landing-presentation-field textarea {
    resize: vertical;
    line-height: 1.5;
}

.landing-presentation-field select {
    cursor: pointer;
}

.landing-presentation-field input:focus,
.landing-presentation-field textarea:focus,
.landing-presentation-field select:focus {
    border-color: rgba(var(--white-rgb), 0.24);
    background: rgba(var(--white-rgb), 0.06);
    box-shadow: 0 0 0 3px rgba(var(--white-rgb), 0.05);
}

.landing-presentation-actions {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 14px;
    flex-wrap: wrap;
}

.landing-presentation-check {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    color: rgba(var(--white-rgb), 0.78);
    font-size: 14px;
    line-height: 1.35;
    cursor: pointer;
}

.landing-presentation-check input {
    accent-color: var(--green-mid);
}

.landing-presentation-options {
    display: grid;
    gap: 14px;
    padding-top: 18px;
    border-top: 1px solid rgba(var(--white-rgb), 0.08);
}

.landing-presentation-options__grid {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 14px;
}

.landing-presentation-option-card {
    display: grid;
    gap: 13px;
    min-width: 0;
    padding: 16px;
    border-radius: 18px;
    border: 1px solid rgba(var(--white-rgb), 0.08);
    background: rgba(var(--white-rgb), 0.04);
}

.landing-presentation-option-card__head {
    display: flex;
    justify-content: space-between;
    align-items: flex-start;
    gap: 12px;
}

.landing-presentation-option-card__title {
    color: rgba(var(--white-rgb), 0.96);
    font-size: 17px;
    line-height: 1.3;
    font-weight: 900;
}

.landing-presentation-option-card__meta {
    margin-top: 4px;
    color: rgba(var(--white-rgb), var(--voile-mention, 0.58));
    font-size: 12px;
    line-height: 1.35;
}

.landing-presentation-admin code {
    padding: 2px 6px;
    border-radius: 8px;
    background: rgba(var(--slate-rgb), 0.52);
    color: var(--couleur-accent-doux);
    font-size: 12px;
}

@media (max-width: 1180px) {
    .landing-presentation-options__grid {
        grid-template-columns: 1fr;
    }
}

@media (max-width: 780px) {
    .landing-presentation-grid--slide,
    .landing-presentation-grid--option-meta {
        grid-template-columns: 1fr;
    }

    .landing-presentation-actions {
        align-items: stretch;
        flex-direction: column;
    }

    .landing-presentation-actions .btn {
        width: 100%;
    }
}

/* ===== Landing presentation: сценарий презентации ===== */

.landing-presentation-slide--create {
    border-color: rgba(var(--blue-light-rgb), 0.18);
    background:
        radial-gradient(circle at 0% 0%, rgba(66, 95, 71, 0.6), transparent 38%),
        rgba(54, 82, 51, 0.4);
}

.landing-presentation-head-actions {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap: 10px;
    flex-wrap: wrap;
}

.landing-presentation-option-create {
    display: grid;
    gap: 14px;
    padding: 16px;
    border-radius: 18px;
    border: 1px dashed rgba(var(--blue-soft-rgb), 0.26);
    background: radial-gradient(circle at 0% 0%, rgba(var(--blue-rgb), 0.08), transparent 40%),
        rgba(var(--white-rgb), 0.025);
}

.landing-presentation-option-create__head h4 {
    margin: 0;
    color: rgba(var(--white-rgb), 0.96);
    font-size: 18px;
    line-height: 1.25;
}

.landing-presentation-option-create__head p {
    margin: 5px 0 0;
    color: rgba(var(--white-rgb), 0.68);
    font-size: 13px;
    line-height: 1.4;
}

.landing-presentation-grid--option-create {
    grid-template-columns: repeat(2, minmax(0, 1fr));
}

.landing-presentation-option-card__form {
    display: grid;
    gap: 13px;
    min-width: 0;
}

.landing-presentation-delete-form {
    display: flex;
    justify-content: flex-end;
    margin: -2px 0 0;
    padding-top: 12px;
    border-top: 1px solid rgba(var(--white-rgb), 0.06);
}

.landing-presentation-danger-btn {
    border-color: rgba(var(--teinte-rouge), 0.26);
    color: var(--couleur-danger-doux);
    background: rgba(var(--red-deep-rgb), 0.20);
}

.landing-presentation-danger-btn:hover {
    border-color: rgba(var(--teinte-rouge), 0.42);
    background: rgba(var(--red-deep-rgb), 0.32);
}

@media (max-width: 900px) {
    .landing-presentation-grid--option-create {
        grid-template-columns: 1fr;
    }

    .landing-presentation-head-actions {
        justify-content: flex-start;
    }
}

@media (max-width: 640px) {
    .landing-presentation-delete-form {
        justify-content: stretch;
    }

    .landing-presentation-delete-form .btn,
    .landing-presentation-head-actions form,
    .landing-presentation-head-actions .btn {
        width: 100%;
    }
}

.landing-presentation-field select {
    background: rgba(var(--white-rgb), 0.04);
    color: rgba(var(--white-rgb), 0.92);
    color-scheme: dark;
}

.landing-presentation-field select option {
    background: var(--slate-mid);
    color: var(--ink-50);
}

.landing-presentation-field select option:checked {
    background: #4056c9;
    color: var(--white);
}

.landing-presentation-field select option:disabled {
    color: rgba(var(--white-rgb), 0.48);
}
/* =========================================
   Admin: лендинг-презентация — компактный редактор
   ========================================= */

.landing-presentation-nav {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 12px 14px;
    position: static;
    z-index: auto;
    backdrop-filter: blur(14px);
    -webkit-backdrop-filter: blur(14px);
}

.landing-presentation-nav__label {
    flex: 0 0 auto;
    color: rgba(var(--white-rgb), var(--voile-mention, 0.62));
    font-size: 13px;
    font-weight: 800;
}

.landing-presentation-nav__links {
    display: flex;
    gap: 8px;
    flex-wrap: wrap;
    min-width: 0;
}

.landing-presentation-nav__link {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    min-height: 30px;
    padding: 6px 10px;
    border-radius: 999px;
    border: 1px solid rgba(var(--white-rgb), 0.08);
    background: rgba(var(--white-rgb), 0.04);
    color: rgba(var(--white-rgb), 0.86);
    text-decoration: none;
    font-size: 13px;
    line-height: 1.2;
}

.landing-presentation-nav__link:hover {
    background: rgba(var(--white-rgb), 0.09);
    border-color: rgba(var(--white-rgb), 0.16);
    color: var(--white);
}

.landing-presentation-nav__link small {
    color: rgba(var(--white-rgb), var(--voile-mention, 0.58));
    font-size: 11px;
    font-weight: 800;
}

.landing-presentation-collapse,
.landing-presentation-subcollapse,
.landing-presentation-option-collapse {
    min-width: 0;
}

.landing-presentation-collapse > summary,
.landing-presentation-subcollapse > summary,
.landing-presentation-option-collapse > summary {
    list-style: none;
    cursor: pointer;
}

.landing-presentation-collapse > summary::-webkit-details-marker,
.landing-presentation-subcollapse > summary::-webkit-details-marker,
.landing-presentation-option-collapse > summary::-webkit-details-marker {
    display: none;
}

.landing-presentation-collapse__summary {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 14px;
    min-width: 0;
    padding: 2px 0;
}

.landing-presentation-collapse__summary::before,
.landing-presentation-subcollapse__summary::before,
.landing-presentation-option-collapse__summary::before {
    content: "▸";
    flex: 0 0 auto;
    color: rgba(var(--white-rgb), var(--voile-mention, 0.58));
    font-size: 14px;
    line-height: 1.35;
    transition: transform .18s ease, color .18s ease;
}

.landing-presentation-collapse[open] > .landing-presentation-collapse__summary::before,
.landing-presentation-subcollapse[open] > .landing-presentation-subcollapse__summary::before,
.landing-presentation-option-collapse[open] > .landing-presentation-option-collapse__summary::before {
    transform: rotate(90deg);
    color: rgba(var(--white-rgb), 0.86);
}

.landing-presentation-collapse__main,
.landing-presentation-option-collapse__main {
    flex: 1 1 auto;
    display: grid;
    gap: 5px;
    min-width: 0;
}

.landing-presentation-collapse__main strong,
.landing-presentation-option-collapse__main strong {
    color: rgba(var(--white-rgb), 0.96);
    font-size: 20px;
    line-height: 1.25;
    font-weight: 900;
}

.landing-presentation-option-collapse__main strong {
    font-size: 16px;
}

.landing-presentation-collapse__main span,
.landing-presentation-option-collapse__main span {
    color: rgba(var(--white-rgb), var(--voile-mention, 0.62));
    font-size: 13px;
    line-height: 1.35;
}

.landing-presentation-collapse__badges {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    justify-content: flex-end;
    gap: 8px;
    flex-wrap: wrap;
}

.landing-presentation-mini-badge {
    display: inline-flex;
    align-items: center;
    min-height: 30px;
    padding: 0 10px;
    border-radius: 999px;
    background: rgba(var(--white-rgb), 0.08);
    border: 1px solid rgba(var(--white-rgb), 0.08);
    color: rgba(var(--white-rgb), 0.72);
    font-size: 12px;
    font-weight: 800;
    white-space: nowrap;
}

.landing-presentation-collapse__body {
    display: grid;
    gap: 14px;
    padding-top: 18px;
}

.landing-presentation-subcollapse {
    border: 1px solid rgba(var(--white-rgb), 0.08);
    border-radius: 16px;
    background: rgba(var(--white-rgb), 0.02);
    overflow: hidden;
}

.landing-presentation-subcollapse__summary {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 13px 14px;
    background: rgba(var(--slate-rgb), 0.24);
}

.landing-presentation-subcollapse__summary span {
    color: rgba(var(--white-rgb), 0.92);
    font-size: 15px;
    font-weight: 900;
    line-height: 1.25;
}

.landing-presentation-subcollapse__summary small {
    margin-left: auto;
    color: rgba(var(--white-rgb), 0.52);
    font-size: 12px;
    line-height: 1.3;
    text-align: right;
}

.landing-presentation-subcollapse__body {
    display: grid;
    gap: 14px;
    padding: 15px;
}

.landing-presentation-options__head {
    align-items: flex-start;
}

.landing-presentation-option-collapse {
    padding: 0;
    overflow: hidden;
}

.landing-presentation-option-collapse__summary {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 12px;
    padding: 14px 16px;
    min-height: 74px;
}

.landing-presentation-option-collapse__summary:hover {
    background: rgba(var(--white-rgb), 0.04);
}

.landing-presentation-option-collapse__body {
    display: grid;
    gap: 13px;
    padding: 0 16px 16px;
    border-top: 1px solid rgba(var(--white-rgb), 0.06);
}

.landing-presentation-option-collapse[open] .landing-presentation-option-collapse__body {
    padding-top: 15px;
}

.landing-presentation-grid--option-edit {
    grid-template-columns: repeat(2, minmax(0, 1fr));
}

.landing-presentation-option-create {
    margin: 0;
}

.landing-presentation-delete-form--slide {
    margin-top: 0;
}

.landing-presentation-admin :target {
    scroll-margin-top: 90px;
}

@media (max-width: 900px) {
    .landing-presentation-nav {
        position: static;
        align-items: flex-start;
        flex-direction: column;
    }

    .landing-presentation-collapse__summary,
    .landing-presentation-option-collapse__summary {
        align-items: flex-start;
        flex-direction: column;
    }

    .landing-presentation-collapse__badges {
        justify-content: flex-start;
    }

    .landing-presentation-subcollapse__summary {
        align-items: flex-start;
        flex-direction: column;
    }

    .landing-presentation-subcollapse__summary small {
        margin-left: 0;
        text-align: left;
    }

    .landing-presentation-grid--option-edit {
        grid-template-columns: 1fr;
    }
}

/* =========================================
   Admin: выбор промо-изображения для лэндинга
   ========================================= */

.landing-promo-image-field {
    display: grid;
    gap: 9px;
    min-width: 0;
}

.landing-promo-image-picker {
    min-width: 0;
    border-radius: 14px;
    border: 1px solid rgba(var(--white-rgb), 0.08);
    background: rgba(var(--slate-rgb), 0.24);
    overflow: hidden;
}

.landing-promo-image-picker__summary {
    list-style: none;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    min-height: 38px;
    padding: 9px 12px;
    cursor: pointer;
    color: rgba(var(--white-rgb), 0.88);
    font-size: 13px;
    line-height: 1.25;
    font-weight: 800;
}

.landing-promo-image-picker__summary::-webkit-details-marker {
    display: none;
}

.landing-promo-image-picker__summary::after {
    content: "▾";
    color: rgba(var(--white-rgb), 0.52);
    font-size: 12px;
    transition: transform .18s ease;
}

.landing-promo-image-picker[open] .landing-promo-image-picker__summary::after {
    transform: rotate(180deg);
}

.landing-promo-image-picker__summary:hover {
    background: rgba(var(--white-rgb), 0.04);
}

.landing-promo-image-picker__summary small {
    margin-left: auto;
    color: rgba(var(--white-rgb), 0.54);
    font-size: 12px;
    font-weight: 700;
}

.landing-promo-image-picker__grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(132px, 1fr));
    gap: 10px;
    max-height: 360px;
    overflow-y: auto;
    padding: 12px;
    border-top: 1px solid rgba(var(--white-rgb), 0.08);
    scrollbar-width: thin;
    scrollbar-color: var(--barre-pouce) var(--barre-piste);
}

.landing-promo-image-picker__grid::-webkit-scrollbar {
    width: 10px;
}

.landing-promo-image-picker__grid::-webkit-scrollbar-track {
    background: transparent;
}

.landing-promo-image-picker__grid::-webkit-scrollbar-thumb {
    background: rgba(var(--white-rgb), 0.16);
    border-radius: 999px;
    border: 2px solid transparent;
    background-clip: padding-box;
}

.landing-promo-image-picker__item {
    appearance: none;
    display: grid;
    gap: 7px;
    min-width: 0;
    padding: 8px;
    border-radius: 12px;
    border: 1px solid rgba(var(--white-rgb), 0.08);
    background: rgba(var(--white-rgb), 0.04);
    color: inherit;
    text-align: left;
    cursor: pointer;
    transition:
        transform .18s ease,
        background .18s ease,
        border-color .18s ease;
}

.landing-promo-image-picker__item:hover {
    transform: translateY(-1px);
    background: rgba(var(--blue-rgb), 0.12);
    border-color: rgba(var(--blue-light-rgb), 0.26);
}

.landing-promo-image-picker__item.is-selected {
    background: rgba(var(--green-state-rgb), 0.11);
    border-color: rgba(var(--green-state-rgb), 0.34);
    box-shadow: 0 0 0 1px rgba(var(--green-state-rgb), 0.10) inset;
}

.landing-promo-image-picker__thumb {
    display: block;
    width: 100%;
    aspect-ratio: 16 / 9;
    overflow: hidden;
    border-radius: 10px;
    background: rgba(var(--surface-sombre-rgb), 0.72);
    border: 1px solid rgba(var(--white-rgb), 0.06);
}

.landing-promo-image-picker__thumb img {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.landing-promo-image-picker__name {
    color: rgba(var(--white-rgb), 0.94);
    font-size: 13px;
    line-height: 1.25;
    font-weight: 800;
    overflow-wrap: anywhere;
}

.landing-promo-image-picker__item code {
    width: fit-content;
    max-width: 100%;
    overflow-wrap: anywhere;
    color: var(--couleur-accent-doux);
    font-size: 11px;
}

.landing-promo-image-picker__empty {
    margin: 0;
    padding: 10px 12px;
    border-radius: 12px;
    background: rgba(var(--white-rgb), 0.04);
    border: 1px solid rgba(var(--white-rgb), 0.08);
    color: rgba(var(--white-rgb), var(--voile-mention, 0.62));
    font-size: 13px;
    line-height: 1.4;
}

.landing-promo-image-picker__empty code {
    color: var(--couleur-accent-doux);
}

@media (max-width: 760px) {
    .landing-promo-image-picker__grid {
        grid-template-columns: repeat(2, minmax(0, 1fr));
        max-height: 320px;
    }
}

@media (max-width: 460px) {
    .landing-promo-image-picker__grid {
        grid-template-columns: 1fr;
    }
}

/* =========================================
   Admin: статистика лендинг-презентации
   ========================================= */

.landing-presentation-stats {
    gap: 18px;
}

.landing-stats-cards {
    margin-bottom: 0;
}

.landing-stats-layout {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 16px;
    align-items: start;
}

.landing-stats-section {
    display: grid;
    gap: 14px;
    padding: 18px;
    min-width: 0;
}

.landing-stats-section--wide {
    grid-column: 1 / -1;
}

.landing-stats-section__head {
    align-items: flex-start;
}

.landing-stats-table-wrap {
    min-width: 0;
    overflow-x: auto;
}

.landing-stats-table {
    min-width: 0;
}

.landing-stats-table--events {
    min-width: 1180px;
}

.landing-stats-muted-code {
    margin-top: 4px;
    color: rgba(var(--white-rgb), var(--voile-mention, 0.58));
    font-size: 12px;
    line-height: 1.35;
    word-break: break-word;
}

.landing-stats-payload {
    max-width: 320px;
    max-height: 160px;
    margin: 0;
    padding: 8px 10px;
    overflow: auto;
    border-radius: 10px;
    background: rgba(var(--slate-rgb), 0.60);
    color: rgba(var(--couleur-accent-doux-rgb), 0.92);
    font-size: 12px;
    line-height: 1.35;
    white-space: pre-wrap;
    word-break: break-word;
}

.landing-presentation-stats code {
    padding: 2px 6px;
    border-radius: 8px;
    background: rgba(var(--slate-rgb), 0.52);
    color: var(--couleur-accent-doux);
    font-size: 12px;
}

.landing-stats-table strong {
    display: inline-block;
    color: rgba(var(--white-rgb), 0.94);
    font-size: 15px;
    font-weight: 400;
    line-height: 1.3;
}

.landing-stats-path {
    display: flex;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
    min-width: 220px;
}

.landing-stats-path__item {
    display: inline-grid;
    gap: 3px;
    padding: 7px 9px;
    border-radius: 12px;
    background: rgba(var(--white-rgb), 0.06);
    border: 1px solid rgba(var(--white-rgb), 0.08);
}

.landing-stats-path__item strong {
    color: rgba(var(--white-rgb), 0.92);
    font-size: 13px;
    line-height: 1.25;
}

.landing-stats-path__item code {
    width: fit-content;
}

.landing-stats-path__arrow {
    color: rgba(var(--white-rgb), var(--voile-mention-basse, 0.42));
    font-weight: 900;
}

.landing-stats-table--registrations {
    min-width: 760px;
}

.landing-stats-table--registrations th:nth-child(1),
.landing-stats-table--registrations td:nth-child(1) {
    width: 150px;
}

.landing-stats-table--registrations th:nth-child(2),
.landing-stats-table--registrations td:nth-child(2) {
    width: 220px;
}

.landing-stats-table--registrations th:nth-child(3),
.landing-stats-table--registrations td:nth-child(3) {
    width: auto;
}

@media (max-width: 1180px) {
    .landing-stats-layout {
        grid-template-columns: 1fr;
    }
}

@media (max-width: 760px) {
    .landing-stats-section {
        padding: 14px;
    }

    .landing-stats-table {
        min-width: 720px;
    }

    .landing-stats-table--events {
        min-width: 1080px;
    }
}
/* =========================================
   Admin: лендинг-презентация — новые кнопки
   ========================================= */

.landing-presentation-buttons-grid {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 14px;
}

.landing-presentation-checks-row {
    display: flex;
    align-items: center;
    gap: 14px;
    flex-wrap: wrap;
}

.landing-presentation-mini-badge--gold {
    background: rgba(var(--teinte-or), 0.16);
    border-color: rgba(var(--teinte-or), 0.26);
    color: #fcd899;
}

.landing-presentation-mini-badge--green {
    background: rgba(var(--green-state-rgb), 0.14);
    border-color: rgba(var(--green-state-rgb), 0.28);
    color: var(--green-mid);
}

.landing-presentation-empty {
    padding: 16px;
}

.landing-slide-buttons-list {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 12px;
}

.landing-slide-button-row {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 92px;
    gap: 10px;
    align-items: start;
    padding: 12px;
    border-radius: 16px;
    border: 1px solid rgba(var(--white-rgb), 0.08);
    background: rgba(var(--white-rgb), 0.04);
}

.landing-slide-button-row.is-global {
    border-color: rgba(var(--teinte-or), 0.22);
    background: radial-gradient(circle at 0% 0%, rgba(var(--teinte-or), 0.08), transparent 42%),
        rgba(var(--white-rgb), 0.03);
}

.landing-slide-button-row__check {
    min-width: 0;
}

.landing-slide-button-row__check span {
    display: grid;
    gap: 4px;
    min-width: 0;
}

.landing-slide-button-row__check strong {
    color: rgba(var(--white-rgb), 0.94);
    font-size: 15px;
    line-height: 1.25;
    font-weight: 900;
}

.landing-slide-button-row__check small {
    color: rgba(var(--white-rgb), var(--voile-mention, 0.62));
    font-size: 12px;
    line-height: 1.35;
}

.landing-slide-button-row__sort {
    gap: 5px;
}

.landing-slide-button-row__sort input:disabled,
.landing-slide-button-row__check input:disabled {
    opacity: 0.55;
    cursor: not-allowed;
}

.landing-slide-button-row__badges {
    grid-column: 1 / -1;
    justify-content: flex-start;
}

@media (max-width: 1180px) {
    .landing-presentation-buttons-grid {
        grid-template-columns: 1fr;
    }

    .landing-slide-buttons-list {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }

    .landing-slide-button-row {
        grid-template-columns: minmax(0, 1fr) 92px;
    }
}

@media (max-width: 760px) {
    .landing-slide-buttons-list {
        grid-template-columns: 1fr;
    }

    .landing-slide-button-row {
        grid-template-columns: 1fr;
    }

    .landing-slide-button-row__sort {
        max-width: none;
    }

    .landing-presentation-checks-row {
        align-items: flex-start;
        flex-direction: column;
    }
}

/* =========================================
   Partner journey widget
   ========================================= */

/* --- 2. Le bloc du parcours praticien passe au cyan ---------------------
   C'est LA carte appuyee de la page, celle qui appelle un geste, et a ce titre
   elle a droit au traitement fort. Mais en violet elle appelle vers une
   couleur qui n'existe nulle part ailleurs dans le produit.

   On garde son intensite, on change sa teinte. La comparaison utile est la
   carte d'etape du parcours client : meme role, meme force, et desormais meme
   couleur.
   ------------------------------------------------------------------------ */
.partner-journey-widget.card {
    display: block;
    padding: 18px 20px;
    border-color: rgba(var(--blue-light-rgb), 0.22);
    background: radial-gradient(circle at 0% 0%,
            rgba(var(--portal-accent-rgb), 0.22), transparent 55%),
        rgba(var(--portal-accent-rgb), 0.10);
    border: var(--filet-epaisseur) solid var(--filet-action);
}

.partner-journey-widget__main {
    display: grid;
    gap: 14px;
    min-width: 0;
}

.partner-journey-widget__top {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    gap: 18px;
    align-items: start;
}

.partner-journey-widget__top > div {
    min-width: 0;
}

.partner-journey-widget__eyebrow {
    color: rgba(var(--blue-pale-rgb), 0.72);
    font-size: 12px;
    line-height: 1.2;
    font-weight: 400;
    text-transform: uppercase;
    letter-spacing: 0.07em;
}

.partner-journey-widget__title {
    margin: 8px 0 0;
    color: rgba(var(--white-rgb), 0.98);
    font-size: 24px;
    line-height: 1.25;
}

.partner-journey-widget__text {
    max-width: none;
    width: 100%;
    margin: 7px 0 0;
    color: rgba(var(--white-rgb), 0.74);
    font-size: 14px;
    line-height: 1.5;
}

.partner-journey-widget__counter {
    min-width: 82px;
    padding: 12px 14px;
    border-radius: 16px;
    background: rgba(var(--white-rgb), 0.06);
    border: 1px solid rgba(var(--white-rgb), 0.08);
    text-align: center;
}

.partner-journey-widget__counter strong {
    display: block;
    color: rgba(var(--white-rgb), 0.98);
    font-size: 28px;
    line-height: 1;
    font-weight: 700;
}

.partner-journey-widget__counter span {
    display: block;
    margin-top: 4px;
    color: rgba(var(--white-rgb), var(--voile-mention, 0.62));
    font-size: 12px;
    line-height: 1.2;
}

.partner-journey-widget__bar {
    height: 12px;
    overflow: hidden;
    border-radius: 999px;
    background: rgba(var(--white-rgb), 0.08);
    border: 1px solid rgba(var(--white-rgb), 0.08);
}

.partner-journey-widget__bar span {
    display: block;
    height: 100%;
    border-radius: inherit;
    background: linear-gradient(90deg, rgba(var(--blue-light-rgb), 0.95), rgba(var(--green-state-rgb), 0.82));
}

.partner-journey-widget__current {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    gap: 14px;
    align-items: center;
    padding: 13px 14px;
    border-radius: 16px;
    background: rgba(var(--slate-rgb), 0.28);
    border: 1px solid rgba(var(--white-rgb), 0.08);
}

.partner-journey-widget__current-main {
    display: grid;
    gap: 5px;
    min-width: 0;
}

.partner-journey-widget__current span {
    color: rgba(var(--blue-pale-rgb), 0.68);
    font-size: 12px;
    line-height: 1.2;
    font-weight: 400;
    text-transform: uppercase;
    letter-spacing: 0.05em;
}

.partner-journey-widget__current strong {
    color: rgba(var(--white-rgb), 0.95);
    font-size: 17px;
    line-height: 1.3;
    font-weight: 700;
}

.partner-journey-widget__current p {
    margin: 0;
    color: rgba(var(--white-rgb), 0.70);
    font-size: 13px;
    line-height: 1.45;
}

/* --- Le repli « En savoir plus », troisieme nom du meme objet -------------
   -------------------------------------------------------------------------
   Vu en capture en comparant les deux pages : le meme repli existe sous TROIS
   noms selon l'ecran, `__step__details`, `__now__details` et ici
   `__widget__details`. Les deux premiers ont ete repris sur le parcours ; le
   troisieme gardait sa case, et c'est la plus voyante des trois : une barre
   pleine largeur, fond blanc 0,06, filet 0,09, rayon 14 px, posee au bas du
   bloc cyan ou elle pese autant que le bloc lui-meme.

   Meme regle que les deux autres : le repli est une ligne de texte qu'on peut
   ouvrir, pas une surface.
   ------------------------------------------------------------------------- */
.partner-journey-widget__details {
    margin-top: 2px;
    border-radius: 14px;
    background: none;
    border: 0;
    overflow: hidden;
    padding: 0;
}

.partner-journey-widget__details summary {
    list-style: none;
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    gap: 8px;
    min-height: 34px;
    padding: 0 12px;
    color: rgba(var(--couleur-accent-doux-rgb), 0.94);
    font-size: 13px;
    line-height: 1;
    font-weight: 400;
}

.partner-journey-widget__details summary::-webkit-details-marker {
    display: none;
}

.partner-journey-widget__details summary::after {
    content: "▾";
    color: rgba(var(--white-rgb), 0.66);
    font-size: 12px;
    transition: transform .18s ease;
}

.partner-journey-widget__details[open] summary::after {
    transform: rotate(180deg);
}

.partner-journey-widget__details summary:hover {
    color: var(--white);
    background: rgba(var(--white-rgb), 0.06);
}

.partner-journey-widget__details-body {
    padding: 0 12px 12px;
    color: rgba(var(--white-rgb), 0.76);
    font-size: 13px;
    line-height: 1.5;
}

.partner-journey-widget__path-link {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-height: 34px;
    /*
     * SANS `border-box`, LE BOUTON DEBORDE DE SA CARTE.
     *
     * Sous 900 px il passe en `width: 100%` pour prendre la ligne. En boite
     * de contenu, ces 100 % s'entendent hors rembourrage : 484 px de colonne
     * plus 28 de rembourrage et 2 de bordure faisaient 514, soit 30 px passes
     * par-dessus le bord droit de la carte, pile la largeur qu'on lui ajoute.
     */
    box-sizing: border-box;
    padding: 0 14px;
    border-radius: 999px;
    background: rgba(var(--blue-light-rgb), 0.16);
    border: 1px solid rgba(var(--blue-soft-rgb), 0.26);
    color: rgba(var(--blue-mist-rgb), 0.96);
    font-size: 13px;
    line-height: 1;
    font-weight: 400;
    text-decoration: none;
    white-space: nowrap;
}

.partner-journey-widget__path-link:hover {
    background: rgba(var(--blue-light-rgb), 0.24);
    border-color: rgba(var(--blue-soft-rgb), 0.38);
    color: var(--white);
}

.partner-journey-widget__current--done {
    border-color: rgba(var(--green-state-rgb), 0.24);
    background: rgba(var(--share-bright-rgb), 0.08);
}

.partner-journey-widget__metrics {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
}

.partner-journey-widget__metrics span {
    display: inline-flex;
    align-items: center;
    min-height: 30px;
    padding: 0 10px;
    border-radius: 999px;
    background: rgba(var(--white-rgb), 0.06);
    border: 1px solid rgba(var(--white-rgb), 0.08);
    color: rgba(var(--white-rgb), 0.70);
    font-size: 12px;
    line-height: 1;
    font-weight: 400;
}

.partner-journey-widget__metrics strong {
    margin-left: 5px;
    color: rgba(var(--white-rgb), 0.94);
    font-weight: 400;
}

/* =========================================
   Partner journey page
   ========================================= */

.partner-journey-page {
    gap: 18px;
}

.partner-journey-page .partner-journey-glass {
    position: relative;
    overflow: hidden;
    background: transparent !important;
    isolation: isolate;
}

/* --- 2. LE VERRE : c'est lui qui peint toute la page ---------------------
   -------------------------------------------------------------------------
   PIEGE, ET IL EXPLIQUE POURQUOI RIEN NE PRENAIT. Chaque surface de cette page
   porte `partner-journey-glass`, dont la regle dit
   `background: transparent !important`. La couleur ne vient donc PAS du fond
   de l'element mais de DEUX pseudo-elements poses par-dessus :

     `::before`  une ardoise a 10 % plus `backdrop-filter: blur(24px)
                 saturate(145%)`, soit un flou de verre par surface ;
     `::after`   `var(--partner-journey-glass-tint)`, deux ou trois degrades
                 radiaux, redefini par chaque etat de carte.

   Repeindre `background` sur l'element ne pouvait donc rien donner : la
   declaration passait bien, et restait invisible sous les deux pseudos. Le
   meme piege que le panneau de progression de l'espace praticien, qui n'avait
   aucun fond et se voyait quand meme.

   ON GARDE LA MECANIQUE, ON CHANGE CE QU ELLE PEINT. Le `::before` devient la
   surface levee retenue pour les blocs, le `::after` porte la teinte. C'est
   moins de code qu'une bataille de `!important`, et surtout ca laisse la page
   fonctionner comme elle a ete concue.

   LE FLOU PART. Onze cartes floutees, plus le heros, plus les trois blocs :
   quinze recompositions de la zone situee derriere, a chaque image. La surface
   levee rend le meme service sans rien recomposer. */
.partner-journey-page .partner-journey-glass::before {
    content: "";
    position: absolute;
    inset: 0;
    z-index: 0;
    border-radius: inherit;
    background: rgba(var(--white-rgb), 0.04);
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
    pointer-events: none;
}

.partner-journey-page .partner-journey-glass::after {
    content: "";
    position: absolute;
    inset: 0;
    z-index: 0;
    border-radius: inherit;
    background: none;
    pointer-events: none;
}

.partner-journey-page .partner-journey-glass > * {
    position: relative;
    z-index: 1;
}

.partner-journey-page .journey-shell {
    padding: 22px 24px;
    border-radius: 18px;
    border: 1px solid rgba(216, 180, 254, 0.26);
    background: radial-gradient(circle at 8% 0%, rgba(var(--blue-light-rgb), 0.34), transparent 34%),
        radial-gradient(circle at 92% 10%, rgba(236, 72, 153, 0.22), transparent 34%),
        linear-gradient(135deg, rgba(99, 102, 241, 0.72), rgba(147, 51, 234, 0.62)),
        rgba(76, 29, 149, 0.72);
    box-shadow: 0 24px 68px rgba(30, 27, 75, 0.32),
        inset 0 1px 0 rgba(var(--white-rgb), 0.14);
}

.partner-journey-page .admin-dashboard__eyebrow {
    color: rgba(233, 213, 255, 0.84);
    opacity: 1;
}

.partner-journey-page .admin-dashboard__title {
    color: rgba(var(--white-rgb), 0.98);
    text-shadow: 0 2px 12px rgba(49, 46, 129, 0.32);
}

/* --- 11. La phrase d'accueil retrouve une longueur de ligne --------------
   -------------------------------------------------------------------------
   Le bouton du premier bloc bornait la colonne de texte sans qu'on l'ait
   voulu : en le retirant, la phrase s'est etalee sur toute la largeur du
   bloc. Mesure apres retrait : 1 286 px, soit 145 caracteres par ligne, pour
   un confort de lecture qui se situe entre 65 et 75.

   ON BORNE ICI, ET PAS DANS LA CARTE DE L ETAPE. La difference n'est pas
   d'humeur : la carte de l'etape occupe deja les deux tiers d'une grille,
   c'est elle qui borne la ligne. Ce bloc-ci n'a plus rien qui le borne, donc
   la borne doit etre ecrite.

   78ch et non 65 : c'est une phrase d'accueil sous un titre de 30 px, elle
   supporte d'etre plus large qu'un paragraphe de contenu. Elle tombe a
   environ 690 px, la moitie du bloc.
   ------------------------------------------------------------------------- */
.partner-journey-page .admin-dashboard__text {
    max-width: 78ch;
    color: rgba(var(--white-rgb), 0.86);
    opacity: 1;
}

.partner-journey-page .admin-dashboard__hero-actions .btn {
    border-color: rgba(var(--white-rgb), 0.24);
    background: rgba(var(--white-rgb), 0.13);
    color: rgba(var(--white-rgb), 0.96);
}

.partner-journey-page .admin-dashboard__hero-actions .btn:hover {
    background: rgba(var(--white-rgb), 0.20);
    border-color: rgba(var(--white-rgb), 0.34);
}

.partner-journey-empty {
    padding: 22px;
}

.partner-journey-empty h2 {
    margin: 0 0 8px;
}

.partner-journey-empty p {
    margin: 0;
    color: rgba(var(--white-rgb), 0.74);
    line-height: 1.5;
}

.partner-journey-bottom-cta {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    gap: 18px;
    align-items: center;
    padding: 20px;
    border-radius: 18px;
    border: 1px solid rgba(216, 180, 254, 0.28);
    background:
        radial-gradient(circle at 0% 0%, rgba(125, 211, 252, 0.18), transparent 34%),
        radial-gradient(circle at 100% 0%, rgba(216, 180, 254, 0.16), transparent 36%),
        rgba(var(--slate-mid-rgb), 0.34);
}

.partner-journey-bottom-cta > div:first-child {
    min-width: 0;
}

.partner-journey-bottom-cta__eyebrow {
    margin-bottom: 7px;
    color: rgba(var(--blue-pale-rgb), 0.78);
    font-size: 12px;
    line-height: 1.2;
    font-weight: 400;
    text-transform: uppercase;
    letter-spacing: 0.06em;
}

.partner-journey-bottom-cta h2 {
    margin: 0;
    color: rgba(var(--white-rgb), 0.98);
    font-size: 22px;
    line-height: 1.25;
}

.partner-journey-bottom-cta p {
    margin: 7px 0 0;
    max-width: 820px;
    color: rgba(var(--white-rgb), 0.74);
    font-size: 14px;
    line-height: 1.5;
}

.partner-journey-bottom-cta__actions {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap: 10px;
    flex-wrap: wrap;
}

.partner-journey-bottom-cta {
    margin-top: 2px;
    border-color: rgba(var(--green-soft-rgb), 0.30);
    --partner-journey-glass-tint: radial-gradient(circle at 0% 0%, rgba(var(--share-bright-rgb), 0.22), transparent 36%),
        radial-gradient(circle at 100% 0%, rgba(125, 211, 252, 0.16), transparent 38%),
        rgba(20, 83, 45, 0.16);
}

.partner-journey-step__details {
    position: relative;
    z-index: 1;
    margin-top: 2px;
    border-radius: 14px;
    background: rgba(var(--white-rgb), 0.075);
    border: 1px solid rgba(var(--white-rgb), 0.08);
    overflow: hidden;
    backdrop-filter: blur(14px) saturate(120%);
    -webkit-backdrop-filter: blur(14px) saturate(120%);
}

.partner-journey-step__details summary {
    list-style: none;
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    gap: 8px;
    min-height: 34px;
    padding: 0 11px;
    color: rgba(var(--couleur-accent-doux-rgb), 0.92);
    font-size: 13px;
    line-height: 1;
    font-weight: 400;
}

.partner-journey-step__details summary::-webkit-details-marker {
    display: none;
}

.partner-journey-step__details summary::after {
    content: "▾";
    color: rgba(var(--white-rgb), var(--voile-mention, 0.62));
    font-size: 12px;
    transition: transform .18s ease;
}

.partner-journey-step__details[open] summary::after {
    transform: rotate(180deg);
}

.partner-journey-step__details summary:hover {
    color: var(--white);
    background: rgba(var(--white-rgb), 0.06);
}

.partner-journey-step__details .partner-journey-step__description {
    margin: 0;
    padding: 0 11px 12px;
}

.partner-journey-overview {
    display: grid;
    gap: 14px;
    padding: 20px;
    border-radius: 18px;
    border: 1px solid rgba(216, 180, 254, 0.24);
    --partner-journey-glass-tint: radial-gradient(circle at 0% 0%, rgba(var(--blue-rgb), 0.22), transparent 36%),
        radial-gradient(circle at 100% 0%, rgba(236, 72, 153, 0.16), transparent 38%),
        rgba(67, 56, 202, 0.18);
    box-shadow: 0 20px 52px rgba(var(--slate-rgb), 0.24),
        inset 0 1px 0 rgba(var(--white-rgb), 0.10);
}

.partner-journey-summary-grid {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(320px, 0.72fr);
    gap: 14px;
    align-items: stretch;
}

.partner-journey-summary-grid--compact {
    grid-template-columns: minmax(0, 1fr) minmax(300px, 0.62fr);
}

.partner-journey-summary-card {
    display: grid;
    gap: 10px;
    align-content: start;
    padding: 14px 15px;
    border-radius: 18px;
    background: linear-gradient(135deg, rgba(var(--white-rgb), 0.14), rgba(var(--white-rgb), 0.07)),
        rgba(var(--slate-mid-rgb), 0.28);
    border: 1px solid rgba(var(--white-rgb), 0.15);
    box-shadow: inset 0 1px 0 rgba(var(--white-rgb), 0.10);
    backdrop-filter: blur(14px) saturate(125%);
    -webkit-backdrop-filter: blur(14px) saturate(125%);
}

.partner-journey-summary-card__head {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 12px;
}

.partner-journey-summary-card__head div {
    display: grid;
    gap: 4px;
    min-width: 0;
}

.partner-journey-summary-card__head span {
    color: rgba(233, 213, 255, 0.82);
    font-size: 12px;
    line-height: 1.2;
    font-weight: 400;
    text-transform: uppercase;
    letter-spacing: 0.05em;
}

.partner-journey-summary-card__head strong {
    color: rgba(var(--white-rgb), 0.96);
    font-size: 14px;
    line-height: 1.35;
    font-weight: 400;
}

.partner-journey-summary-card__head em {
    min-width: 58px;
    padding: 7px 10px;
    border-radius: 999px;
    background: rgba(var(--white-rgb), 0.16);
    border: 1px solid rgba(var(--white-rgb), 0.18);
    color: rgba(var(--white-rgb), 0.98);
    font-size: 13px;
    line-height: 1;
    font-style: normal;
    text-align: center;
}

.partner-journey-summary-card.is-expired {
    border-color: rgba(var(--teinte-rouge), 0.28);
    background: radial-gradient(circle at 100% 0%, rgba(var(--teinte-rouge), 0.18), transparent 38%),
        rgba(var(--red-deep-rgb), 0.22);
}

.partner-journey-steps {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 14px;
    align-items: stretch;
}

/* L ETAT PAR DEFAUT, c'est-a-dire « pas encore fait ». Il prend le traitement
   des BLOCS DE CETTE PAGE, celui de « Votre prochaine etape » : la surface
   levee posee par le `::before` du verre, et le filet large.

   Premiere version : l'ardoise 0,7 de `.card`. Vu en capture, elle faisait une
   carte plus DENSE que le bloc juste au-dessus, alors qu'elle dit moins de
   choses. Une etape a venir n'a rien a annoncer ; elle doit peser le moins
   possible, et le moins possible sur cette page est deja defini. */
.partner-journey-page .partner-journey-step {
    position: relative;
    overflow: hidden;
    display: grid;
    grid-template-columns: 1fr;
    gap: 14px;
    min-height: 220px;
    padding: 17px;
    align-content: start;
    border-radius: 14px;
    border: var(--filet-epaisseur) solid var(--filet-large);
    --partner-journey-glass-tint: radial-gradient(circle at 0% 0%, rgba(125, 211, 252, 0.18), transparent 38%),
        radial-gradient(circle at 100% 100%, rgba(var(--blue-rgb), 0.12), transparent 42%),
        rgba(30, 64, 175, 0.14);
    box-shadow: none;
}

.partner-journey-page .partner-journey-step.is-current,
.partner-journey-page .partner-journey-step.is-progress {
    border-color: rgba(216, 180, 254, 0.48);
    --partner-journey-glass-tint:
        radial-gradient(circle at 0% 0%, rgba(232, 121, 249, 0.30), transparent 38%),
        radial-gradient(circle at 100% 100%, rgba(129, 140, 248, 0.24), transparent 44%),
        linear-gradient(135deg, rgba(126, 34, 206, 0.34), rgba(76, 29, 149, 0.24)),
        rgba(88, 28, 135, 0.18);
    box-shadow: 0 22px 58px rgba(88, 28, 135, 0.28),
        inset 0 1px 0 rgba(var(--white-rgb), 0.14);
}

.partner-journey-page .partner-journey-step.is-completed {
    border-color: rgba(var(--green-soft-rgb), 0.42);
    --partner-journey-glass-tint:
        radial-gradient(circle at 0% 0%, rgba(var(--green-soft-rgb), 0.22), transparent 38%),
        radial-gradient(circle at 100% 100%, rgba(129, 140, 248, 0.16), transparent 44%),
        linear-gradient(135deg, rgba(22, 163, 74, 0.24), rgba(88, 28, 135, 0.16)),
        rgba(20, 83, 45, 0.16);
}

.partner-journey-step__marker {
    position: relative;
    z-index: 1;
    width: 44px;
    height: 44px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border-radius: 16px;
    background: rgba(186, 230, 253, 0.18);
    border: 1px solid rgba(186, 230, 253, 0.28);
    color: rgba(var(--ink-50-rgb), 0.96);
    font-size: 16px;
    font-weight: 400;
    box-shadow: inset 0 1px 0 rgba(var(--white-rgb), 0.12);
}

.partner-journey-step.is-current .partner-journey-step__marker,
.partner-journey-step.is-progress .partner-journey-step__marker {
    background: rgba(232, 121, 249, 0.22);
    border-color: rgba(240, 171, 252, 0.42);
    color: var(--violet-pale);
}

.partner-journey-step.is-completed .partner-journey-step__marker {
    background: rgba(var(--share-bright-rgb), 0.20);
    border-color: rgba(var(--green-soft-rgb), 0.38);
    color: var(--green-pale);
}

.partner-journey-step__body {
    position: relative;
    z-index: 1;
    display: grid;
    gap: 10px;
    min-width: 0;
}

.partner-journey-step__top {
    display: flex;
    justify-content: space-between;
    gap: 14px;
    align-items: flex-start;
}

.partner-journey-step__top h2 {
    margin: 0;
    color: rgba(var(--white-rgb), 0.98);
    font-size: 20px;
    line-height: 1.28;
}

.partner-journey-step__top p,
.partner-journey-step__description {
    margin: 6px 0 0;
    color: rgba(var(--white-rgb), 0.78);
    font-size: 14px;
    line-height: 1.5;
}

.partner-journey-step__status {
    display: inline-flex;
    align-items: center;
    min-height: 30px;
    padding: 0 10px;
    border-radius: 999px;
    background: rgba(186, 230, 253, 0.14);
    border: 1px solid rgba(186, 230, 253, 0.22);
    color: rgba(var(--couleur-accent-doux-rgb), 0.92);
    font-size: 12px;
    line-height: 1;
    font-weight: 400;
    white-space: nowrap;
}

.partner-journey-step.is-current .partner-journey-step__status,
.partner-journey-step.is-progress .partner-journey-step__status {
    background: rgba(232, 121, 249, 0.18);
    border-color: rgba(240, 171, 252, 0.34);
    color: var(--violet-pale);
}

.partner-journey-step.is-completed .partner-journey-step__status {
    background: rgba(var(--share-bright-rgb), 0.16);
    border-color: rgba(var(--green-soft-rgb), 0.30);
    color: var(--green-pale);
}

.partner-journey-step__count {
    width: fit-content;
    padding: 7px 10px;
    border-radius: 999px;
    background: rgba(var(--white-rgb), 0.10);
    border: 1px solid rgba(var(--white-rgb), 0.12);
    color: rgba(var(--white-rgb), 0.82);
    font-size: 13px;
    line-height: 1.4;
}

.partner-journey-step__count strong {
    color: rgba(var(--white-rgb), 0.98);
    font-weight: 400;
}

.partner-journey-access__bar {
    height: 10px;
    overflow: hidden;
    border-radius: 999px;
    background: rgba(var(--white-rgb), 0.08);
    border: 1px solid rgba(var(--white-rgb), 0.08);
}

.partner-journey-access__bar span {
    display: block;
    height: 100%;
    border-radius: inherit;
    background: linear-gradient(90deg, rgba(var(--green-rgb), 0.94), rgba(125, 211, 252, 0.88), rgba(216, 180, 254, 0.82));
    transition: width .18s ease;
}

.partner-journey-access__note {
    padding: 9px 10px;
    border-radius: 12px;
    background: rgba(var(--red-rgb), 0.10);
    border: 1px solid rgba(var(--teinte-rouge), 0.22);
    color: var(--couleur-danger-doux);
    font-size: 12px;
    line-height: 1.45;
}

.partner-journey-access.is-expired {
    border-color: rgba(var(--teinte-rouge), 0.24);
    background: rgba(var(--red-deep-rgb), 0.12);
}

.partner-journey-access.is-expired .partner-journey-access__bar span {
    background: rgba(var(--teinte-rouge), 0.82);
}

.partner-pending-diagnostic__locked {
    display: grid;
    gap: 8px;
}

.partner-pending-diagnostic__locked .btn[disabled] {
    opacity: 0.55;
    cursor: not-allowed;
}

.partner-pending-diagnostic__locked-note {
    max-width: 260px;
    color: rgba(var(--white-rgb), 0.78);
    font-size: 12px;
    line-height: 1.35;
}

@media (max-width: 1180px) {
    .partner-journey-steps {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }
}

@media (max-width: 980px) {
    .partner-journey-summary-grid,
    .partner-journey-summary-grid--compact {
        grid-template-columns: 1fr;
    }
}

@media (max-width: 780px) {
    .partner-journey-steps,
    .partner-journey-widget__top,
    .partner-journey-widget__current,
    .partner-journey-now,
    .partner-journey-bottom-cta {
        grid-template-columns: 1fr;
    }

    .partner-journey-now__actions,
    .partner-journey-bottom-cta__actions {
        justify-content: flex-start;
    }

    .partner-journey-now__actions .btn,
    .partner-journey-bottom-cta__actions .btn {
        width: 100%;
        justify-content: center;
    }

    .partner-journey-overview__head,
    .partner-journey-step__top {
        flex-direction: column;
    }

    .partner-journey-widget__path-link {
        width: 100%;
    }
}

/* =========================================
   Admin: путь специалистов
   ========================================= */

.admin-partner-journeys-page {
    gap: 18px;
}

.admin-partner-journey-hero .admin-dashboard__text {
    max-width: none;
}

.admin-partner-journey-hero__stats {
    margin-top: 14px;
}

.admin-partner-journey-hero__stat--warning strong {
    color: var(--red-soft);
}

.admin-partner-journey-select {
    min-width: 260px;
    color-scheme: dark;
    cursor: pointer;
}

.admin-partner-journey-select option {
    background: var(--slate-mid);
    color: var(--ink-50);
}

.admin-partner-journey-select option:checked {
    background: #4056c9;
    color: var(--white);
}

.admin-partner-journey-select option:disabled {
    color: rgba(var(--white-rgb), 0.48);
}

.admin-partner-journeys {
    display: grid;
    gap: 16px;
    padding: 18px;
}

.admin-partner-journeys__head {
    display: block;
}

.admin-partner-journey-filter {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(280px, 420px);
    grid-template-areas:
        "title search"
        "status search";
    gap: 10px 16px;
    align-items: start;
    width: 100%;
}

.admin-partner-journeys__head-main {
    grid-area: title;
    min-width: 0;
}

.admin-partner-journey-filter__search {
    grid-area: search;
    justify-self: end;
    width: 100%;
    min-width: 0;
    max-width: 420px;
}

.admin-partner-journey-filter__status {
    grid-area: status;
    display: grid;
    grid-template-columns: minmax(220px, 320px) 96px;
    gap: 10px;
    align-items: stretch;
    width: min(430px, 100%);
}

.admin-partner-journey-filter .admin-users-panel__search,
.admin-partner-journey-filter .processing-input,
.admin-partner-journey-filter .btn {
    width: 100%;
    height: 42px;
    min-height: 42px;
    box-sizing: border-box;
}

.admin-partner-journey-filter .btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 0 12px;
    line-height: 1;
}

/* LA COLONNE DE DROITE EST PARTIE, ET LA LISTE PREND SA PLACE.

   Elle posait `minmax(0, 1fr) 380px` : un tiers de la largeur pour une fiche
   qui disait « Selectionnez un praticien » tant qu'on n'avait rien choisi, et
   qui redisait ensuite le nom, l'etat et la progression que la ligne porte
   deja. Ce qu'elle portait seule est descendu dans le volet de la ligne. */
.admin-partner-journey-layout {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: 16px;
    align-items: start;
}

/* ET LA LISTE NE DEFILE PLUS DANS SA PROPRE BOITE. Les 850 px de hauteur
   existaient pour que la fiche de droite reste en vue pendant qu'on parcourait
   la liste. Sans elle, cette boite ne fait qu'ajouter une seconde barre de
   defilement a l'interieur de la page -- et un volet ouvert en bas de liste
   s'y retrouvait coupe. */
.admin-partner-journey-list {
    min-width: 0;
    display: grid;
    gap: 12px;
}

/* LES BARRES DE DEFILEMENT DE CES DEUX BOITES SONT PARTIES AVEC ELLES : la
   liste defile maintenant avec la page, et la fiche n'existe plus. */

.admin-partner-journey-table th,
.admin-partner-journey-table td {
    vertical-align: middle;
}

.admin-partner-journey-table th {
    padding-bottom: 6px;
}

/* Le decor de la ligne vient de la grammaire commune (`liste-carte`) : ce
   tableau n'apporte que SA couleur. */
.admin-partner-journey-row {
    --row-rgb: var(--teinte-violette);
    --row-solide: var(--violet-soft);
    cursor: pointer;
}

.admin-partner-journey-row__name {
    display: block;
    color: rgba(var(--white-rgb), 0.96);
    font-size: 16px;
    line-height: 1.25;
    font-weight: 400;
}

.admin-partner-journey-progress {
    display: grid;
    gap: 7px;
    min-width: 150px;
}

.admin-partner-journey-progress__head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    color: rgba(var(--white-rgb), 0.74);
    font-size: 12px;
    line-height: 1.2;
}

.admin-partner-journey-progress__head strong {
    color: rgba(var(--white-rgb), 0.94);
    font-weight: 400;
}

.admin-partner-journey-progress__bar {
    height: 9px;
    overflow: hidden;
    border-radius: 999px;
    background: rgba(var(--white-rgb), 0.08);
    border: 1px solid rgba(var(--white-rgb), 0.08);
}

.admin-partner-journey-progress__bar span {
    display: block;
    height: 100%;
    border-radius: inherit;
    background: linear-gradient(90deg, rgba(var(--blue-light-rgb), 0.94), rgba(var(--consultation-rgb), 0.84), rgba(var(--green-state-rgb), 0.82));
}

.admin-partner-journey-current {
    display: block;
    max-width: 260px;
    color: rgba(var(--white-rgb), 0.88);
    font-size: 13px;
    line-height: 1.35;
}

.admin-partner-journey-status {
    display: inline-flex;
    align-items: center;
    min-height: 28px;
    width: fit-content;
    padding: 0 10px;
    border-radius: 999px;
    background: rgba(var(--white-rgb), 0.08);
    border: 1px solid rgba(var(--white-rgb), 0.10);
    color: rgba(var(--white-rgb), 0.78);
    font-size: 12px;
    line-height: 1;
    font-weight: 400;
    white-space: nowrap;
}

.admin-partner-journey-status.is-active {
    background: rgba(var(--blue-rgb), 0.14);
    border-color: rgba(var(--blue-light-rgb), 0.28);
    color: var(--blue-mist);
}

.admin-partner-journey-status.is-expired {
    background: rgba(var(--red-rgb), 0.14);
    border-color: rgba(var(--teinte-rouge), 0.28);
    color: var(--couleur-danger-doux);
}

.admin-partner-journey-status.is-completed {
    background: rgba(var(--share-bright-rgb), 0.14);
    border-color: rgba(var(--green-soft-rgb), 0.28);
    color: var(--couleur-succes-doux);
}

.admin-partner-journey-status.is-disabled {
    background: rgba(var(--white-rgb), 0.06);
    border-color: rgba(var(--white-rgb), 0.10);
    color: rgba(var(--white-rgb), var(--voile-mention, 0.58));
}

/* =========================================================================
   LE VOLET D UNE LIGNE DE PARCOURS
   =========================================================================
   LA FICHE DE DROITE EST DEVENUE CE VOLET. Elle etait collante, haute d'un
   ecran, et portait son propre defilement ; ici le detail s'ouvre sous la
   ligne qu'on interroge et ne coute de la place que le temps qu'on le regarde.

   LA MECANIQUE DU DEPLI est dans `reprise/composants/ligne-depliante.css`, la
   meme que la liste des clients du praticien. Ce qui suit n'en est que le
   dessin.
   ========================================================================= */

.apj-volet {
    display: grid;
    gap: 12px;
    padding: 14px 16px;

    background: rgba(var(--row-rgb), var(--voile-4, 0.09));
    border-left: 4px solid var(--row-solide, rgb(var(--row-rgb)));
    border-bottom: 1px solid rgba(var(--row-rgb), var(--voile-5, 0.14));
    border-right: 1px solid rgba(var(--row-rgb), var(--voile-5, 0.14));
    border-radius: 0 0 14px 14px;
}

.apj-volet__bloc {
    display: grid;
    gap: 8px;
    padding: 12px;
    border-radius: 14px;
    background: rgba(var(--white-rgb), 0.04);
    border: 1px solid rgba(var(--white-rgb), 0.08);
}

.apj-volet__titre {
    color: rgba(var(--white-rgb), var(--voile-mention, 0.62));
    font-size: 12px;
    text-transform: uppercase;
    letter-spacing: .04em;
}

/* LES QUATRE COMPTEURS TIENNENT SUR UNE LIGNE. Dans la fiche de 380 px ils
   etaient sur deux colonnes ; le volet fait toute la largeur de la liste. */
.apj-volet__compteurs {
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: 10px;
}

.apj-volet__mesure {
    display: grid;
    gap: 2px;
    min-width: 0;
}

.apj-volet__mesure span {
    color: rgba(var(--white-rgb), var(--voile-mention, 0.62));
    font-size: 12px;
}

.apj-volet__mesure strong {
    font-size: 18px;
    line-height: 1.1;
}

/* LES ETAPES EN RANGEE, ET ELLES SE REPLIENT. Une colonne de douze etapes
   faisait, dans la fiche, un volet plus haut que l'ecran. */
.apj-volet__etapes {
    grid-template-columns: 1fr;
}

.apj-volet__etape {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 4px 10px;
    padding: 6px 0;
    border-bottom: 1px solid rgba(var(--white-rgb), 0.06);
}

.apj-volet__etape:last-child {
    border-bottom: 0;
}

.apj-volet__etape strong {
    font-weight: 500;
    color: rgba(var(--white-rgb), var(--voile-mention, 0.72));
}

/* UNE ETAPE FAITE SE LIT SANS COMPTER : c'est la seule qui porte l'encre
   pleine et la pastille. */
.apj-volet__etape.is-completed strong {
    color: rgb(var(--white-rgb));
}

.apj-volet__etape.is-completed strong::before {
    content: '¹3';
    margin-right: 6px;
    color: var(--vert-soft, rgb(var(--teinte-verte)));
}

.apj-volet__etape span {
    color: rgba(var(--white-rgb), var(--voile-mention, 0.55));
    font-size: 12px;
}

/* LES TROIS FORMULAIRES COTE A COTE : le cadre, la masterclasse, la place dans
   le parcours. Ils se replient quand la place manque.

   TOUT CE QUI SE CLIQUE OU SE SAISIT FAIT LA MEME HAUTEUR, et elle est ecrite
   UNE FOIS. Champs et boutons la tenaient chacun de leur cote -- une valeur ici,
   le remplissage d'ailleurs la -- et il suffisait qu'une regle du produit
   rallonge l'un pour que la rangee se decale sans que rien ne le dise.

   `align-items: end` ALIGNE PAR LE BAS, et c'est la bonne ligne : deux des
   trois formulaires portent une etiquette au-dessus de leur champ, le
   troisieme n'est qu'un bouton. Alignes par le haut, le bouton flotterait a
   hauteur d'etiquette. */
.apj-volet__formulaires {
    --apj-hauteur: 38px;

    display: flex;
    flex-wrap: wrap;
    align-items: end;
    gap: 12px;
}

.apj-volet__formulaire {
    display: flex;
    flex-wrap: wrap;
    align-items: end;
    gap: 8px;
    margin: 0;
}

.apj-volet__formulaire .processing-field {
    display: grid;
    gap: 4px;
    min-width: 0;
    margin: 0;
    font-weight: 400;
}

.apj-volet__formulaire .processing-field span {
    color: rgba(var(--white-rgb), var(--voile-mention, 0.62));
    font-size: 12px;
    line-height: 1.25;
}

/* LE SELECTEUR COMPTE AUSSI, et il a sa propre famille de regles dans le
   produit : le nommer explicitement evite qu'il garde la hauteur d'ailleurs. */
.apj-volet__formulaire .processing-input,
.apj-volet__formulaire input.processing-input,
.apj-volet__formulaire select.processing-input,
.apj-volet__formulaire .btn {
    height: var(--apj-hauteur);
    min-height: var(--apj-hauteur);
    max-height: var(--apj-hauteur);
    margin: 0;
    box-sizing: border-box;
    line-height: 1.2;
}

.apj-volet__formulaire input[type="number"].processing-input {
    width: 110px;
}

.apj-volet__formulaire .btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 0 14px;
}

.apj-volet__liens {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
}

/* LE SEUIL DE 1180 PX N A PLUS RIEN A REPLIER : la mise en page est a une
   colonne a toutes les largeurs depuis que la fiche est descendue dans la
   ligne. */

@media (max-width: 980px) {
    .admin-partner-journey-filter {
        grid-template-columns: minmax(0, 1fr) minmax(260px, 360px);
    }

    .admin-partner-journey-filter__search {
        max-width: 360px;
    }
}

@media (max-width: 720px) {
    /* QUATRE COMPTEURS SUR UNE LIGNE DE TELEPHONE feraient quatre colonnes de
       soixante pixels : le libelle passe a la ligne a chaque mot. Deux par
       deux, ils se lisent. */
    .apj-volet__compteurs {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }

    .apj-volet__formulaire,
    .apj-volet__formulaire .processing-field,
    .apj-volet__formulaire .processing-input,
    .apj-volet__formulaire .btn {
        width: 100%;
        max-width: none;
    }

    .apj-volet__formulaire input[type="number"].processing-input {
        width: 100%;
    }

    .admin-partner-journey-filter,
    .admin-partner-journey-filter .admin-users-panel__search-wrap,
    .admin-partner-journey-filter .processing-input,
    .admin-partner-journey-filter .btn {
        width: 100%;
        max-width: none;
    }

    .admin-partner-journey-filter {
        grid-template-columns: 1fr;
        grid-template-areas:
            "title"
            "search"
            "status";
    }

    .admin-partner-journey-filter__search,
    .admin-partner-journey-filter__status {
        width: 100%;
        max-width: none;
    }

    .admin-partner-journey-filter__status {
        grid-template-columns: 1fr;
    }
}

/* LES REGLES DE LA FICHE DE DROITE SONT PARTIES AVEC ELLE : son bloc
   d'actions, son formulaire de cadre et sa grille a deux colonnes. Ce que ces
   formulaires portent vit maintenant dans `.apj-volet__formulaire`, plus haut,
   ou ils sont cote a cote au lieu d'etre empiles dans 340 px. */

/*Подсветка новых обработок с последнего захода*/
.admin-processing-table tbody
tr.admin-processing-table__row--new td {
    background: rgba(78, 166, 112, 0.16);
    border-bottom-color: rgba(var(--teinte-verte), 0.24);
}

.admin-processing-table tbody
tr.admin-processing-table__row--new td:first-child {
    box-shadow: inset 3px 0 0 rgba(var(--teinte-verte), 0.78);
}

.admin-processing-table tbody
tr.admin-processing-table__row--new:hover td {
    background: rgba(78, 166, 112, 0.22);
}

/* --- Facturation d'un compte, dans sa fiche ----------------------------- */

.admin-billing-account__grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
    gap: 12px;
    margin-bottom: 20px;
}

.admin-billing-account__label {
    color: rgba(var(--white-rgb), var(--voile-mention, 0.6));
    font-size: 0.85rem;
}

.admin-billing-account__value {
    font-size: 1.25rem;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
}

.admin-billing-account__note,
.admin-billing-account__ref {
    color: rgba(var(--white-rgb), var(--voile-mention, 0.55));
    font-size: 0.85rem;
}

.admin-billing-account__ref {
    margin-top: 4px;
    font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
    font-size: 0.75rem;
    overflow-wrap: anywhere;
}

.admin-billing-account__empty {
    color: rgba(var(--white-rgb), var(--voile-mention, 0.55));
}

/* Une ligne par code : le code, ce qu'il fait, s'il a servi, et le retrait. */
.admin-billing-codes__row {
    display: grid;
    grid-template-columns: auto 1fr auto auto;
    align-items: center;
    gap: 12px;
    padding: 10px 0;
    border-bottom: 1px solid rgba(var(--white-rgb), 0.08);
}

.admin-billing-codes__row:last-child {
    border-bottom: 0;
}

.admin-billing-codes__code {
    font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
    font-weight: 600;
    letter-spacing: 0.04em;
}

.admin-billing-codes__state {
    color: rgba(var(--white-rgb), var(--voile-mention, 0.55));
    font-size: 0.85rem;
    white-space: nowrap;
}

/* ===== Les acces offerts, en lignes lisibles =====

   Trois travees de texte brut ne disaient ni qui, ni quoi, ni jusqu'a quand
   sans qu'on lise tout. On reprend la grammaire des autres listes : une
   ligne posee sur une teinte, un liseré a gauche qui dit le type de compte,
   et l'etat en pastille a droite. */

.acces-offerts {
    display: flex;
    flex-direction: column;
    gap: 8px;
    margin-top: 14px;
}

.acces-offert {
    display: grid;
    grid-template-columns: minmax(0, 1.1fr) minmax(0, 1.6fr) auto;
    align-items: center;
    gap: 12px 16px;

    padding: 12px 14px;
    border-radius: 10px;

    /* La teinte vient de la ligne, pas d'ici : `--row-rgb` porte le type de
       compte, comme dans /users. */
    border-left: 3px solid rgba(var(--row-rgb), 0.75);
    background: rgba(var(--row-rgb), 0.07);
}

.acces-offert__qui {
    display: flex;
    flex-direction: column;
    gap: 2px;
    min-width: 0;
}

/* Le courriel etait un lien au style par defaut : viole, souligne, plus
   voyant que la personne qu'il designe. Le nom porte le lien, l'adresse
   passe dessous en second plan. */
.acces-offert__nom {
    font-weight: 600;
    color: inherit;
    text-decoration: none;
    overflow-wrap: anywhere;
}

.acces-offert__nom:hover,
.acces-offert__nom:focus-visible {
    text-decoration: underline;
}

.acces-offert__mail {
    font-size: 0.82rem;
    color: rgba(var(--white-rgb), var(--voile-mention, 0.55));
    overflow-wrap: anywhere;
}

.acces-offert__quoi {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 6px 10px;
    min-width: 0;
    font-size: 0.88rem;
}

.acces-offert__formule {
    font-weight: 600;
}

.acces-offert__motif,
.acces-offert__par {
    color: rgba(var(--white-rgb), var(--voile-mention, 0.55));
    overflow-wrap: anywhere;
}

.acces-offert__etat {
    display: flex;
    align-items: center;
    gap: 8px;
    justify-self: end;
}

.acces-offert__puce {
    padding: 3px 10px;
    border-radius: 999px;
    border: 1px solid rgba(var(--white-rgb), 0.16);
    font-size: 0.78rem;
    white-space: nowrap;
    font-variant-numeric: tabular-nums;
}

/* Sans terme : c'est celui qu'on oublie, il doit se voir en premier. */
.acces-offert__puce--sans-terme {
    border-color: rgba(var(--amber-rgb), 0.55);
    background: rgba(var(--amber-rgb), 0.14);
    font-weight: 600;
}

.acces-offert__puce--bientot {
    border-color: rgba(var(--red-rgb), 0.5);
    background: rgba(var(--red-rgb), 0.12);
}

.acces-offert__bientot {
    font-size: 0.78rem;
    color: rgb(var(--red-light-rgb));
}

/* En dessous de 720 px, les trois travees s'empilent : un courriel et un
   motif saisi a la main n'ont pas de longueur connue, et les garder cote a
   cote emportait la page vers la droite. */
@media (max-width: 720px) {
    .acces-offert {
        grid-template-columns: 1fr;
    }

    .acces-offert__etat {
        justify-self: start;
    }
}

.admin-billing-grant {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 10px;
    margin-top: 14px;
}

.admin-billing-orders__row {
    display: grid;
    grid-template-columns: auto 1fr auto auto;
    align-items: center;
    gap: 12px;
    padding: 8px 0;
    border-bottom: 1px solid rgba(var(--white-rgb), 0.08);
    font-variant-numeric: tabular-nums;
}

.admin-billing-orders__row:last-child {
    border-bottom: 0;
}

@media (max-width: 720px) {
    .admin-billing-codes__row,
    .admin-billing-orders__row {
        grid-template-columns: minmax(0, 1fr) auto;
        row-gap: 4px;
    }

    /*
     * Un courriel et un motif saisi a la main n'ont pas de longueur connue.
     * Places en piste `auto`, ils se dimensionnaient sur leur contenu, et la
     * piste s'elargissait autant qu'il le fallait : la ligne sortait de
     * l'ecran, et la page avec elle (355 px de document pour 350 de fenetre
     * a 360 px de large).
     *
     * Ils prennent donc la largeur entiere et se coupent, `1fr` seul ne
     * suffisant pas puisque son plancher est la largeur du plus long mot.
     */
    .admin-billing-codes__code,
    .admin-billing-codes__what {
        grid-column: 1 / -1;
        min-width: 0;
        overflow-wrap: anywhere;
    }
}

/* Le visage en tête de la fiche d'un compte, avec le geste pour le retirer.
   Une photo montrée à des clients doit pouvoir se retirer sans chercher. */
.admin-user-tete {
    display: flex;
    align-items: center;
    gap: 16px;
    margin-bottom: 8px;
}

.admin-user-tete__texte {
    display: flex;
    align-items: center;
    gap: 14px;
    flex-wrap: wrap;
    min-width: 0;
}

.admin-user-tete__texte h1 {
    margin: 0;
}

/* =========================================================================
   LA GRAMMAIRE DES CARTES DU TABLEAU DE BORD

   /partner et /admin repondent a la meme question : qu'est-ce qui se passe
   sur ce compte, et ou vais-je pour agir. Chaque domaine tient dans une carte
   qui dit toujours les memes choses dans le meme ordre : le sujet, l'etat,
   les chiffres, le detail, la porte.

   Les cartes d'une meme rangee alignent leur pied, sinon l'oeil lit une
   colonne bancale la ou il n'y a qu'un contenu plus court.
   ========================================================================= */

.dashboard-grid {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 18px;
    align-items: stretch;
}

/* CETTE REGLE NE PEINT PLUS RIEN : elle ne pose que la mise en page.
   La PEAU du bloc est decidee une seule fois, dans `lk.css`, par la regle
   `.dashboard-card` de la section « Les blocs passent en surface levee (B4) ».

   POURQUOI ELLE PEIGNAIT ENCORE, ET CE QUE CA COUTAIT. Elle declarait
   `background: rgba(--slate-mid, 0.7)` -- de l'ardoise a 70 %, donc une
   surface presque opaque. Les deux regles ont la MEME specificite (0,1,0), et
   cette feuille se charge APRES `lk.css` : a egalite, la derniere ecrite
   gagne. La peau unifiee ne s'appliquait donc nulle part sur /partner ni sur
   /admin, et ces deux espaces gardaient seuls l'ancien aplat gris pendant que
   tout le reste du produit passait en surface levee.

   RIEN N EST PERDU EN LA RETIRANT : `lk.css` porte deja le fond et l'ombre.
   Le repli `@supports` qui vivait ici part avec elle, et c'est correct : il
   rattrapait un fond translucide devenu lisible faute de flou, or la peau
   unifiee pose `backdrop-filter: none` et un fond fixe. Il n'y a plus rien a
   rattraper. */
.dashboard-card {
    display: flex;
    flex-direction: column;
    gap: 14px;
    padding: 20px;
    border-radius: var(--rayon-m);
    box-sizing: border-box;
    min-width: 0;
}

/* Ce qui demande une action passe devant, sur toute la largeur. */
/* --- 1. « Ce qui attend » est le bloc qui appelle un geste ----------------
   -------------------------------------------------------------------------
   Chaque page de la reprise a UN bloc qui dit ce qu'on attend du lecteur, et
   ce bloc porte le cyan et le filet appuye : le parcours sur l'espace
   praticien, « Vous pouvez passer au test » sur le parcours client, le titre
   sur le parcours praticien. Ici c'est « Ce qui attend », et le libelle le dit
   lui-meme : « Ce qui demande une decision de votre part maintenant ».

   IL ETAIT POURTANT LE PLUS DISCRET. Sept blocs identiques a la file, et
   celui qui compte se distinguait seulement par sa largeur. Or la largeur ne
   se lit qu'en comparant ; la teinte se lit tout de suite.

   La recette est recopiee valeur pour valeur de `praticien-essai.css`, pas
   rapprochee a vue : c'est ce qui evite le quatrieme dialecte de cyan.

   COMBIEN PAR ECRAN, ET LA REPONSE A ETE CORRIGEE LE 29/08. Ce paragraphe
   disait « c'est le seul de la page a porter `--filet-action` », en supposant
   qu'une seule carte serait marquee `large`. La mesure a montre le contraire :
   l'espace praticien en portait DEUX, plus le bloc du parcours, soit trois
   cadres appuyes sur un ecran.

   L'intruse etait la carte des reglages de notifications, qui n'avait rien a
   faire ici : le composant definit `large` comme « reservee a ce qui demande
   une action tout de suite ». Elle a perdu la classe.

   RESTENT DEUX BLOCS APPUYES SUR L ESPACE PRATICIEN, et c'est assume : le
   parcours, qui dit quoi faire ensuite, et « Ce qui attend », qui dit ce qui
   reclame une decision maintenant. Ils se lisent en paire, en haut de page,
   avant les cartes ordinaires. L'administration n'en porte qu'un, n'ayant pas
   de parcours. La regle n'est donc pas « un par ecran » mais « un par chose
   qui appelle un geste », et il n'y en a jamais plus de deux.
   ------------------------------------------------------------------------- */
.dashboard-card--large {
    grid-column: 1 / -1;
    background: radial-gradient(circle at 0% 0%,
            rgba(var(--portal-accent-rgb), 0.22), transparent 55%),
        rgba(var(--portal-accent-rgb), 0.10);
    border: var(--filet-epaisseur) solid var(--filet-action);
    box-shadow: none;
}

/* LES 22 px NE VALENT QUE DANS LA GRILLE. Ils detachent la carte accentuee des
   cartes ordinaires, qui la suivent a l'ecart serre de la grille. Sur l'espace
   praticien, elle a quitte la grille pour passer devant le parcours : elle est
   alors dans une colonne dont l'ecart est celui des SECTIONS, et les 22 px
   s'ajoutaient a un ecart deja pris. */
.dashboard-grid > .dashboard-card--large {
    margin-bottom: 22px;
}

/* Les clients portent un tableau : ils tiennent sur deux colonnes, sinon les
   noms se cassent en deux lignes des la premiere ligne. */
.dashboard-card--double {
    grid-column: span 2;
}

/* Un tableau dans une carte n'a pas de fond a lui : la carte le porte deja,
   et une seconde surface ferait un cadre dans un cadre. */
.dashboard-card .responsive-table {
    margin: 0;
}

/* Un tableau ne doit JAMAIS pouvoir deborder de sa carte. Entre le moment ou
   la grille passe a une colonne et celui ou les lignes s'empilent, il reste
   une plage ou cinq colonnes peuvent ne plus tenir : elles defilent alors
   dans leur propre boite, et la page ne part pas de travers.

   La boite est posee dans le gabarit plutot que par `:has()` : elle ne
   concerne qu'un tableau, et le corps des autres cartes ne doit surtout pas
   devenir une zone de defilement. */
.dashboard-card__tableau {
    overflow-x: auto;
}

.dashboard-card__head {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 12px;
}

.dashboard-card__title-area {
    min-width: 0;
}

.dashboard-card__title {
    margin: 0;
    font-size: var(--taille-titre-s);
    font-weight: var(--graisse-titre);
    line-height: 1.25;
}

.dashboard-card__subtitle {
    margin: 4px 0 0;
    font-size: var(--taille-legende);
    line-height: 1.45;
    color: rgba(var(--white-rgb), var(--voile-mention, 0.62));
}

/* L'etat se lit sans lire la carte : une pastille, une teinte, un mot. */
.dashboard-card__state {
    flex: 0 0 auto;
    padding: 4px 10px;
    border-radius: var(--rayon-pilule);
    font-size: var(--taille-mention);
    font-weight: var(--graisse-forte);
    text-transform: uppercase;
    letter-spacing: 0.06em;
    white-space: nowrap;
    border: 1px solid transparent;
}

.dashboard-card__state--muet {
    background: rgba(var(--white-rgb), 0.08);
    border-color: rgba(var(--white-rgb), 0.14);
    color: rgba(var(--white-rgb), 0.66);
}

.dashboard-card__state--ok {
    background: rgba(var(--share-bright-rgb), 0.16);
    border-color: rgba(var(--share-bright-rgb), 0.42);
    /* Le vert de ligne rend 3,17 sur ce voile en clair : l'encre de pastille
       descend d'un cran, le repli garde le vert du sombre. */
    color: rgb(var(--encre-etat-ok-rgb, var(--share-line-rgb)));
}

.dashboard-card__state--attention {
    background: rgba(var(--amber-rgb), 0.16);
    border-color: rgba(var(--amber-rgb), 0.42);
    /* Meme mesure que la pastille verte : 3,89 sur son propre voile en clair. */
    color: rgb(var(--encre-etat-attention-rgb, var(--amber-rgb)));
}

.dashboard-card__state--alerte {
    background: rgba(var(--red-rgb), 0.18);
    border-color: rgba(var(--red-rgb), 0.46);
    color: rgba(var(--red-light-rgb), 1);
}

/* UNE GRILLE, PAS UN ALIGNEMENT LIBRE. En flex, chaque chiffre prend la
   largeur de son libelle : « e-mails en echec » ecarte ses voisins et les
   nombres ne tombent plus sur une verticale. Ils se lisent pourtant en
   balayant la ligne, donc ils doivent etre a intervalle regulier. */
.dashboard-card__figures {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(128px, 1fr));
    gap: 14px 22px;
    padding-bottom: 16px;
    margin-bottom: 4px;
    border-bottom: 1px solid rgba(var(--white-rgb), 0.08);
}

.dashboard-figure {
    display: flex;
    flex-direction: column;
    gap: 3px;
    min-width: 0;
}

/* UN ZERO N'EST PAS UNE NOUVELLE. Sans teinte, un chiffre compte quelque
   chose qui n'attend pas : il s'efface pour que l'oeil tombe d'abord sur ce
   qui demande une decision. Il reste lisible, il ne crie plus. */
/* --- 6. Les chiffres ressortent ----------------------------------------
   MESURE. Le chiffre est a 42 % de blanc, son libelle a 40 %. Ils ont donc la
   meme presence, alors que l'un porte l'information et l'autre l'explique. La
   taille (22 px contre 12) et la graisse (800 contre normale) font tout le
   travail, la couleur n'en fait aucun.

   On rend au chiffre son contraste et on laisse le libelle ou il est : c'est
   l'ECART entre les deux qui se lit, pas leur valeur absolue.

   SELECTEUR RECOPIE A L IDENTIQUE, `:not()` compris. Il vaut (0,3,0) : une
   version plus courte perdrait en silence, ce qui m'est arrive trois fois
   aujourd'hui.

   A NOTER POUR PLUS TARD. La regle d'origine eteint TOUTE figure sans
   modificateur. Si l'intention etait d'eteindre les ZEROS, ce qui se defend,
   il faut une classe posee par le serveur : « rien a voir ici » est une
   information, « pas de modificateur » n'en est pas une.
   ------------------------------------------------------------------------ */
.dashboard-figure:not([class*="dashboard-figure--"]) .dashboard-figure__value {
    color: rgba(var(--white-rgb), 0.88);
}

.dashboard-figure:not([class*="dashboard-figure--"]) .dashboard-figure__label {
    /* LE RETRAIT NE PEUT PAS SE PAYER EN LISIBILITE. Ce libelle recule d'un
       plan par rapport a un chiffre plein ; au cran bas des mentions il rendait
       3,07 en sombre et 3,66 en clair, a 12 px. Le retrait tient deja dans la
       valeur au-dessus (0,88 contre 0,96) : le libelle rejoint le cran des
       mentions, comme son jumeau non qualifie. */
    color: rgba(var(--white-rgb), var(--voile-mention, 0.62));
}

.dashboard-figure__value {
    font-size: var(--taille-titre-m);
    font-weight: var(--graisse-titre);
    line-height: 1.1;
    color: rgba(var(--white-rgb), 0.96);
    font-variant-numeric: tabular-nums;
}

.dashboard-figure__label {
    font-size: var(--taille-legende);
    line-height: 1.3;
    color: rgba(var(--white-rgb), var(--voile-mention, 0.62));
}

.dashboard-figure--ok .dashboard-figure__value { color: rgba(var(--share-line-rgb), 1); }
.dashboard-figure--attention .dashboard-figure__value { color: rgba(var(--amber-rgb), 1); }
.dashboard-figure--alerte .dashboard-figure__value { color: rgba(var(--red-light-rgb), 1); }

/* Le corps prend la place restante : c'est lui qui fait tenir les pieds de
   cartes voisines sur une meme ligne. */
.dashboard-card__body {
    flex: 1 1 auto;
    min-width: 0;
    font-size: var(--taille-corps-l);
    line-height: 1.5;
    color: rgba(var(--white-rgb), 0.82);
}

.dashboard-card__body > :first-child { margin-top: 0; }
.dashboard-card__body > :last-child { margin-bottom: 0; }

.dashboard-card__foot {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 10px;
    margin-top: auto;
    padding-top: 14px;
    border-top: 1px solid rgba(var(--white-rgb), 0.10);
}

.dashboard-card__link {
    margin-left: auto;
}

/* La carte des notifications n'a pas de porte vers une page : son bouton
   d'enregistrement EST son pied, et doit donc s'en donner l'allure, sinon
   c'est la seule carte de la rangee sans trait de separation. */
.dashboard-card .partner-client-notifications__actions {
    margin-top: auto;
    padding-top: 14px;
    border-top: 1px solid rgba(var(--white-rgb), 0.10);
}

/* Le formulaire porte la fin de la carte : sans cela son bouton reste colle
   au dernier interrupteur, quelle que soit la hauteur de la rangee.

   Il faut que la CHAINE entiere s'etire, du corps de carte au formulaire :
   un `height: 100%` sur le seul formulaire ne resout rien tant que son parent
   n'a pas de hauteur a lui. */
.dashboard-card__body:has(> .partner-client-notifications__form) {
    display: flex;
    flex-direction: column;
}

.dashboard-card .partner-client-notifications__form {
    display: flex;
    flex-direction: column;
    gap: 12px;
    flex: 1 1 auto;
}

/* --- Le contenu courant d'une carte ------------------------------------ */

/* Une suite de lignes « intitule / valeur » : les couts, les derniers
   echanges, tout ce qui s'enumere sans etre un tableau. */
.dashboard-list {
    display: flex;
    flex-direction: column;
    gap: 8px;
    margin: 0;
    padding: 0;
    list-style: none;
}

.dashboard-list__item {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 12px;
    font-size: var(--taille-corps-l);
}

.dashboard-list__item {
    padding: 9px 12px;
    border-radius: 12px;
    background: rgba(var(--white-rgb), 0.04);
    background-clip: padding-box;
    border: 1px solid rgba(var(--white-rgb), 0.06);
    transition: background .14s ease, border-color .14s ease;
}

.dashboard-list__item:hover {
    background: rgba(var(--white-rgb), 0.06);
    border-color: rgba(var(--white-rgb), 0.12);
}

.dashboard-list__label {
    text-decoration: none;
    font-weight: 600;
}

.dashboard-list__item:hover .dashboard-list__label {
    text-decoration: underline;
}

/* Chaque echange est une carte : le filet qui les separait n'a plus lieu
   d'etre, et les liens souligne bleu du navigateur non plus. */
.dashboard-list__item + .dashboard-list__item {
    padding-top: 8px;
    border-top: 1px solid rgba(var(--white-rgb), 0.08);
}

.dashboard-list__label {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    color: rgba(var(--white-rgb), 0.82);
}

.dashboard-list__value {
    flex: 0 0 auto;
    font-weight: var(--graisse-forte);
    color: rgba(var(--white-rgb), 0.96);
    font-variant-numeric: tabular-nums;
}

.dashboard-list__value--muet {
    font-weight: var(--graisse-normale);
    color: rgba(var(--white-rgb), var(--voile-mention, 0.58));
}

/* Une barre de progression sobre, sans chiffre repete a l'interieur. */
.dashboard-bar {
    height: 8px;
    border-radius: var(--rayon-pilule);
    background: rgba(var(--white-rgb), 0.10);
    overflow: hidden;
}

.dashboard-bar__fill {
    display: block;
    height: 100%;
    border-radius: inherit;
    background: linear-gradient(
        90deg,
        rgba(var(--share-fill-rgb), 1),
        rgba(var(--share-line-rgb), 1)
    );
}

/* Une rangee de portes : les espaces qu'on ne visite pas tous les jours, et
   les gestes a faire quand quelque chose attend. Elles s'enroulent plutot que
   de se comprimer, un libelle tronque ne dit plus ou il mene. */
/* Les boutons sont une ACTION, la ligne au-dessus un constat : ils ne se
   touchent pas. Sans cette marge, le bouton semblait appartenir a la phrase
   qui le precede. */
.dashboard-liens {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    margin-top: 16px;
}

.dashboard-liens .btn {
    flex: 0 1 auto;
}

/* Une rangee de portes vers des ESPACES, par opposition a une rangee de
   gestes a faire. Elle seule passe en colonnes sur telephone : les libelles
   d'un geste sont des phrases (« Traiter les demandes d'acces (2) ») et se
   casseraient en trois lignes dans une demi-largeur. */
.dashboard-liens--grille {
    gap: 8px;
}

.dashboard-vide {
    margin: 0;
    font-size: var(--taille-corps-l);
    color: rgba(var(--white-rgb), var(--voile-mention, 0.56));
}

/* Le lien de parrainage : on le LIT avant de l'envoyer, souvent pour le
   dicter. Il ne peut donc pas vivre seulement dans un bouton de copie. */
/*
 * LE CHAMP ET SON BOUTON FONT UN SEUL OBJET.
 *
 * Ils etaient separes de huit pixels, le bouton en ardoise : on lisait un
 * champ, puis une commande, alors que la commande ne sert qu'a ce champ-la.
 * Ils prennent la facture de « Televerser une therapie » : coins arrondis a
 * gauche pour le champ, a droite pour le bouton, aucune couture entre eux.
 *
 * TOUT CE QUI CONCERNE CETTE PAIRE EST ICI. Le reglage etait eparpille en cinq
 * endroits de la feuille, dont trois plus bas qui defaisaient le premier : un
 * `flex-wrap: wrap`, un `flex-direction: column` et un `width: 100%` sur le
 * champ. Ecrire une sixieme regle par-dessus aurait allonge la pile ; elles
 * sont donc supprimees et leurs raisons reprises ici.
 */
.dashboard-lien-copie {
    display: flex;
    /* Une paire soudee ne se coupe pas en deux. Sous 620 px elle se dessoude
       proprement, voir le point de rupture plus bas. */
    flex-wrap: nowrap;
    align-items: stretch;
    gap: 0;
}

/*
 * DEUX CLASSES, PAS UNE.
 *
 * `.dashboard-lien-copie__champ` pese (0,1,0) et perd contre le bloc
 * `input[type="text"], ...` de lk.css, qui pese (0,1,1) : son rayon de 10 px et
 * sa marge basse de 16 px survivaient a tout ce qu'on ecrivait ici. En nommant
 * le conteneur on passe a (0,2,0), qui l'emporte.
 *
 * `flex: 1 1 350px` : une adresse d'invitation mesure environ 340 px, et un
 * lien coupe ne se verifie pas. Le champ demande donc de quoi la montrer en
 * entier, et ne cede que lorsque la colonne ne le permet plus.
 */
.dashboard-lien-copie .dashboard-lien-copie__champ {
    flex: 1 1 350px;
    min-width: 0;
    height: 46px;
    padding: 0 14px;
    box-sizing: border-box;
    /* Arrondi a gauche seulement : la droite est fermee par le bouton. */
    border-radius: 12px 0 0 12px;
    border: 1px solid rgba(var(--white-rgb), 0.12);
    border-right: none;
    background: rgba(var(--ink-900-rgb), 0.36);
    color: rgba(var(--white-rgb), 0.9);
    font-size: var(--taille-legende);
    font-family: inherit;
    margin: 0;
}

.dashboard-lien-copie .dashboard-lien-copie__champ:focus {
    outline: none;
    /* Le vert du bouton d'a cote : la paire s'allume d'un seul tenant. */
    border-color: rgba(var(--teinte-verte), 0.55);
}

/*
 * SOUS 640 px, LA PAIRE SE DESSOUDE.
 *
 * A cette largeur le champ tombait a une trentaine de pixels : on ne lisait
 * plus rien de ce qu'on allait copier. Le bouton descend donc sur sa propre
 * ligne, et le champ, redevenu seul, reprend ses quatre coins et sa bordure
 * droite. Une moitie de paire ne doit pas rester ouverte d'un cote.
 *
 * 640 ET PAS 620, PARCE QUE `lk.css` DECIDE AILLEURS. Sous 640 px, il donne a
 * TOUT bouton `width: 100%` : c'est la regle du telephone, ou une action se
 * prend au pouce sur toute la largeur. Entre 621 et 640 la paire tenait donc
 * encore sur une ligne AVEC un bouton large comme elle : le champ tombait a
 * 29 px et le bouton sortait de la page de trois pixels.
 *
 * Mesure du 17/09/2026 sur `/partner/clients` a 640 : `scrollWidth` 643 pour
 * 640 de large. Les deux seuils doivent s'accorder, sinon l'un fabrique
 * exactement ce que l'autre repare.
 */
@media (max-width: 640px) {
    .dashboard-lien-copie {
        flex-wrap: wrap;
        gap: 8px;
    }

    .dashboard-lien-copie .dashboard-lien-copie__champ {
        flex: 1 1 100%;
        border-radius: 12px;
        border-right: 1px solid rgba(var(--white-rgb), 0.12);
    }

    /*
     * ET LE MEME, EN PLUS LOURD, PARCE QU UNE REGLE GENERIQUE LE DEFAISAIT.
     *
     * `elements-retenus.css` porte `.lk-body input:has(+ button)
     * { border-right: 0 }` : la regle du couple soude, juste en soi, mais qui
     * ne sait pas que le couple s'est DESSOUDE. Elle est chargee apres cette
     * feuille, donc elle gagnait par l'ordre, et le champ gardait son bord
     * droit ouvert alors que le bouton etait passe a la ligne du dessous. C'est
     * la bordure coupee qu'on voyait sur `/partner/clients`.
     *
     * On ne la contredit pas par `!important` : on pese plus lourd qu'elle.
     * `.lk-body .dashboard-lien-copie .dashboard-lien-copie__champ:has(+ button)`
     * fait (0,3,1) contre (0,1,2). Les jetons sont repris du socle pour que le
     * filet referme soit exactement celui des trois autres cotes.
     */
    .lk-body .dashboard-lien-copie .dashboard-lien-copie__champ:has(+ button),
    .lk-body .dashboard-lien-copie .dashboard-lien-copie__champ:has(+ .btn),
    .lk-body .dashboard-lien-copie .dashboard-lien-copie__champ:has(+ .bouton-programme) {
        border-right: var(--filet-epaisseur) solid var(--champ-filet, var(--filet-large));
        border-radius: var(--rayon-bloc);
    }

    .dashboard-lien-copie .bouton-programme {
        border-radius: 12px;
    }
}

/* Le libelle du lien respire : colle a la phrase des paliers, il se lisait
   comme sa suite. */
.dashboard-lien-copie,
.paliers + .dashboard-card__subtitle {
    margin-top: 4px;
}

.paliers + .dashboard-card__subtitle {
    margin-top: 14px;
}

/* --- Points de rupture -------------------------------------------------- */

@media (max-width: 1200px) {
    .dashboard-grid {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }

    /* Deux colonnes sur deux, c'est toute la rangee : autant le dire ainsi,
       sinon la carte suivante se retrouve seule sur la sienne. */
    .dashboard-card--double {
        grid-column: 1 / -1;
    }
}

@media (max-width: 820px) {
    .dashboard-grid {
        grid-template-columns: minmax(0, 1fr);
    }

    .dashboard-card--double {
        grid-column: auto;
    }

    .dashboard-card {
        padding: 16px;
    }

    /* Le titre et l'etat se superposaient des que le libelle d'etat tenait
       deux mots : l'etat passe sous le titre plutot que de le comprimer. */
    .dashboard-card__head {
        flex-direction: column;
        align-items: flex-start;
        gap: 8px;
    }

    .dashboard-card__link {
        margin-left: 0;
        width: 100%;
        text-align: center;
    }

    /* Deux colonnes plutot qu'une pile. Six portes empilees faisaient six
       lignes pleine largeur, pour six mots : la carte devenait la plus haute
       de l'ecran alors qu'elle est la moins urgente. */
    .dashboard-liens--grille {
        display: grid;
        grid-template-columns: repeat(2, minmax(0, 1fr));
        align-items: stretch;
    }

    .dashboard-liens--grille .btn {
        width: 100%;
        text-align: center;
        /* Un libelle de deux lignes ne doit pas rendre son bouton plus haut
           que son voisin : la rangee se lit comme une grille, pas comme un
           escalier. */
        display: flex;
        align-items: center;
        justify-content: center;
    }
}

/* =========================================================================
   LA BARRE DES PALIERS DE PARRAINAGE

   Un chemin, pas une jauge. Une jauge dit « combien sur un total » ; ici la
   question est « ou j'en suis entre deux paliers », et le total n'interesse
   personne. D'ou les jalons poses le long de la piste, et un curseur qui
   avance de l'un a l'autre.

   L'echelle n'est pas celle des nombres : chaque palier occupe le meme
   segment. Les seuils vont de 1 a 25, et a l'echelle reelle les deux premiers
   se tasseraient dans le premier dixieme. La geometrie vit dans
   `NiveauParrainage::barre()`, pas ici : deux ecrans l'affichent.
   ========================================================================= */

.paliers {
    display: flex;
    flex-direction: column;
    gap: 34px;

    /* La largeur d'un jalon. Elle sert deux fois : a le dimensionner, et a
       reserver la place qu'il prend en debordant de la piste. */
    --paliers-jalon: 84px;

}

/*
 * LA TEINTE DU PALIER ATTEINT, posee sur la CARTE et non sur la barre.
 *
 * Quatre endroits la reprennent : le remplissage, le halo du curseur, les noms
 * franchis, et la pastille d'etat. Cette derniere vit dans l'entete, hors de la
 * barre : c'est pour elle que la teinte remonte d'un cran, sans quoi elle ne
 * pourrait pas l'atteindre. Ils diraient sinon quatre choses differentes.
 */
/* Les quatre couleurs, declarees une fois. Elles servent deux fois : a teinter
   la carte selon le palier COURANT, et a donner a chaque nom de palier la
   sienne, quel que soit celui qu'on a atteint. */
.paliers--bronze,
.paliers--argent,
.paliers--or,
.paliers--saphir,
.paliers--aucun {
    --palier-bronze: 205, 127, 50;
    --palier-argent: 192, 200, 214;
    --palier-or: var(--teinte-or);
    --palier-saphir: var(--teinte-bleue);
}

.paliers--bronze { --paliers-teinte: var(--palier-bronze); }
.paliers--argent { --paliers-teinte: var(--palier-argent); }
.paliers--or     { --paliers-teinte: var(--palier-or); }
.paliers--saphir { --paliers-teinte: var(--palier-saphir); }

/* Aucun palier : la piste reste neutre. La colorer avant le premier seuil
   annoncerait une progression qui n'a pas commence. */
.paliers--aucun { --paliers-teinte: var(--white-rgb); }

/* La pastille d'etat porte le nom du palier : elle en porte donc la couleur.
   Plus specifique que `--muet` et `--ok`, qui la peignaient en neutre. */
.dashboard-card.paliers--bronze .dashboard-card__state,
.dashboard-card.paliers--argent .dashboard-card__state,
.dashboard-card.paliers--or .dashboard-card__state,
.dashboard-card.paliers--saphir .dashboard-card__state {
    background: rgba(var(--paliers-teinte), 0.16);
    border-color: rgba(var(--paliers-teinte), 0.45);
    color: rgba(var(--paliers-teinte), 1);
}

.paliers__piste {
    position: relative;
    height: 8px;
    border-radius: var(--rayon-pilule);
    background: rgba(var(--white-rgb), 0.10);

    /*
     * De la place pour les insignes au-dessus et les noms en dessous : ils
     * debordent de la piste, qui n'est qu'un trait.
     *
     * Et sur les COTES : un jalon est centre sur sa position, donc celui de
     * 100 % deborde de sa demi-largeur. Sans cette marge, le dernier palier
     * sortait de la carte, qui se mettait a defiler horizontalement.
     */
    margin: 92px calc(var(--paliers-jalon) / 2) 0;
}

.paliers__parcouru {
    position: absolute;
    inset: 0 auto 0 0;
    border-radius: inherit;
    background: linear-gradient(
        90deg,
        rgba(var(--paliers-teinte), 0.45),
        rgba(var(--paliers-teinte), 1)
    );
}

.paliers__jalon {
    position: absolute;
    /*
     * AU-DESSUS de la piste, pas dessus. Centre sur elle, l'insigne la touchait
     * et le nom passait dessous : la barre traversait le jalon en son milieu.
     * Elle reste desormais un trait libre, que les jalons surplombent.
     *
     * `left` porte la position, la translation horizontale recentre le jalon
     * dessus.
     */
    bottom: calc(100% + 14px);
    transform: translateX(-50%);
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 3px;
    width: var(--paliers-jalon);
    text-align: center;
}

.paliers__insigne {
    width: 30px;
    height: 30px;
    object-fit: contain;
    /* Un palier pas encore atteint se montre, eteint : le cacher priverait de
       ce qu'on vise, et c'est precisement ce qu'on vient lire. */
    filter: grayscale(1);
    opacity: 0.38;
    transition: filter var(--transition), opacity var(--transition);
}

.paliers__jalon.is-atteint .paliers__insigne {
    filter: none;
    opacity: 1;
}

.paliers__nom {
    font-size: var(--taille-mention);
    font-weight: var(--graisse-forte);
    text-transform: uppercase;
    letter-spacing: 0.06em;
    /* 0,42 rendait 4,01 sur la piste des paliers ; le cran de mention du
       produit rend 5,2 et ne se confond pas avec le nom atteint, qui porte la
       couleur de son palier. */
    color: rgba(var(--white-rgb), var(--voile-mention, 0.54));
    white-space: nowrap;
}

/* CHAQUE NOM PORTE SA PROPRE COULEUR, celle de son insigne, et non celle du
   palier ou l'on se trouve. Un nom teint par le palier courant changeait de
   couleur a chaque franchissement, comme si Bronze devenait argente en passant
   Argent : ce sont quatre reperes distincts, pas une seule jauge coloree. */
.paliers__jalon--bronze.is-atteint .paliers__nom { color: rgba(var(--palier-bronze), 1); }
.paliers__jalon--argent.is-atteint .paliers__nom { color: rgba(var(--palier-argent), 1); }
.paliers__jalon--or.is-atteint .paliers__nom     { color: rgba(var(--palier-or), 1); }
.paliers__jalon--saphir.is-atteint .paliers__nom { color: rgba(var(--palier-saphir), 1); }

/* 0,34 DE BLANC REND 3,07 SUR LE SOL DU TABLEAU DE BORD. La peau de page le
   corrige deja, mais elle ne se charge que la ou les couches reprises se
   chargent : une correction de contraste vit dans la feuille du PRODUIT, a la
   regle fautive (`REGLES_CONSTRUCTION.md`, section 6). Ecrite seulement dans la
   peau, elle laissait le defaut en ligne et le faisait passer pour regle --
   c'est le piege qui s'est deja referme trois fois. */
.paliers__seuil {
    font-size: var(--taille-mention);
    color: rgba(var(--white-rgb), var(--voile-mention, 0.54));
    font-variant-numeric: tabular-nums;
}

.paliers__jalon.is-atteint .paliers__seuil {
    color: rgba(var(--white-rgb), var(--voile-mention, 0.58));
}

/* Le curseur passe DEVANT les insignes : c'est le seul repere qui reponde a
   « et moi, ou suis-je ».

   IL PORTE LA COULEUR DU PALIER ATTEINT. Il etait blanc, avec un halo teinte :
   le halo disait le palier, le rond ne disait rien, et l'oeil cherchait le lien
   entre ce blanc et l'insigne allume le plus a gauche. `--paliers-teinte` est
   deja pose par la classe de la carte, quinze regles plus haut ; il n'y avait
   qu'a la lire. */
.paliers__curseur {
    position: absolute;
    top: 50%;
    width: 14px;
    height: 14px;
    transform: translate(-50%, -50%);
    border-radius: 50%;
    background: rgba(var(--paliers-teinte), 1);
    box-shadow: 0 0 0 4px rgba(var(--paliers-teinte), 0.35);
    z-index: 2;
}

/* SANS PALIER, LE ROND EST GRIS, et pas blanc : `--paliers-teinte` vaut alors
   le blanc de la piste neutre, et un rond blanc sur une barre blanche est le
   repere le plus voyant des cinq, pour l'etat ou l'on n'a rien franchi. Le gris
   est ecrit ici plutot que pose sur `--paliers-teinte`, qui sert aussi la barre
   parcourue et la pastille d'etat. */
.paliers--aucun .paliers__curseur {
    background: rgb(148, 163, 184);
}

.paliers__reste {
    margin: 0;
    font-size: var(--taille-corps-l);
    color: rgba(var(--white-rgb), 0.82);
}

/* Sur telephone, quatre jalons de 84 px ne tiennent pas dans 300 : les noms
   se chevaucheraient. On garde les insignes, qui se reconnaissent, et le
   detail passe dans la phrase sous la barre. */
@media (max-width: 620px) {
    /* Le jalon retrecit, et la marge laterale de la piste avec lui, puisque
       les deux sont tenus par la meme mesure. */
    .paliers {
        --paliers-jalon: 34px;
    }

    .paliers__nom,
    .paliers__seuil {
        display: none;
    }

    .paliers__piste {
        /* Sans les noms ni les seuils, l'insigne seul demande moins de hauteur. */
        margin-top: 56px;
    }
}

/* Les interrupteurs de notification, quand leur carte occupe toute la rangee :
   empiles sur cette largeur, chacun tirerait sa description sur une seule
   ligne tres longue, penible a parcourir. */
.dashboard-card--large .partner-client-notifications__list {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 10px;
}

@media (max-width: 820px) {
    .dashboard-card--large .partner-client-notifications__list {
        grid-template-columns: minmax(0, 1fr);
    }
}

/* =========================================================================
   L'ETAPE EN COURS, en tete du parcours praticien

   L'ecran rendait compte d'un avancement. Il dit desormais la seule chose a
   faire maintenant, et donne le bouton pour la faire : c'est ce bloc. Le
   chemin complet reste dessous, comme carte, et non comme consigne.
   ========================================================================= */

.partner-journey-page .partner-journey-now {
    padding: 26px 28px;
    margin-bottom: 22px;
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 12px;

    /*
     * LE SEUL BLOC A ANGLES DROITS DE LA PAGE.
     *
     * Il n'avait ni rayon ni bordure. Ses deux calques de verre font
     * `border-radius: inherit` : ils heritaient donc de zero, et le bloc le
     * plus voyant de l'ecran se posait en dalle carree entre `.journey-shell`
     * a 18 px et les cartes a 12. Un `inherit` n'invente pas la valeur qu'il
     * attend, il recopie celle qui existe.
     */
    border-radius: 18px;
    border: 1px solid rgba(var(--white-rgb), 0.10);
}

/* L'action du bloc est le geste principal de la page : elle prend l'accent du
   parcours, et non le bleu generique de `.btn`, qui n'appartient a aucune des
   couleurs de cet ecran. */
.partner-journey-page .partner-journey-now__action {
    background: rgba(var(--portal-accent-rgb), 0.92);
    color: rgb(var(--surface-sombre-rgb));
    font-weight: var(--graisse-forte);
}

.partner-journey-page .partner-journey-now__action:hover,
.partner-journey-page .partner-journey-now__action:focus-visible {
    background: rgb(var(--portal-accent-clair-rgb));
}

.partner-journey-now__eyebrow {
    font-size: var(--taille-mention);
    letter-spacing: 0.12em;
    text-transform: uppercase;
    font-weight: var(--graisse-forte);
    color: rgba(var(--teinte-or), 1);
}

.partner-journey-now__titre {
    margin: 0;
    font-size: var(--taille-titre-m);
    line-height: 1.22;
    font-weight: var(--graisse-titre);
}

.partner-journey-now__mot {
    margin: 0;
    max-width: 68ch;
    font-size: var(--taille-intro);
    line-height: 1.55;
    color: rgba(var(--white-rgb), 0.84);
}

/* L'action est le point d'arrivee du bloc : elle se detache du texte plutot
   que de le suivre en petit. */
.partner-journey-now__action {
    margin-top: 4px;
}

/* Une etape d'attente n'a pas de bouton. Le dire noir sur blanc vaut mieux que
   de laisser un vide, qu'on lirait comme un ecran casse. */
.partner-journey-now__attente {
    margin: 0;
    font-size: var(--taille-corps-l);
    color: rgba(var(--white-rgb), var(--voile-mention, 0.56));
    font-style: italic;
}

/*
 * LE MEME REPLI QUE CELUI DES ETAPES.
 *
 * Deux accordeons vivaient sur cette page. Celui des etapes avait sa boite
 * arrondie, son fond teinte et son chevron ; celui-ci gardait le marqueur natif
 * du navigateur, un triangle noir colle au texte. C'etait le plus visible des
 * deux, en tete de page.
 */
.partner-journey-now__details {
    margin: 2px 0 0;
    max-width: 72ch;
    border-radius: 14px;
    background: rgba(var(--white-rgb), 0.075);
    border: 1px solid rgba(var(--white-rgb), 0.08);
    overflow: hidden;
}

.partner-journey-now__details summary {
    list-style: none;
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    gap: 8px;
    min-height: 34px;
    padding: 0 11px;
    color: rgba(var(--couleur-accent-doux-rgb), 0.92);
    font-size: 13px;
    line-height: 1;
}

.partner-journey-now__details summary::-webkit-details-marker {
    display: none;
}

.partner-journey-now__details summary::after {
    content: "▾";
    color: rgba(var(--white-rgb), var(--voile-mention, 0.62));
    font-size: 12px;
    transition: transform .18s ease;
}

.partner-journey-now__details[open] summary::after {
    transform: rotate(180deg);
}

.partner-journey-now__details summary:hover {
    color: var(--white);
    background: rgba(var(--white-rgb), 0.06);
}

.partner-journey-now__details > div {
    margin: 0;
    padding: 0 11px 12px;
    font-size: var(--taille-corps-l);
    line-height: 1.6;
    color: rgba(var(--white-rgb), 0.78);
}

/* Les compteurs des trois premiers cas, sur l'etape qu'ils mesurent. */
.partner-journey-now .partner-journey-widget__metrics {
    margin: 0;
}

@media (max-width: 640px) {
    .partner-journey-page .partner-journey-now {
        padding: 20px 18px;
    }

    .partner-journey-now__action {
        width: 100%;
        text-align: center;
    }
}

/* « 1 sur 3 » : le compte d'une etape qui se repete. */
.partner-journey-now__compte {
    font-size: var(--taille-corps-l);
    font-weight: var(--graisse-forte);
    color: rgba(var(--teinte-or), 1);
    font-variant-numeric: tabular-nums;
}

/* =========================================================================
   LA FORMATION ET LES LECTURES DE CAS
   ========================================================================= */

.formation-formulaire {
    display: flex;
    flex-direction: column;
    gap: 10px;
    align-items: flex-start;
}

.formation-formulaire__champ {
    width: 100%;
    box-sizing: border-box;
    padding: 12px 14px;
    border-radius: var(--rayon-s);
    border: 1px solid rgba(var(--white-rgb), 0.14);
    background: rgba(var(--black-rgb), 0.22);
    color: rgba(var(--white-rgb), 0.92);
    font-family: inherit;
    font-size: var(--taille-corps-l);
    line-height: 1.6;
    resize: vertical;
    margin-bottom: 0;
}

.formation-formulaire__champ:focus {
    outline: none;
    border-color: rgba(var(--portal-accent-rgb), 0.6);
}

/* Le mot du relecteur : il s'adresse a quelqu'un, il ne se noie donc pas dans
   le reste de la carte. */
.formation-retour {
    border-left: 3px solid rgba(var(--share-line-rgb), 0.7);
    background: rgba(var(--share-line-rgb), 0.07);
    padding: 12px 16px;
    border-radius: 0 var(--rayon-s) var(--rayon-s) 0;
}

.formation-retour--reprise {
    border-left-color: rgba(var(--amber-rgb), 0.8);
    background: rgba(var(--amber-rgb), 0.08);
}

.formation-retour__titre {
    font-size: var(--taille-mention);
    letter-spacing: 0.1em;
    text-transform: uppercase;
    font-weight: var(--graisse-forte);
    color: rgba(var(--white-rgb), 0.66);
    margin-bottom: 6px;
}

.formation-retour p {
    margin: 0;
    line-height: 1.6;
}

/* --- La file de relecture ---------------------------------------------- */

.case-reading {
    display: flex;
    flex-direction: column;
    gap: 16px;
}

.case-reading__tete {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 14px;
}

/* La copie telle qu'elle a ete ecrite : les retours a la ligne comptent, et
   le texte reste du texte plutot que du balisage fabrique. */
.case-reading__copie {
    white-space: pre-line;
    line-height: 1.7;
    font-size: var(--taille-corps-l);
    color: rgba(var(--white-rgb), 0.88);
    background: rgba(var(--black-rgb), 0.22);
    border-radius: var(--rayon-s);
    padding: 18px 20px;
    max-height: 460px;
    overflow-y: auto;
}

/* Les deux verdicts cote a cote : valider et renvoyer sont deux gestes
   symetriques, et l'un ne doit pas paraitre plus naturel que l'autre. */
.case-reading__verdict {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
    gap: 16px;
}

.case-reading__verdict form {
    display: flex;
    flex-direction: column;
    gap: 10px;
    align-items: flex-start;
}

/* -------------------------------------------------------------------------
   UNE PARTIE FERMEE, ET ELLE MONTRE CE QU'IL Y A DERRIERE
   -------------------------------------------------------------------------

   Voir le composant `cadre-verrouille` pour la regle qui compte : ce qui est
   floute est un DECOR, jamais la vraie donnee. Le flou est une propriete
   d'affichage, le contenu reste dans la page ; flouter des donnees reelles
   reviendrait a les publier en croyant les cacher.

   Le decor est donc fabrique en CSS et en barres vides. Il n'evoque que la
   FORME de ce qui existera : des lignes de personnes, des paves, du texte.
   ------------------------------------------------------------------------- */

.cadre-verrouille {
    position: relative;
    overflow: hidden;
    border-radius: var(--rayon-carte);
    border: 1px solid var(--trait-sur-sombre);
    background: rgba(var(--slate-mid-rgb), 0.55);
    min-height: 320px;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: var(--espace-xxl) var(--espace-xl);
    box-sizing: border-box;
}

/* Le decor occupe le fond, sous le voile et sous le mot. */
.cadre-verrouille__decor {
    position: absolute;
    inset: 0;
    display: flex;
    flex-direction: column;
    justify-content: center;
    gap: var(--espace-l);
    padding: var(--espace-xl);
    box-sizing: border-box;

    /* Deux flous se cumulent : celui-ci brouille la forme, celui du voile
       brouille ce qui passerait encore. Un seul, plus fort, ecraserait le
       decor en aplat et il n'y aurait plus rien a deviner. */
    filter: blur(3px);
    opacity: .85;
    pointer-events: none;
    user-select: none;
}

.cadre-verrouille__ligne {
    display: flex;
    align-items: center;
    gap: var(--espace-m);
}

.cadre-verrouille__pastille {
    flex: 0 0 auto;
    width: 34px;
    height: 34px;
    border-radius: var(--rayon-pilule);
    background: rgba(255, 255, 255, 0.34);
}

.cadre-verrouille__barre {
    display: block;
    height: 10px;
    border-radius: var(--rayon-pilule);
    background: rgba(255, 255, 255, 0.28);
}

.cadre-verrouille__barre--courte {
    flex: 0 0 auto;
    width: 54px;
    background: rgba(255, 255, 255, 0.18);
}

.cadre-verrouille__pave {
    display: flex;
    flex-direction: column;
    gap: var(--espace-s);
    padding: var(--espace-l);
    border-radius: var(--rayon-m);
    background: rgba(255, 255, 255, 0.09);
}

/* Le voile pose le contraste : sans lui, le mot se lit mal sur le decor. */
.cadre-verrouille__voile {
    position: absolute;
    inset: 0;
    background: radial-gradient(
        ellipse at center,
        rgba(var(--slate-rgb), 0.88) 0%,
        rgba(var(--slate-rgb), 0.70) 48%,
        rgba(var(--slate-rgb), 0.42) 100%
    );
    backdrop-filter: blur(6px);
    -webkit-backdrop-filter: blur(6px);
    pointer-events: none;
}

@supports not ((backdrop-filter: blur(6px)) or (-webkit-backdrop-filter: blur(6px))) {
    /* Sans flou de fond, le decor resterait trop lisible : on l'assombrit. */
    .cadre-verrouille__voile {
        background: rgba(var(--slate-rgb), 0.93);
    }
}

.cadre-verrouille__mot {
    position: relative;
    z-index: 1;
    max-width: 42ch;
    text-align: center;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--espace-m);
}

.cadre-verrouille__cadenas {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 52px;
    height: 52px;
    border-radius: var(--rayon-pilule);
    border: 1px solid rgba(var(--teinte-or), 0.35);
    background: rgba(var(--teinte-or), 0.10);
    color: rgb(var(--teinte-or));
}

.cadre-verrouille__titre {
    margin: 0;
    font-size: var(--taille-titre-s);
    font-weight: var(--graisse-moyenne);
    color: var(--texte-sur-sombre);
    text-wrap: balance;
}

.cadre-verrouille__raison {
    margin: 0;
    font-size: var(--taille-corps-l);
    line-height: 1.5;
    color: var(--texte-discret-sur-sombre);
}

.cadre-verrouille__detail {
    width: 100%;
    font-size: var(--taille-corps);
    color: var(--texte-discret-sur-sombre);
}

.cadre-verrouille__action {
    margin-top: var(--espace-xs);
}

@media (max-width: 640px) {
    .cadre-verrouille {
        min-height: 260px;
        padding: var(--espace-xl) var(--espace-l);
    }

    .cadre-verrouille__decor {
        padding: var(--espace-l);
        gap: var(--espace-m);
    }
}

/* -------------------------------------------------------------------------
   LA FICHE LATERALE, EN MODALE SUR PETIT ECRAN
   -------------------------------------------------------------------------

   Voir `public/js/fiche-modale.js` pour le pourquoi. En resume : sous 1180px
   la mise en page retombe sur une colonne et la fiche se retrouvait sous la
   liste, longue, invisible tant qu'on n'avait pas fait defiler jusqu'en bas.
   Choisir quelqu'un ne montrait donc rien.

   Au-dessus du seuil, aucune de ces regles ne s'applique : la fiche reste
   dans sa colonne.
   ------------------------------------------------------------------------- */

.fiche-modale__fond {
    display: none;
}

.fiche-modale__fermer {
    display: none;
}

@media (max-width: 1180px) {

    .fiche-modale__fond:not([hidden]) {
        display: block;
        position: fixed;
        inset: 0;
        /* Au-dessus de la barre du haut (1500), et JUSTE EN DESSOUS des
           modales du produit (9999) : la fiche peut en ouvrir une, et elle
           doit alors passer devant. */
        z-index: 9990;
        background: rgba(0, 0, 0, 0.62);
        backdrop-filter: blur(2px);
        -webkit-backdrop-filter: blur(2px);
    }

    /* La fiche NON ouverte disparait : la laisser en bas de page ferait
       doublon avec la modale, et on lirait deux fois la meme chose. */
    [data-fiche-modale]:not(.fiche-modale--ouverte) {
        display: none;
    }

    [data-fiche-modale].fiche-modale--ouverte {
        display: block;
        position: fixed;
        z-index: 9991;

        /* Une feuille posee au centre, avec une marge partout : collee aux
           bords, elle se confondrait avec la page. */
        top: 50%;
        left: 50%;
        transform: translate(-50%, -50%);
        width: min(560px, calc(100vw - 2 * var(--espace-l)));
        max-height: calc(100vh - 2 * var(--espace-xl));
        overflow-y: auto;
        -webkit-overflow-scrolling: touch;

        box-sizing: border-box;
        padding: var(--espace-xl);
        padding-top: var(--espace-xxl);
        border-radius: var(--rayon-carte);
        border: 1px solid var(--trait-sur-sombre);
        background: rgba(var(--slate-mid-rgb), 0.98);
        box-shadow: var(--ombre-flottante);
    }

    .fiche-modale--ouverte .fiche-modale__fermer {
        display: flex;
        align-items: center;
        justify-content: center;
        position: absolute;
        top: var(--espace-m);
        right: var(--espace-m);
        width: 34px;
        height: 34px;
        padding: 0;
        font-size: 24px;
        line-height: 1;
        border-radius: var(--rayon-pilule);
        border: 1px solid var(--trait-sur-sombre);
        background: rgba(255, 255, 255, 0.06);
        color: var(--texte-sur-sombre);
        cursor: pointer;
    }

    .fiche-modale--ouverte .fiche-modale__fermer:hover {
        background: rgba(255, 255, 255, 0.12);
    }

    /* Le fond ne defile pas pendant qu'on lit la fiche : sans cela, refermer
       la modale rendait une page qui avait bouge toute seule. */
    body.fiche-modale-ouverte {
        overflow: hidden;
    }
}

/* -------------------------------------------------------------------------
   LA LISTE DES UTILISATEURS, COTE ADMINISTRATION
   -------------------------------------------------------------------------

   Elle reprend la grammaire `liste-carte` : tout le decor de la ligne vient
   de la, et il n'y a ici que ce qui lui est propre.

   LA COULEUR DIT LE TYPE DE COMPTE, posee sur la ligne par le gabarit. Elle
   melait clients, praticiens et administrateurs sans qu'aucun signe ne les
   distingue : il fallait ouvrir une fiche pour savoir a qui on avait affaire.
   ------------------------------------------------------------------------- */

.admin-users-table th,
.admin-users-table td {
    vertical-align: middle;
}

.admin-users-table th {
    padding-bottom: 6px;
}

.admin-user-name {
    font-weight: var(--graisse-moyenne);
    color: var(--texte-sur-sombre);
}

/* L'adresse passe sous le nom. Elle identifie, elle ne se lit pas en premier :
   elle occupait une travee entiere du tableau pour une information dont on n'a
   besoin qu'une fois la bonne ligne trouvee. */
.admin-user-mail {
    display: block;
    margin-top: 2px;
    font-size: 0.8rem;
    color: rgba(var(--white-rgb), 0.52);
    overflow-wrap: anywhere;
}

/* ----- L'etat du compte, et les deux dates ----- */

/*
 * LA CELLULE RESTE UNE CELLULE, LA MISE EN LIGNE SE FAIT DEDANS.
 *
 * `display: flex` etait pose sur le `<td>` lui-meme. Une cellule ainsi sortie
 * du tableau ne s'etire plus a la hauteur de sa ligne : elle mesurait 41 px
 * quand les six autres en faisaient 68, et le fond de la ligne apparaissait
 * dessous en rectangle vide, large comme la colonne. Le defaut ne se voyait
 * que sur les lignes hautes, celles dont le nom passe sur deux lignes.
 */
.admin-user-etat__contenu {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 6px 8px;
}

.puce-etat {
    display: inline-flex;
    align-items: center;
    padding: 2px 9px;
    border-radius: 999px;
    border: 1px solid rgba(var(--white-rgb), 0.16);
    font-size: 0.76rem;
    white-space: nowrap;
}

/* Un compte jamais active n'a rien fait et ne fera rien : c'est le seul etat
   qui appelle un geste, et il porte donc la seule couleur d'alerte. */
.puce-etat--attente {
    border-color: rgba(var(--amber-rgb), 0.42);
    background: rgba(var(--amber-rgb), 0.16);
    font-weight: var(--graisse-moyenne);
    color: color-mix(in srgb, rgb(var(--amber-rgb)) 82%, #ffffff);
}

.puce-etat--actif {
    border-color: rgba(var(--share-bright-rgb), 0.5);
    background: rgba(var(--share-bright-rgb), 0.12);
}

.puce-etat--offert {
    border-color: rgba(var(--teinte-violette), 0.5);
    background: rgba(var(--teinte-violette), 0.12);
}

/* « Sans abonnement » et « sans praticien » sont des ABSENCES, pas des
   problemes : elles se disent sans couleur, sinon la liste s'allume pour
   des lignes ou il n'y a rien a faire. */
.puce-etat--sans {
    color: rgba(var(--white-rgb), 0.82);
    background: rgba(var(--white-rgb), 0.06);
    border-color: rgba(var(--white-rgb), 0.14);
}

.admin-user-solde,
.admin-user-referent {
    font-size: 0.8rem;
    color: rgba(var(--white-rgb), 0.7);
    font-variant-numeric: tabular-nums;
}

.admin-user-dates {
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

.admin-user-dates__inscrit {
    display: block;
    font-size: 0.85rem;
}

.admin-user-dates__vu {
    display: block;
    margin-top: 2px;
    font-size: 0.78rem;
    color: rgba(var(--white-rgb), 0.52);
}

/* Plus d'un mois sans venir : le compte existe, la personne non. La nuance
   vaut d'etre visible sans etre criarde. */
.admin-user-dates__vu--loin {
    color: rgba(var(--amber-rgb), 0.85);
}

/* La pastille reprend la couleur de la ligne : elle ECRIT ce que la teinte
   dit deja, pour qui ne distingue pas les couleurs ou lit en noir et blanc. */
.admin-user-type {
    display: inline-flex;
    align-items: center;
    box-sizing: border-box;
    min-height: 26px;
    padding: 0 10px;
    border-radius: var(--rayon-pilule);
    border: 1px solid rgba(var(--row-rgb, var(--teinte-bleue)), 0.34);

    /* HUIT CENTIEMES DE VOILE, PAS QUATORZE. L'encre de la pastille et son fond
       sont la MEME teinte : plus le voile monte, plus le fond se rapproche de
       l'encre, et moins elle se lit. Sur une ligne deja teintee par le role, le
       cumul des trois couches -- carte, cellule, pastille -- rendait 4,33 pour
       4,5 exiges. A huit centiemes, le fond redescend vers la carte et la
       pastille rend 4,9, sans rien perdre de sa teinte : c'est elle qui dit le
       role, et elle reste. */
    background: rgba(var(--row-rgb, var(--teinte-bleue)), 0.08);
    color: rgb(var(--row-rgb, var(--teinte-bleue)));
    font-size: var(--taille-legende);
    font-weight: var(--graisse-moyenne);
    white-space: nowrap;
}

/* 880 px, et non 640 : c'est la largeur ou `.responsive-table` bascule en
   cartes. En dessous de sa propre bascule, une reparation repare dans le vide. */
@media (max-width: 880px) {
    /* Empilee, la carte donne son nom en titre : le nom prend la taille qui
       va avec, comme dans la liste de clients. */
    .admin-users-table .admin-user-name {
        font-size: var(--taille-titre-s);
        font-weight: var(--graisse-normale);
    }

    /*
     * LES TROIS ACTIONS SUR UNE RANGEE, pas en colonne.
     *
     * Le tableau generique empile ses boutons et les etire sur toute la
     * largeur : trois boutons ajoutaient 130 px a chaque carte, et l'ecran
     * ne montrait plus que deux personnes. Leurs libelles sont courts, ils
     * tiennent a trois de front.
     */
    .admin-users-table .responsive-table__actions {
        flex-direction: row;
        flex-wrap: wrap;
        gap: var(--espace-s);
    }

    .admin-users-table .responsive-table__actions .btn {
        flex: 1 1 0;
        width: auto;
        min-width: 0;
        padding-inline: var(--espace-s);
    }

    /* « Actions » au-dessus de trois boutons n'apprend rien : ils se
       reconnaissent seuls. */
    .admin-users-table td:has(> .responsive-table__actions) > .responsive-table__label {
        display: none;
    }

    /*
     * L'IDENTIFIANT SE POSE EN HAUT A DROITE, AU NIVEAU DU NOM.
     *
     * Il occupait deux lignes en bas de carte, « ID » puis son numero, pour
     * quatre caracteres. Un identifiant sert a designer quelqu'un dont on
     * parle : on le cherche quand on a deja le nom sous les yeux, donc a
     * cote du nom, et jamais en le lisant de haut en bas.
     *
     * Pose hors du flux plutot que reordonne : la carte est une colonne, et
     * une colonne ne met pas deux choses sur la meme ligne. Le titre reserve
     * la place a sa droite pour qu'un nom long ne passe pas dessous.
     *
     * Reserve a CETTE liste : le pied de la liste des clients porte une date
     * d'inscription, plus longue, et qui a sa place en bas.
     */
    .admin-users-table tbody tr.liste-carte__ligne {
        position: relative;
    }

    /* `.liste-carte` est nomme ICI AUSSI, et ce n'est pas du bavardage : la
       regle qui remet le pied en `display: block` pese exactement autant et
       s'ecrit plus bas dans la feuille. A poids egal, c'est la derniere qui
       gagne, et le pied restait en deux lignes. */
    .admin-users-table.liste-carte tbody tr.liste-carte__ligne > td.cellule--pied {
        position: absolute;
        /* Le meme retrait que le rembourrage de la carte : l'identifiant se
           cale sur son coin, pas a cote. */
        top: var(--espace-l);
        right: var(--espace-l);
        /* `width: auto` CONTRE le `width: 100%` que le tableau empile donne a
           chaque cellule : sans lui, la boite posee hors du flux s'etirait sur
           toute la carte et passait sous le nom. */
        width: auto;
        display: flex;
        align-items: baseline;
        gap: 6px;
        margin: 0;
        padding: 0;
        border: none;
    }

    .admin-users-table.liste-carte tbody tr.liste-carte__ligne > td.cellule--titre {
        padding-right: 76px;

        /* LES 76 PIXELS SE PRENNENT DANS LA LARGEUR, ILS NE S Y AJOUTENT PAS.
           La case est en `content-box` : sa largeur calculee, 301 px, ne compte
           pas ses creux, et les 88 px de remplissage s'ajoutaient par-dessus --
           389 dans une rangee de 338, et la page debordait de 45 px sans barre,
           puisque la rangee laisse deborder. Meme piege que le pied de page.

           `min-width: 0` reste : une case de flex refuse par defaut de
           descendre sous la largeur de son contenu, et la reserve du bouton
           d'action l'y aurait ramenee au premier nom un peu long. */
        box-sizing: border-box;
        min-width: 0;
    }

    /*
     * LA DATE NE FLOTTE PLUS AU MILIEU.
     *
     * La cellule range trois choses en `space-between` : l'etiquette, la date
     * d'arrivee, la derniere visite. A trois, celle du milieu se pose au
     * centre et se lit comme un titre centre, alors que c'est une valeur.
     *
     * La marge automatique groupe les deux dates a droite, ou sont toutes les
     * autres valeurs de la carte.
     */
    .admin-users-table .admin-user-dates {
        gap: 6px 12px;
    }

    .admin-users-table .admin-user-dates .admin-user-dates__inscrit {
        margin-left: auto;
    }
}

/* -------------------------------------------------------------------------
   CONFIER DES CLIENTS A UN AUTRE PRATICIEN
   -------------------------------------------------------------------------

   C'etait un tableau nu : deux colonnes, un liste deroulant par ligne, un
   bouton. Rien ne disait que ce geste est le plus lourd de l'ecran — chaque
   personne change d'accompagnant et en est avertie sur-le-champ.

   La liste reprend donc la grammaire des cartes du produit, avec le rail
   violet du praticien, et le passage de l'un a l'autre se lit dans la ligne
   elle-meme grace a la fleche.
   ------------------------------------------------------------------------- */

.reassignation__liste {
    display: flex;
    flex-direction: column;
    /* En `gap` et non en marges : deux marges voisines s'additionnent, et la
       pile montrait des trous inegaux. */
    gap: 8px;
    margin: 14px 0 4px;
}

.reassignation__ligne {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1.1fr);
    align-items: center;
    gap: 14px;
    box-sizing: border-box;
    padding: 12px 14px;
    border-radius: 14px;
    background: rgba(var(--teinte-violette), 0.09);
    background-clip: padding-box;
    border: 1px solid rgba(var(--teinte-violette), 0.14);
    border-left: 4px solid rgba(var(--teinte-violette), 0.76);
}

.reassignation__personne {
    display: flex;
    flex-direction: column;
    gap: 2px;
    min-width: 0;
}

.reassignation__personne a {
    color: var(--white);
    text-decoration: none;
    font-weight: 600;
}

.reassignation__personne a:hover {
    text-decoration: underline;
}

.reassignation__courriel {
    font-size: 12px;
    color: rgba(var(--white-rgb), 0.5);
    overflow: hidden;
    text-overflow: ellipsis;
}

.reassignation__vers {
    display: flex;
    align-items: center;
    gap: 10px;
    min-width: 0;
}

.reassignation__vers select {
    margin-bottom: 0;
    min-width: 0;
    width: 100%;
}

/* La fleche porte le sens de la ligne : de cette personne, vers ce praticien.
   Dans sa propre boite flexible, comme celle du retour : « → » ne s'assied
   pas sur la ligne de base comme une lettre. */
.reassignation__fleche {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    line-height: 1;
    font-size: 16px;
    color: rgba(var(--teinte-violette), 0.9);
}

/* --- La confirmation ---------------------------------------------------
   Elle prend la place du bouton, au meme endroit : la decision se lit la ou
   on venait de cliquer, sans que l'ecran saute. */

.reassignation__confirmation {
    margin-top: 12px;
    padding: 16px;
    border-radius: 14px;
    background: rgba(var(--amber-deep-rgb), 0.10);
    background-clip: padding-box;
    border: 1px solid rgba(var(--amber-deep-rgb), 0.34);
}

.reassignation__confirmation-titre {
    margin: 0 0 4px;
    font-weight: 700;
    color: var(--white);
}

.reassignation__confirmation-intro {
    margin: 0 0 12px;
    font-size: 13px;
    color: rgba(var(--white-rgb), 0.66);
}

.reassignation__recapitulatif {
    list-style: none;
    margin: 0 0 14px;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 7px;
}

.reassignation__recapitulatif li {
    display: flex;
    align-items: center;
    gap: 9px;
    flex-wrap: wrap;
    font-size: 14px;
    color: rgba(var(--white-rgb), 0.86);
}

.reassignation__recapitulatif strong {
    color: var(--white);
}

.reassignation__confirmation-boutons {
    display: flex;
    gap: 10px;
    flex-wrap: wrap;
}

@media (max-width: 640px) {
    .reassignation__ligne {
        grid-template-columns: 1fr;
        gap: 10px;
    }
}

/* -------------------------------------------------------------------------
   L'ECRAN DES CONNEXIONS
   -------------------------------------------------------------------------

   Deux sources, deux questions : les sessions disent qui est la MAINTENANT,
   le journal dit qui est ENTRE. La premiere oublie tout a l'expiration, d'ou
   la seconde.

   La ligne reprend la grammaire des autres listes : rail de couleur a
   gauche, la personne a droite. La teinte dit le type de compte, et le rouge
   les echecs.
   ------------------------------------------------------------------------- */

.connexions-fenetre {
    display: flex;
    align-items: center;
    gap: 10px;
    flex-wrap: wrap;
    margin-bottom: 16px;
}

.connexions-fenetre__intitule {
    font-size: 12.5px;
    color: rgba(var(--white-rgb), 0.5);
}

.connexions-fenetre__choix {
    display: inline-flex;
    align-items: center;
    height: 34px;
    padding: 0 14px;
    border-radius: 12px;
    border: 1px solid rgba(var(--slate-light-rgb), 0.20);
    background: rgba(var(--slate-rgb), 0.55);
    background-clip: padding-box;
    color: rgba(var(--white-rgb), 0.86);
    font-size: 14px;
    line-height: 1;
    text-decoration: none;
    transition: transform .14s ease, filter .14s ease, border-color .14s ease;
}

.connexions-fenetre__choix:hover {
    transform: translateY(-1px);
    filter: brightness(1.08);
    border-color: rgba(var(--cyan-rgb), 0.48);
}

.connexions-fenetre__choix:active {
    transform: translateY(0);
    filter: brightness(0.92);
}

/* Le meme marquage que les onglets de la fiche : c'est le meme geste, choisir
   ce qu'on regarde. */
.connexions-fenetre__choix.is-active {
    border-width: 2px;
    border-color: rgba(var(--cyan-rgb), 0.85);
    background: rgba(var(--cyan-rgb), 0.20);
    color: var(--white);
}

.connexions-chiffres {
    display: flex;
    flex-wrap: wrap;
    gap: 26px;
    margin-bottom: 18px;
}

.connexions-chiffre {
    display: flex;
    flex-direction: column;
    gap: 2px;
}

.connexions-chiffre strong {
    font-size: 26px;
    line-height: 1.1;
    font-weight: 700;
}

.connexions-chiffre span {
    font-size: 12.5px;
    color: rgba(var(--white-rgb), var(--voile-mention, 0.55));
}

/* Un echec compte pour rien quand il n'y en a pas ; des qu'il y en a, le
   chiffre doit se voir sans qu'on le cherche. */
.connexions-chiffre--attention strong {
    color: rgb(248, 113, 113);
}

.connexions-liste {
    display: flex;
    flex-direction: column;
    gap: 8px;
    margin-top: 12px;
}

.connexions-ligne {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 150px 120px;
    align-items: center;
    gap: 14px;
    box-sizing: border-box;
    padding: 10px 14px;
    border-radius: 14px;
    border: 1px solid rgba(var(--row-rgb, var(--teinte-bleue)), 0.14);
    border-left: 4px solid rgba(var(--row-rgb, var(--teinte-bleue)), 0.76);
    background: rgba(var(--row-rgb, var(--teinte-bleue)), 0.07);
    background-clip: padding-box;
}

.connexions-ligne__qui {
    display: flex;
    flex-direction: column;
    gap: 2px;
    min-width: 0;
}

.connexions-ligne__qui strong {
    font-size: 15px;
    font-weight: 600;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.connexions-ligne__qui span {
    font-size: 12.5px;
    color: rgba(var(--white-rgb), var(--voile-mention, 0.55));
}

/* Les adresses et les heures s'alignent en colonne : on les compare du regard
   d'une ligne a l'autre, donc les chiffres doivent avoir la meme chasse. */
.connexions-ligne__adresse,
.connexions-ligne__quand {
    font-size: 13px;
    color: rgba(var(--white-rgb), var(--voile-mention, 0.62));
    font-variant-numeric: tabular-nums;
}

.connexions-ligne__quand {
    text-align: right;
}

.card--attention {
    border-color: rgba(248, 113, 113, 0.34);
}

@media (max-width: 700px) {
    .connexions-ligne {
        grid-template-columns: 1fr;
        gap: 6px;
    }

    .connexions-ligne__quand {
        text-align: left;
    }
}

/* -------------------------------------------------------------------------
   LES BARRES DES STATISTIQUES
   -------------------------------------------------------------------------

   Un tableau de chiffres oblige a comparer de tete. La barre porte la
   comparaison : on voit d'un regard lequel domine, et de combien.

   La longueur est relative au PLUS GRAND de la liste, pas a un total : on
   compare des rangs entre eux, pas des parts d'un tout.
   ------------------------------------------------------------------------- */

.stats-deux-colonnes {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
    gap: 16px;
    align-items: start;
}

.stats-barres {
    display: flex;
    flex-direction: column;
    gap: 9px;
    margin-top: 12px;
}

.stats-barre {
    display: grid;
    grid-template-columns: minmax(0, 140px) minmax(0, 1fr) 48px;
    align-items: center;
    gap: 12px;
}

.stats-barre__nom {
    font-size: 13.5px;
    color: rgba(var(--white-rgb), 0.86);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.stats-barre__piste {
    height: 8px;
    border-radius: 999px;
    background: rgba(var(--white-rgb), 0.06);
    overflow: hidden;
}

.stats-barre__part {
    display: block;
    height: 100%;
    border-radius: 999px;
    background: linear-gradient(90deg, rgba(var(--cyan-rgb), 0.85), rgba(var(--cyan-rgb), 0.42));
}

/* --- LE TUNNEL DU TEST GRATUIT ------------------------------------------ */

/* Cinq marches cote a cote, dans l'ordre du parcours. Une par colonne tant
   qu'elles tiennent, empilees ensuite : une marche de 60 px ne se lit pas. */
.stats-tunnel {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(118px, 1fr));
    gap: 10px;
    margin-top: 14px;
}

.stats-tunnel__marche {
    padding: 12px 14px;
    border-radius: 10px;
    background: rgba(var(--white-rgb), 0.04);
    border: 1px solid rgba(var(--white-rgb), 0.07);
}

/* LE TEST PASSE EST LA MARCHE QUI COMPTE. Les quatre autres existent pour
   expliquer celle-la, donc elle se distingue, et une seule se distingue. */
.stats-tunnel__marche--cle {
    background: rgba(var(--cyan-rgb), 0.1);
    border-color: rgba(var(--cyan-rgb), 0.3);
}

.stats-tunnel__marche > strong {
    display: block;
    font-size: 26px;
    line-height: 1.1;
    font-variant-numeric: tabular-nums;
}

.stats-tunnel__quoi {
    display: block;
    margin-top: 5px;
    font-size: 12.5px;
    color: rgba(var(--white-rgb), 0.72);
}

.stats-tunnel__marche-part {
    display: block;
    margin-top: 8px;
    font-size: 12px;
    font-variant-numeric: tabular-nums;
    color: rgba(var(--white-rgb), 0.55);
}

.stats-tunnel__marche-part em {
    font-style: normal;
    opacity: 0.72;
}

.stats-canaux__titre {
    margin: 22px 0 0;
    font-size: 14px;
}

.stats-canaux {
    width: 100%;
    margin-top: 10px;
    border-collapse: collapse;
}

.stats-canaux th,
.stats-canaux td {
    padding: 9px 8px;
    text-align: right;
    border-bottom: 1px solid rgba(var(--white-rgb), 0.07);
    font-variant-numeric: tabular-nums;
    font-size: 13.5px;
}

/* Le nom du canal est du texte, pas un nombre : il se lit a gauche. */
.stats-canaux th:first-child,
.stats-canaux td:first-child {
    text-align: left;
    font-variant-numeric: normal;
}

.stats-canaux th {
    font-size: 11px;
    text-transform: uppercase;
    letter-spacing: 0.07em;
    color: rgba(var(--white-rgb), 0.55);
}

/* La provenance n'est pas de la meme nature qu'un domaine choisi : elle dit
   d'ou l'on vient, pas ce qu'on a fait. Une autre teinte evite de croire que
   les deux listes se comparent. */
.stats-barre__part--source {
    background: linear-gradient(90deg, rgba(var(--teinte-violette), 0.85), rgba(var(--teinte-violette), 0.42));
}

.stats-barre__valeur {
    font-size: 13.5px;
    font-variant-numeric: tabular-nums;
    text-align: right;
    color: rgba(var(--white-rgb), 0.72);
}

@media (max-width: 560px) {
    .stats-barre {
        grid-template-columns: minmax(0, 1fr) 44px;
    }

    /* La piste passe sous le nom : a cette largeur, trois colonnes ne
       laissent plus assez de place a la barre pour qu'elle compare. */
    .stats-barre__piste {
        grid-column: 1 / -1;
    }
}

/* Fermer une session : une action discrete, posee au bout de la ligne. Elle
   deconnecte quelqu'un, donc elle demande confirmation ; mais elle n'a pas a
   crier pour autant, on la cherche rarement. */
.connexions-fermer {
    appearance: none;
    height: 30px;
    padding: 0 12px;
    border-radius: 10px;
    border: 1px solid rgba(248, 113, 113, 0.34);
    background: rgba(248, 113, 113, 0.12);
    color: rgb(248, 143, 143);
    font: inherit;
    font-size: 12.5px;
    line-height: 1;
    cursor: pointer;
    transition: transform .14s ease, filter .14s ease, border-color .14s ease;
}

/* Meme raison que pour `.btn` : 30 px se visent mal au doigt, et fermer une
   session par erreur deconnecte quelqu'un. On ouvre la hauteur sur mobile, la
   largeur ne bouge pas. */
@media (max-width: 768px) {
    .connexions-fermer {
        height: 44px;
    }
}

.connexions-fermer:hover {
    transform: translateY(-1px);
    filter: brightness(1.08);
    border-color: rgba(248, 113, 113, 0.62);
}

.connexions-fermer:active {
    transform: translateY(0);
    filter: brightness(0.92);
}

.connexions-ligne__mienne {
    font-size: 12px;
    color: rgba(var(--white-rgb), var(--voile-mention-basse, 0.42));
    font-style: italic;
    text-align: right;
}

/* La ligne compte une colonne de plus depuis qu'elle porte une action. */
.connexions-liste[data-sessions] .connexions-ligne {
    grid-template-columns: minmax(0, 1fr) 150px 120px 90px;
}

@media (max-width: 700px) {
    .connexions-liste[data-sessions] .connexions-ligne {
        grid-template-columns: 1fr;
    }
}

/* Les jours en colonnes : le temps se lit de gauche a droite, et c'est la
   SILHOUETTE qu'on cherche, pas la valeur de chaque barre. */
.stats-jours {
    display: flex;
    align-items: flex-end;
    gap: 4px;
    height: 120px;
    margin-top: 14px;
    overflow-x: auto;
    padding-bottom: 2px;
}

.stats-jour {
    flex: 1 0 22px;
    min-width: 22px;
    height: 100%;
    display: flex;
    flex-direction: column;
    justify-content: flex-end;
    align-items: center;
    gap: 5px;
}

.stats-jour__colonne {
    width: 100%;
    border-radius: 5px 5px 0 0;
    background: linear-gradient(180deg, rgba(var(--cyan-rgb), 0.82), rgba(var(--cyan-rgb), 0.28));
}

.stats-jour__date {
    font-size: 10.5px;
    color: rgba(var(--white-rgb), var(--voile-mention-basse, 0.42));
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

.stats-barre__part--appareil {
    background: linear-gradient(90deg, rgba(var(--teinte-or), 0.85), rgba(var(--teinte-or), 0.42));
}

/* -------------------------------------------------------------------------
   LA CARTE DU MONDE
   -------------------------------------------------------------------------

   Un fond converti une fois en chemins SVG, peint par le SERVEUR : la teinte
   d'un pays est calculee la ou vivent les chiffres, et le script n'y touche
   jamais. Tenir la meme regle a deux endroits, c'est se preparer a la voir
   diverger.
   ------------------------------------------------------------------------- */

.carte-monde__cadre {
    position: relative;
    margin-top: 14px;
    padding: 10px;
    border-radius: 14px;
    background: rgba(var(--ink-900-rgb, 12, 18, 33), 0.34);
    border: 1px solid rgba(var(--white-rgb), 0.06);
}

.carte-monde {
    display: block;
    width: 100%;
    height: auto;
}

.carte-monde path {
    /* Le trait separe les pays sans les cerner : sur une carte a cette
       echelle, un contour epais mange les petits pays. */
    stroke: rgba(var(--ink-900-rgb, 12, 18, 33), 0.55);
    stroke-width: 0.5;
    transition: filter .12s ease;
}

.carte-monde path:hover {
    filter: brightness(1.35);
    cursor: default;
}

/* L'infobulle suit le pointeur : la bulle native attend une seconde avant de
   paraitre et ne se laisse pas mettre en forme. */
.carte-monde__bulle {
    position: absolute;
    z-index: 4;
    padding: 6px 10px;
    border-radius: 10px;
    background: rgba(var(--ink-900-rgb, 12, 18, 33), 0.94);
    border: 1px solid rgba(var(--cyan-rgb), 0.42);
    color: var(--white);
    font-size: 12.5px;
    line-height: 1.3;
    white-space: nowrap;
    pointer-events: none;
}

.carte-monde__filtre {
    display: flex;
    align-items: center;
    gap: 10px;
    margin-top: 16px;
}

.carte-monde__filtre label {
    margin: 0;
    font-size: 12.5px;
    color: rgba(var(--white-rgb), var(--voile-mention, 0.55));
    white-space: nowrap;
}

.carte-monde__filtre input {
    margin-bottom: 0;
    max-width: 280px;
    /* Le meme rayon que les pastilles de fenetre juste au-dessus : les deux
       servent a restreindre ce qu'on regarde. */
    border-radius: 12px;
    padding: 9px 13px;
    font-size: 14px;
}

/* La mise au point se voit : on tape dedans, il faut savoir ou. */
.carte-monde__filtre input:focus {
    outline: none;
    border-color: rgba(var(--cyan-rgb), 0.62);
    box-shadow: 0 0 0 3px rgba(var(--cyan-rgb), 0.16);
}

/* La croix de vidage que Chrome ajoute aux champs de recherche est grise
   et presque invisible sur ce fond : on la remonte a la couleur du texte. */
.carte-monde__filtre input::-webkit-search-cancel-button {
    filter: invert(1) opacity(0.55);
    cursor: pointer;
}

.carte-monde__vide {
    margin-top: 10px;
}

/* Le drapeau ou, a defaut, le code du pays. Voir le commentaire de la vue :
   l'emoji drapeau ne rend pas sous Windows. */
.carte-monde__drapeau {
    flex: 0 0 auto;
    border-radius: 2px;
    vertical-align: -2px;
}

.carte-monde__code {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 24px;
    height: 15px;
    padding: 0 4px;
    border-radius: 3px;
    background: rgba(var(--white-rgb), 0.10);
    color: rgba(var(--white-rgb), var(--voile-mention, 0.62));
    font-size: 10px;
    font-weight: 700;
    letter-spacing: .04em;
}

/* Le nom et son drapeau forment une paire : ils ne se separent pas quand la
   colonne se resserre. */
.stats-barre__nom {
    display: flex;
    align-items: center;
    gap: 7px;
}

/* =========================================================================
   UNE CANDIDATURE DE PRATICIEN.

   La fiche etait une suite de paragraphes bruts, et le lien d'inscription y
   tenait la place la plus voyante : en caracteres de code, au milieu. Or le
   lien ne se lit pas, il se copie une fois la decision prise. Ce qui se lit,
   c'est qui demande et qui le recommande.

   L'ordre suit donc la decision : l'identite et son statut, les moyens de
   joindre la personne, le referent qui fait pencher, puis le geste qui clot —
   statut, lien a copier, note.
   ========================================================================= */
.candidature {
    display: flex;
    flex-direction: column;
    gap: 14px;
}

.candidature__tete {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 16px;
    flex-wrap: wrap;
}

.candidature__nom {
    margin: 0;
    font-size: 1.06rem;
}

.candidature__metier {
    margin-top: 2px;
    /* 0,72 rend 4,09 sur la carte de candidature en clair : ce metier est la
       seule ligne qui dit QUI est la personne, on la lit vraiment. */
    color: rgba(var(--ink-200-rgb), 0.88);
    font-size: 0.9rem;
}

/* Le statut se lit d'un coup d'oeil dans une liste : il porte sa couleur,
   celle du systeme d'actions. Bleu tant qu'il reste quelque chose a faire,
   vert quand c'est accepte, rouge quand c'est refuse, neutre entre les deux. */
.candidature__statut {
    flex: none;
    padding: 4px 11px;
    border-radius: 999px;
    border: 1px solid transparent;
    font-size: 0.78rem;
    font-weight: 600;
    letter-spacing: 0.01em;
    white-space: nowrap;
}

.candidature__statut--new {
    background: rgba(var(--blue-rgb), 0.16);
    border-color: rgba(var(--blue-rgb), 0.45);
    /* LE BLEU DE DONNEE NE PASSE NI D UN COTE NI DE L AUTRE : 2,53 en clair
       sur son propre voile, 4,06 en sombre. Il lui faut un cran de chaque
       cote -- plus profond en clair, plus clair en sombre. */
    color: rgb(var(--encre-etat-info-rgb, 147, 197, 253));
}

.candidature__statut--contacted,
.candidature__statut--invited {
    background: rgba(var(--ink-200-rgb), 0.10);
    border-color: rgba(var(--ink-200-rgb), 0.24);
    color: rgba(var(--ink-200-rgb), 0.86);
}

.candidature__statut--accepted {
    background: rgba(var(--green-rgb), 0.16);
    border-color: rgba(var(--green-rgb), 0.45);
    color: rgb(var(--encre-etat-ok-rgb, var(--green-rgb)));
}

.candidature__statut--declined {
    background: rgba(var(--red-rgb), 0.14);
    border-color: rgba(var(--red-rgb), 0.42);
    color: rgba(var(--red-rgb), 1);
}

/* Le contact : une rangee de faits, separes par des points mediands poses en
   CSS. Ecrits dans le gabarit, ils restaient quand un champ manquait. */
.candidature__contact {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 6px 14px;
    color: rgba(var(--ink-200-rgb), 0.78);
    font-size: 0.9rem;
}

/* Le point est pose sur l'ENVELOPPE, jamais sur le lien : dans le lien, il
   heritait du soulignement et paraissait en faire partie. */
.candidature__contact > span + span::before {
    content: '·';
    margin-right: 14px;
    color: rgba(var(--ink-200-rgb), 0.34);
    text-decoration: none;
}

.candidature__referent,
.candidature__compte {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 8px 10px;
    padding: 10px 13px;
    border-radius: 12px;
    background: rgba(var(--black-rgb), 0.22);
    border: 1px solid rgba(var(--white-rgb), 0.06);
    font-size: 0.92rem;
}

.candidature__etiquette {
    /* UNE ETIQUETTE EN CAPITALES DE 12,5 px N A PAS DE MARGE. A 0,60 elle rend
       2,45 en clair ; elle nomme le champ d'a cote, elle se lit pleine. */
    color: rgb(var(--ink-200-rgb));
    font-size: 0.78rem;
    text-transform: uppercase;
    letter-spacing: 0.05em;
}

.candidature__actif {
    color: rgba(var(--green-rgb), 0.9);
}

.candidature__compte form {
    margin: 0;
}

/* Le mot du candidat est une citation : il se lit dans sa voix, pas dans la
   notre. Un filet plutot que des guillemets, qui se melent au texte. */
.candidature__mot {
    margin: 0;
    padding: 8px 0 8px 14px;
    border-left: 2px solid rgba(var(--blue-rgb), 0.42);
    color: rgba(var(--ink-200-rgb), 0.86);
    font-style: italic;
}

.candidature__suite {
    display: flex;
    flex-direction: column;
    gap: 12px;
    margin: 2px 0 0;
    padding-top: 14px;
    border-top: 1px solid rgba(var(--white-rgb), 0.08);
}

/* Le statut et le lien vont ensemble : on choisit l'un et on copie l'autre
   dans le meme geste. Le statut ne prend que la place de son plus long
   libelle, le lien recoit le reste. */
/* Les deux colonnes commencent EN HAUT, pas en bas : cale sur le bas, la
   colonne la plus courte descendait, et son libelle ne se lisait plus sur la
   meme ligne que celui d'a cote. Ce sont les libelles qu'on parcourt. */
.candidature__champs {
    display: grid;
    grid-template-columns: minmax(0, 240px) minmax(0, 1fr);
    gap: 12px 16px;
    align-items: start;
}

/* Le champ et le select prennent la meme hauteur, sinon les deux colonnes
   s'alignent en haut et se decalent en bas. */
.candidature__champs .candidature__champ > select,
.candidature__champ .dashboard-lien-copie__champ {
    min-height: 44px;
}

.candidature__champ {
    display: flex;
    flex-direction: column;
    gap: 6px;
    min-width: 0;
}

.candidature__champ label {
    margin: 0;
    /* 0,72 rend 4,09 en clair a 13 px : un libelle de champ se lit avant le
       champ, il ne peut pas etre le texte le plus faible de la carte. */
    color: rgba(var(--ink-200-rgb), 0.92);
    font-size: 0.82rem;
    font-weight: 600;
}

.candidature__champ select,
.candidature__champ textarea {
    margin: 0;
}

/* Le champ part d'une base NULLE, pas de son contenu.
   `flex: 1 1 auto` prend pour base la largeur du texte, et une adresse
   complete est plus large que la colonne : le bouton passait a la ligne
   suivante, seul, loin du champ qu'il copie. */
/*
 * LE BOUTON A LA HAUTEUR DU CHAMP QU'IL COPIE, PARTOUT.
 *
 * C'etait ecrit pour la seule fiche de candidature. La cause etait pourtant
 * generale : dans cette ligne, le champ mesure 43 px et le bouton 35, donc le
 * centrage posait le bouton quatre pixels plus bas que ce qu'il copie. Et tout
 * `input` de l'interface porte 16 px de marge basse, faits pour un champ seul
 * dans sa colonne, qui allongeaient la ligne quand il en partage une.
 *
 * La regle vit maintenant sur le composant lui-meme : le lien d'affiliation du
 * praticien, le code d'invitation, le lien a envoyer a un candidat et l'entete
 * des candidatures s'alignent de la meme facon, sans qu'on ait a y repenser.
 */
/*
 * LE BOUTON PASSE A LA LIGNE PLUTOT QUE D'ECRASER LE CHAMP.
 *
 * En `nowrap`, le bouton garde la largeur de son intitule et le champ prend ce
 * qui reste : a 375 px il ne restait que 26 px, soit un champ ou l'on ne lit
 * rien de ce qu'on va copier. Mesure faite avant correction : champ 26 px,
 * bouton 299.
 *
 * Le champ demande donc 220 px avant de ceder : au-dela il s'etire, en deca le
 * bouton descend sur sa propre ligne et le champ reprend toute la largeur.
 * C'est le meme reglage qui evite la troncature a 1280 px.
 */
/* La largeur du champ, sa marge et le repli de la paire sont regles une fois
   pour toutes avec le composant, plus haut dans cette feuille. Dans la liste
   des candidatures la colonne est plus etroite : le champ y cede sa largeur
   de confort. */
.candidature__champ .dashboard-lien-copie .dashboard-lien-copie__champ {
    flex: 1 1 0;
}

/* Dans l'en-tete, le champ vit hors d'une fiche : il lui faut sa propre
   respiration et une largeur qui ne s'etale pas sur toute la banniere. */
.candidature__champ--entete {
    max-width: 620px;
    margin-top: 16px;
}

.candidature__champ--entete label {
    font-weight: 700;
    color: var(--ink-100, rgba(var(--ink-200-rgb), 0.95));
}

/*
 * LE FILTRE ACTIF SE DISTINGUE DES AUTRES.
 *
 * Actif et inactif differaient de 1,19 pour 1 en contraste (#334155 contre
 * #3a4e58) et de rien d'autre : on ne pouvait pas dire quel filtre on
 * regardait, et la liste semblait donc parfois incomplete sans raison.
 *
 * Un fond marque, un liseré, et le texte a pleine clarte : trois signes
 * plutot qu'un seul, pour que ca tienne aussi quand l'ecran est mal regle.
 */
.admin-dashboard .btn.btn-primary,
.card .btn.btn-primary {
    box-shadow: inset 0 0 0 1px rgba(var(--blue-rgb), 0.55);
}

.candidature__pied {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 14px;
}

@media (max-width: 760px) {
    .candidature__champs {
        grid-template-columns: minmax(0, 1fr);
    }
}

/* =========================================================================
   LE CODE D'INVITATION, SEUL.

   La grille portait DEUX parts : le lien d'inscription praticien et le code.
   Deux champs a copier pour un seul identifiant faisaient hesiter sur lequel
   envoyer, et l'adresse ne disait rien de plus que le code qu'elle traine au
   bout. Le lien est parti ; la seconde colonne resterait vide.

   Le code garde la largeur de son libelle, pas celle de la carte : onze
   caracteres etales sur toute la largeur promettent une saisie qu'on n'attend
   pas. Le champ retombe a `auto` sous 900 px, plus bas dans cette feuille.
   ========================================================================= */
.dashboard-invitation {
    display: grid;
    grid-template-columns: minmax(0, auto);
    justify-content: start;
    gap: 12px 16px;
    align-items: start;
    margin-top: 4px;
}

.dashboard-invitation__part {
    display: flex;
    flex-direction: column;
    gap: 6px;
    min-width: 0;
}

/* Le code prend la largeur de sa colonne, qui est calee sur son contenu : un
   champ ajuste au caractere pres a l'air d'un afficheur, pas d'une valeur
   qu'on selectionne et qu'on copie. */
.dashboard-invitation__part--code {
    width: 44ch;
}

/*
 * LE BOUTON SOUS SON CHAMP, TOUJOURS.
 *
 * A cote, il prenait sa part de la largeur, et le champ changeait de taille
 * selon la longueur de l'intitule et selon la place restante : le lien tenait
 * a une largeur, se coupait a une autre, et le bouton descendait parfois.
 * Le champ prend la largeur de sa colonne, le bouton garde la sienne : un
 * bouton large comme un champ se lit comme une barre, et on ne sait plus ou
 * cliquer.
 */
.dashboard-invitation .dashboard-lien-copie {
    margin-top: 0;
}

/* Le libelle du code se lit sur la meme ligne que celui du lien : sans cette
   hauteur commune, un libelle qui passe a deux lignes decalerait son champ. */
.dashboard-invitation .dashboard-card__subtitle {
    margin: 0;
}

/*
 * SOUS 420 px, MEME TOUTE LA LARGEUR NE SUFFIT PLUS.
 *
 * A 375 px, le champ recoit 297 px et l'adresse en demande 338 : elle se coupe
 * quoi qu'on fasse de la mise en page. Deux points de police en moins la
 * ramenent a 293 px, donc lisible en entier, et c'est le seul endroit du
 * produit ou l'on descend sous la taille de saisie courante. On l'accepte ici
 * parce qu'on ne saisit pas dans ce champ : on le lit et on le copie.
 */
@media (max-width: 420px) {
    .dashboard-lien-copie .dashboard-lien-copie__champ {
        font-size: 13px;
    }
}

@media (max-width: 900px) {
    .dashboard-invitation {
        grid-template-columns: minmax(0, 1fr);
    }

    .dashboard-invitation__part--code {
        width: auto;
    }
}

/* ======================================================================
   QUI PEUT QUOI
   ======================================================================
   Une fiche par praticien, ses droits en grille. Trois etats a distinguer d'un
   coup d'oeil, et pas deux : ouvert, ferme, et SUSPENDU, c'est-a-dire accorde
   un jour mais sans effet aujourd'hui faute d'abonnement. Confondre les deux
   derniers ferait chercher la panne au mauvais endroit.
   ====================================================================== */

/*
 * UNE LIGNE PAR PERSONNE, DEPLIEE A LA DEMANDE.
 *
 * Le premier jet montrait les dix droits de chacun, tout le temps : lisible a
 * trois praticiens, un mur a cinquante, alors qu'on vient ici quelques fois
 * pour accorder UN droit a UNE personne.
 */
/*
 * LA MEME FACTURE QUE LES AUTRES LISTES DU PRODUIT.
 *
 * Des cartes detachees, avec un rail de couleur a gauche qui porte le type de
 * compte : l'or pour un administrateur, le violet pour un praticien. Ce sont
 * les teintes de `liste-carte`, pas des valeurs posees ici, pour qu'une liste
 * ne se lise pas autrement qu'une autre.
 */
.capacites-liste {
    display: flex;
    flex-direction: column;
    gap: 10px;
}

.capacites-ligne {
    box-sizing: border-box;
    border: 1px solid rgba(var(--row-rgb, var(--teinte-bleue)), 0.14);
    border-left: 4px solid rgba(var(--row-rgb, var(--teinte-bleue)), 0.76);
    border-radius: var(--rayon-l, 14px);
    background: rgba(var(--row-rgb, var(--teinte-bleue)), 0.09);
}

/* Ouverte, la carte s'affirme : on sait laquelle on manipule quand la page a
   defile et que le resume est sorti de l'ecran. */
.capacites-ligne[open] {
    border-color: rgba(var(--row-rgb, var(--teinte-bleue)), 0.34);
    background: rgba(var(--row-rgb, var(--teinte-bleue)), 0.15);
}

/* La fleche du navigateur est remplacee par la notre, qui tourne. */
.capacites-ligne > summary {
    list-style: none;
}

.capacites-ligne > summary::-webkit-details-marker {
    display: none;
}

.capacites-ligne__resume {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px 16px;
    padding: 14px 18px;
    cursor: pointer;
    border-radius: var(--rayon-l, 14px);
}

.capacites-ligne__resume:hover {
    background: rgba(var(--row-rgb, var(--teinte-bleue)), 0.10);
}

/* Le clavier doit voir ou il est : c'est le resume qui recoit le focus. */
.capacites-ligne > summary:focus-visible {
    outline: 2px solid rgba(var(--portal-accent-rgb), 0.8);
    outline-offset: 2px;
}

.capacites-ligne__identite {
    display: flex;
    flex-direction: column;
    gap: 1px;
    min-width: 0;
    flex: 1 1 240px;
}

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

.capacites-ligne__mail {
    font-size: 13px;
    overflow-wrap: anywhere;
}

.capacites-ligne__compte {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 6px 10px;
    font-size: 13px;
}

.capacites-ligne__chiffre {
    font-variant-numeric: tabular-nums;
    font-weight: 600;
}

.capacites-ligne__suspendues {
    padding: 3px 9px;
    border-radius: 999px;
    font-size: 12px;
    color: var(--ink-50);
    background: rgba(var(--amber-rgb), 0.16);
    border: 1px solid rgba(var(--amber-rgb), 0.45);
}

.capacites-ligne__chevron {
    display: inline-flex;
    flex: none;
    width: 18px;
    height: 18px;
    opacity: .6;
    transition: transform .16s ease;
}

.capacites-ligne[open] .capacites-ligne__chevron {
    transform: rotate(180deg);
}

.capacites-ligne[open] .capacites-grille {
    margin: 4px 18px 18px;
}

@media (prefers-reduced-motion: reduce) {
    .capacites-ligne__chevron {
        transition: none;
    }
}

.capacites-pastille--admin {
    padding: 4px 10px;
    border-radius: 999px;
    font-size: 12px;
    font-weight: 600;
    color: var(--ink-50);
    background: rgba(var(--blue-rgb), 0.22);
    border: 1px solid rgba(var(--blue-rgb), 0.45);
}

.capacites-grille {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(min(100%, 230px), 1fr));
    gap: 12px;
}

.capacites-case {
    display: flex;
    flex-direction: column;
    gap: 4px;
    min-width: 0;
    padding: 14px;
    border-radius: 12px;
    border: 1px solid rgba(var(--slate-light-rgb), 0.22);
    background: rgba(var(--slate-light-rgb), 0.05);
}

/* Le liseré porte l'etat, pas seulement la couleur du texte : sur un ecran mal
   regle, une nuance de gris ne se lit pas, un bord si. */
.capacites-case.is-ouverte {
    border-color: rgba(var(--share-bright-rgb), 0.5);
    background: rgba(var(--share-bright-rgb), 0.08);
}

.capacites-case.is-suspendue {
    border-color: rgba(var(--amber-rgb), 0.55);
    background: rgba(var(--amber-rgb), 0.10);
}

.capacites-case__nom {
    font-weight: 600;
}

.capacites-case__etat {
    font-size: 13px;
    font-weight: 600;
    opacity: .9;
}

.capacites-case__source,
.capacites-case__echeance,
.capacites-case__raison {
    font-size: 12px;
    opacity: .72;
    overflow-wrap: anywhere;
}

/* Le geste se pose en bas, aligne d'une case a l'autre quel que soit le nombre
   de lignes de detail au-dessus. */
.capacites-case__geste {
    margin: 10px 0 0;
    display: flex;
}

.capacites-case__geste .btn {
    width: 100%;
    min-height: 40px;
}

/*
 * REPRENDRE NE CRIE PAS, MAIS SE VOIT.
 *
 * Le bouton rouge plein est juste pour un geste isole. Ici il y en a un par
 * droit ouvert, soit neuf sur une seule fiche : la grille devenait un mur
 * rouge sur un ecran qu'on vient d'abord LIRE, et le rouge ne distinguait plus
 * rien puisqu'il etait partout.
 *
 * Il garde sa couleur, en contour : on le reconnait, il ne domine plus. La
 * modale de confirmation, elle, reste rouge plein, la ou la question se pose
 * vraiment et ou il n'y a qu'un bouton.
 */
/* Un voile de sa teinte derriere le contour : voir `.bouton-programme--creux`,
   meme raison. Il etait le seul autre bouton du produit a n'avoir rien. */
.capacites-case__geste .btn-danger {
    background: rgba(var(--red-rgb), 0.12);
    border: 1px solid rgba(var(--red-rgb), 0.55);
    color: var(--couleur-danger-doux);
}

.capacites-case__geste .btn-danger:hover {
    background: rgba(var(--red-rgb), 0.22);
    border-color: rgba(var(--red-rgb), 0.85);
}

.capacites-fiche + .capacites-fiche {
    margin-top: 0;
}

/* ======================================================================
   LA BOUTIQUE PRATICIEN
   ======================================================================
   Une carte par lot. Le prix et la duree se lisent d'un bloc, a droite du nom,
   parce que ce sont les deux choses qu'on compare entre deux lots. La liste
   des capacites vient dessous : c'est ce qu'on achete, et une etiquette ne le
   dit pas.
   ====================================================================== */

.boutique-lot__tete {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    justify-content: space-between;
    gap: 10px 20px;
}

.boutique-lot__identite {
    min-width: 0;
    flex: 1 1 260px;
}

.boutique-lot__nom {
    margin: 0;
    font-size: 20px;
}

.boutique-lot__description {
    margin: 4px 0 0;
    overflow-wrap: anywhere;
}

/* Le prix ne se coupe pas en deux lignes au milieu d'un nombre. */
.boutique-lot__prix {
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    gap: 2px;
    font-size: 20px;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

.boutique-lot__duree {
    font-size: 13px;
    font-weight: 500;
    opacity: .72;
}

.boutique-lot__capacites {
    margin: 16px 0 0;
    padding: 0;
    list-style: none;
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
}

.boutique-lot__capacites li {
    padding: 5px 12px;
    border-radius: 999px;
    font-size: 13px;
    border: 1px solid rgba(var(--slate-light-rgb), 0.28);
    background: rgba(var(--slate-light-rgb), 0.07);
}

.boutique-lot__geste {
    margin-top: 18px;
}

.boutique-lot__geste .btn {
    min-height: 44px;
}

/* Un lot deja ouvert ne propose plus rien : il le dit, et se distingue au
   liseré pour qu'on ne le relise pas a chaque passage. */
.boutique-lot.is-ouvert {
    border: 1px solid rgba(var(--share-bright-rgb), 0.45);
}

.boutique-lot__possede {
    font-weight: 600;
    color: var(--couleur-succes-doux);
}

@media (max-width: 560px) {
    /* Le prix repasse a gauche : colle a droite sous le nom, il se lisait
       comme s'il appartenait a la ligne suivante. */
    .boutique-lot__prix {
        align-items: flex-start;
    }

    .boutique-lot__geste .btn {
        width: 100%;
    }
}

/* Un lot que seul l Admin voit : la marque le dit, discrete mais lisible. */
.boutique-lot__ferme {
    align-self: flex-start;
    padding: 4px 10px;
    border-radius: 999px;
    font-size: 12px;
    font-weight: 600;
    color: var(--ink-50);
    background: rgba(var(--amber-rgb), 0.16);
    border: 1px solid rgba(var(--amber-rgb), 0.45);
}

/* --- Un prereglage se deplie ------------------------------------------
   Ils etaient tous deroules, cinq champs chacun, pour des valeurs qu'on
   regarde une fois par an. Le resume suffit a s'y retrouver. */
.processing-preset--depliable > summary {
    list-style: none;
    cursor: pointer;
}

.processing-preset--depliable > summary::-webkit-details-marker {
    display: none;
}

.processing-preset--depliable > summary:focus-visible {
    outline: 2px solid rgba(var(--portal-accent-rgb), 0.8);
    outline-offset: 2px;
    border-radius: 10px;
}

.processing-preset__chevron {
    display: inline-flex;
    flex: none;
    width: 18px;
    height: 18px;
    opacity: .6;
    transition: transform .16s ease;
}

.processing-preset--depliable[open] .processing-preset__chevron {
    transform: rotate(180deg);
}

.processing-preset--depliable[open] .processing-preset__grid {
    margin-top: 14px;
}

@media (prefers-reduced-motion: reduce) {
    .processing-preset__chevron {
        transition: none;
    }
}

/* ===== Le catalogue de la boutique client =====

   Meme grammaire que la liste des capacites : une ligne par element, depliee
   a la demande, une seule ouverte a la fois. On vient ici regler UN produit,
   pas comparer le catalogue entier. */

.catalogue-base {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    gap: 16px;
    margin-top: 14px;
}

.catalogue-base .champ {
    display: flex;
    flex-direction: column;
    gap: 4px;
    min-width: 180px;
}

/* Le cout de traitement se lit A COTE du prix, pas ailleurs sur la page :
   fixer un prix sans voir ce qu'il couvre, c'est fixer un prix a l'aveugle. */
.catalogue-cout {
    display: flex;
    flex-direction: column;
    gap: 2px;
    padding: 8px 14px;
    border-radius: 10px;
    border: 1px solid rgba(var(--white-rgb), 0.12);
    background: rgba(var(--white-rgb), 0.04);
    font-variant-numeric: tabular-nums;
}

.catalogue-cout__titre {
    font-size: 0.76rem;
    text-transform: uppercase;
    letter-spacing: .04em;
    opacity: .66;
}

.catalogue-cout__valeur {
    font-size: 0.9rem;
    font-weight: 600;
}

.catalogue-cout__marge {
    font-size: 0.84rem;
    color: rgba(var(--share-bright-rgb), 0.95);
}

/* Une marge negative, c'est vendre a perte. Elle ne se murmure pas. */
.catalogue-cout__marge--negative {
    color: rgb(var(--red-light-rgb));
    font-weight: 700;
}

.catalogue-avertissement {
    margin: 10px 0 0;
    padding: 10px 14px;
    border-radius: 10px;
    border-left: 3px solid rgba(var(--amber-rgb), 0.7);
    background: rgba(var(--amber-rgb), 0.09);
    font-size: 0.88rem;
}

.catalogue-liste {
    display: flex;
    flex-direction: column;
    gap: 8px;
    margin-top: 14px;
}

.catalogue-ligne {
    border-radius: 12px;
    border: 1px solid rgba(var(--white-rgb), 0.10);
    border-left: 3px solid rgba(var(--row-rgb, var(--slate-light-rgb)), 0.75);
    background: rgba(var(--row-rgb, var(--slate-light-rgb)), 0.06);
    overflow: hidden;
}

.catalogue-ligne__resume {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    padding: 12px 16px;
    cursor: pointer;

    /* Le triangle natif se place mal dans une boite en `flex` : un chevron
       qui pivote dit la meme chose et suit l'etat ouvert. */
    list-style: none;
}

.catalogue-ligne__resume::-webkit-details-marker { display: none; }

.catalogue-ligne__resume::after {
    content: "▾";
    color: rgba(var(--white-rgb), var(--voile-mention, 0.62));
    font-size: 12px;
    transition: transform .18s ease;
    flex: 0 0 auto;
}

.catalogue-ligne[open] > .catalogue-ligne__resume::after {
    transform: rotate(180deg);
}

.catalogue-ligne__nom {
    font-weight: 600;
    min-width: 0;
    overflow-wrap: anywhere;
}

.catalogue-ligne__code {
    margin-left: 8px;
    font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
    font-size: 0.78rem;
    font-weight: 400;
}

.catalogue-ligne__etat {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-left: auto;
    margin-right: 8px;
}

.catalogue-ligne__prix {
    font-variant-numeric: tabular-nums;
    font-weight: 600;
}

.catalogue-formulaire {
    display: flex;
    flex-direction: column;
    gap: 14px;
    padding: 4px 16px 18px;
}

.catalogue-formulaire__rangee {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
    gap: 12px 16px;
}

.catalogue-formulaire .champ {
    display: flex;
    flex-direction: column;
    gap: 4px;
    min-width: 0;
}

.catalogue-formulaire .champ input,
.catalogue-formulaire .champ select,
.catalogue-formulaire .champ textarea {
    width: 100%;
    box-sizing: border-box;
}

.catalogue-pages,
.catalogue-langue {
    margin: 0;
    padding: 12px 14px;
    border: 1px solid rgba(var(--white-rgb), 0.10);
    border-radius: 10px;
}

.catalogue-pages legend,
.catalogue-langue legend {
    padding: 0 6px;
    font-size: 0.8rem;
    font-weight: 700;
    letter-spacing: .04em;
    text-transform: uppercase;
    opacity: .7;
}

.catalogue-langue {
    display: flex;
    flex-direction: column;
    gap: 10px;
}

.catalogue-pages__case {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 4px 0;
    cursor: pointer;
}

.catalogue-pages__case input[type="checkbox"] {
    width: 18px;
    height: 18px;
    margin: 0;
    accent-color: var(--couleur-accent);
    flex: 0 0 auto;
}

/* La ligne de creation se distingue de celles qui modifient l'existant. */
.catalogue-ligne--nouveau {
    border-style: dashed;
}

/* Deux portes cote a cote sous les interrupteurs : voir la boutique praticien,
   regler le catalogue client. Empilees, elles s'etiraient chacune sur toute la
   largeur du bloc de reglage. */
.reglage-boutique__portes {
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
}

/* ===== L'etat de l'agent de traitement =====

   Une PRESENCE CONSTATEE, pas une disponibilite : le pont est a sens unique,
   on ne peut pas lui demander s'il va bien, seulement voir qu'il est passe. */

/* La ligne du pont dit un ETAT, les chiffres au-dessus comptent des choses a
   faire. Le filet et l'air qui les separent disent cette difference de
   nature, que rien d'autre ne signale. */
.dashboard-pont {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px;

    /* UN SEUL RACCOURCI, et il vient en dernier : un `margin-top` pose plus
       haut se faisait effacer par le `margin` qui suivait, et la ligne
       restait collee a ce qui la precede. */
    margin: 14px 0 0;
    font-size: 0.88rem;
}

.dashboard-pont__pastille {
    width: 8px;
    height: 8px;
    border-radius: 50%;
    flex: 0 0 auto;
}

.dashboard-pont--ok .dashboard-pont__pastille {
    background: rgb(var(--share-bright-rgb));

    /* Un halo doux : le point seul se perd dans une carte chargee, et c'est
       le premier signe qu'on vient chercher. */
    box-shadow: 0 0 0 3px rgba(var(--share-bright-rgb), 0.18);
}

.dashboard-pont--ok {
    color: rgba(var(--white-rgb), 0.78);
}

.dashboard-pont--muet .dashboard-pont__pastille {
    background: rgb(var(--amber-rgb));
    box-shadow: 0 0 0 3px rgba(var(--amber-rgb), 0.18);
}

.dashboard-pont--muet {
    color: rgba(var(--amber-rgb), 0.95);
}

/* Le nombre de tests qui attendent : il ne s'affiche que s'il y en a, et c'est
   lui qui fait la difference entre un silence banal et un silence qui coute.

   ELLE TIENT SEULE DEPUIS LE 02/09. Elle vivait dans la ligne d'etat du
   pont, qui a ete retiree : sans le `display` ci-dessous, un paragraphe
   s'etire sur toute la largeur et la pastille devient une barre. */
.dashboard-pont__file {
    display: inline-block;
    margin: 14px 0 0;
    padding: 2px 9px;
    border-radius: 999px;
    border: 1px solid currentColor;
    font-size: 0.78rem;
    opacity: .9;
}

/* ======================================================================
   LE SOLDE DE TRAITEMENT, SUR LA FICHE D'UN COMPTE
   ======================================================================
   Ces classes etaient posees dans le gabarit et traduites nulle part : la
   carte rendait « 100 Solde » en deux morceaux de texte brut, sans le
   moindre style. Le nombre est ce qu'on vient lire, il porte donc le poids ;
   la phrase autour reste discrete.
   ====================================================================== */
/* --- L ECOLE DE FORMATION, SUR LA FICHE D UN COMPTE ---------------------- */

/* Un champ et un bouton : ils tiennent sur une ligne au large et s'empilent au
   serre, sans largeur imposee qui deborderait. */
.admin-ecole__form {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    gap: 12px;
}

.admin-ecole__champ {
    display: flex;
    flex-direction: column;
    gap: 4px;
    flex: 1 1 180px;
    min-width: 0;
}

.admin-ecole__champ > span {
    font-size: 11px;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: var(--texte-discret);
}

.admin-ecole__champ input {
    width: 100%;
    min-width: 0;
}

.admin-ecole__etat {
    margin: 14px 0 10px;
    color: var(--texte-discret);
}

.admin-users-credits__aide {
    margin: 0 0 14px;
    color: var(--texte-discret);
}

.admin-users-credits__etat {
    display: flex;
    align-items: baseline;
    flex-wrap: wrap;
    gap: 4px 10px;
    margin: 0 0 14px;
    padding: 10px 14px;
    border-radius: 12px;
    border: 1px solid rgba(var(--portal-accent-rgb), 0.22);
    background: rgba(var(--portal-accent-rgb), 0.07);
    /*
     * PAS `--texte-fort` ICI. Ce nom de role vaut #111827, l'encre du PORTAIL
     * CLAIR. Pose sur une carte sombre, il donnait du noir sur bleu nuit :
     * 1,4 de rapport, illisible. Quand le role contredit la surface, on
     * descend sur l'echelle neutre, celle que prend deja le titre de la carte.
     */
    color: var(--ink-200);
    font-weight: 600;
    /* Les chiffres s'alignent d'une fiche a l'autre. */
    font-variant-numeric: tabular-nums;
}

/* La reserve est une precision, pas le solde : elle ne rivalise pas avec lui. */
.admin-users-credits__reserve {
    color: var(--texte-discret);
    font-weight: 400;
}

/* ======================================================================
   LA PAGE DES PROGRAMMES D'UN CLIENT
   ======================================================================
   Elle n'avait aucune feuille a elle : le navigateur rendait des boutons
   bleus, verts et rouges par defaut, un champ de fichier natif, et sept
   lignes de « Libelle: valeur » par programme.

   La couleur suit la regle du produit : l'or appartient aux programmes,
   le rouge a ce qui est irreversible, et rien d'autre n'est peint.
   ====================================================================== */

.programmes-tete h1 {
    margin: 6px 0 2px;
}

.programmes-tete__mail {
    margin: 0;
    color: var(--texte-discret);
}

/* Un lien, pas un second bouton de retour empile sous le premier. */
.programmes-tete__lien {
    display: inline-block;
    margin-top: 12px;
    color: var(--texte-discret);
    text-decoration: none;
    border-bottom: 1px solid rgba(var(--white-rgb), 0.18);
    padding-bottom: 1px;
}

.programmes-tete__lien:hover {
    color: var(--ink-200);
    border-bottom-color: rgba(var(--white-rgb), var(--voile-mention-basse, 0.42));
}

/* ---- La barre d'actions ---- */
.programmes-barre {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 12px 16px;
}

.programmes-depot {
    display: flex;
    /*
     * `center`, PAS `stretch`. Le jeton anti-rejeu de `@csrf` est un champ
     * cache, et une regle generale des formulaires lui donne une marge basse :
     * en `stretch` il ajoutait huit pixels a la ligne, et le depot se
     * retrouvait quatre pixels plus haut que le bouton d'a cote. On le sort du
     * flux pour de bon, et on centre le reste.
     */
    align-items: center;
    margin: 0;
    /* Le depot est l'action principale : il prend la place qui reste. */
    flex: 1 1 420px;
    min-width: 0;
}

/*
 * LE CHOIX DU FICHIER ET LE DEPOT SONT UN SEUL OBJET.
 *
 * Deux boites accolees : a gauche on choisit, a droite on envoie. Le champ
 * natif est masque mais reste dans le `<label>`, donc tout le bloc gauche est
 * cliquable et le clavier y arrive toujours.
 */
.programmes-fichier {
    /*
     * PAS DE MARGE. C'est un `<label>`, et la regle generale des formulaires
     * leur donne huit pixels sous le menton. Centre dans la ligne, sa boite de
     * marge faisait 54 px quand celle du bouton en faisait 46 : le champ se
     * calait quatre pixels plus haut, et les deux moities du meme objet ne se
     * touchaient plus. Mesure avant : champ 400..446, bouton 404..450.
     */
    margin: 0;
    position: relative;
    display: inline-flex;
    align-items: center;
    gap: 12px;
    flex: 1 1 auto;
    min-width: 0;
    height: 46px;
    padding: 0 14px;
    box-sizing: border-box;
    border: 1px solid rgba(var(--white-rgb), 0.12);
    border-right: none;
    border-radius: 12px 0 0 12px;
    background: rgba(var(--ink-900-rgb), 0.36);
    cursor: pointer;
}

.programmes-depot input[type="hidden"] {
    display: none;
}

.programmes-fichier .file-picker__input {
    /* Ni `display: none` ni `visibility` : le champ doit rester focalisable. */
    position: absolute;
    width: 1px;
    height: 1px;
    opacity: 0;
    pointer-events: none;
}

.programmes-fichier__choisir {
    flex: 0 0 auto;
    color: var(--ink-200);
    font-weight: 600;
    white-space: nowrap;
}

/*
 * LE NOM PREND TOUTE LA PLACE LIBRE.
 *
 * Il portait aussi `therapy-upload-combo__name`, uniquement parce que le
 * script la cherchait -- et cette classe plafonne a 220 px, largeur pensee
 * pour l'ancienne boite etroite. Dans le champ pleine largeur d'aujourd'hui,
 * un nom se coupait a 220 px alors que 535 etaient libres. La classe est
 * retiree du balisage, et le plafond neutralise ici par precaution.
 */
.programmes-fichier__nom {
    flex: 1 1 auto;
    /* `min-width: 0` autorise le retrecissement sous la largeur du texte :
       sans lui, un element flexible refuse de descendre sous son contenu et
       c'est le champ qui deborde au lieu du texte qui se coupe. */
    min-width: 0;
    max-width: none;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    color: var(--texte-discret);
    font-size: 14px;
}

.programmes-fichier:focus-within {
    border-color: rgba(var(--teinte-or), 0.55);
}

/*
 * TOUT RETIRER RESTE POSSIBLE, SANS ETRE CE QU'ON VOIT EN PREMIER.
 *
 * C'etait le bouton le plus voyant de la page : un rectangle rouge plein,
 * plus large que celui qui depose un programme. Il devient un lien, il garde
 * sa couleur d'avertissement, et il demande toujours confirmation.
 */
.programmes-barre__retrait {
    margin: 0 0 0 auto;
}

.lien-danger {
    appearance: none;
    border: none;
    background: none;
    padding: 6px 2px;
    color: rgb(var(--red-light-rgb));
    font: inherit;
    text-decoration: underline;
    text-underline-offset: 3px;
    text-decoration-color: rgba(var(--red-rgb), 0.45);
    cursor: pointer;
}

.lien-danger:hover {
    text-decoration-color: rgb(var(--red-light-rgb));
}

.lien-danger:disabled {
    color: var(--texte-discret);
    text-decoration: none;
    cursor: default;
}

/* ---- Le tableau ---- */
.programmes-table td {
    vertical-align: top;
}

.programme-emplacement {
    font-size: 20px;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
    color: var(--ink-200);
}

.programme-id {
    color: var(--texte-discret);
    font-variant-numeric: tabular-nums;
}

.programme-nom {
    display: block;
    font-weight: 700;
    color: var(--ink-200);
}

.programme-description {
    display: block;
    margin-top: 3px;
    color: var(--texte-discret);
    font-size: 13px;
}

/*
 * DEUX COLONNES, PAS UNE PHRASE PAR LIGNE.
 *
 * « Seances effectuees: 1 » puis « Limite de seances: ∞ » en texte courant
 * mettait le libelle et le chiffre a une place differente a chaque ligne :
 * aucun nombre n'etait comparable a celui du dessous. Ici l'oeil descend une
 * seule colonne de chiffres.
 */
.programme-paires {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    gap: 3px 14px;
    margin: 0;
    font-size: 13px;
}

.programme-paires dt {
    color: var(--texte-discret);
}

.programme-paires dd {
    margin: 0;
    text-align: right;
    color: var(--ink-200);
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

.programme-eteint {
    display: inline-block;
    margin-top: 8px;
    color: rgb(var(--red-light-rgb));
    font-size: 12px;
    font-weight: 600;
}

.programme-type {
    display: block;
    font-weight: 600;
    color: var(--ink-200);
}

.programme-source {
    display: block;
    margin-top: 3px;
    color: var(--texte-discret);
    font-size: 13px;
}

.programme-lien {
    display: inline-block;
    margin-top: 6px;
    color: rgb(var(--portal-accent-rgb));
    font-size: 13px;
}

/* ---- Les deux actions d'une ligne ---- */
.programme-actions {
    display: flex;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
}

.programme-actions form {
    margin: 0;
}

/*
 * MODIFIER N'EST PAS BLEU. Le bleu du produit dit « poster, envoyer » ;
 * ouvrir un formulaire d'edition n'envoie rien. Ces deux commandes sont
 * neutres, seule celle qui detruit porte sa couleur.
 */
.bouton-ligne {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    height: 34px;
    padding: 0 14px;
    box-sizing: border-box;
    border: 1px solid rgba(var(--white-rgb), 0.16);
    border-radius: 9px;
    background: rgba(var(--white-rgb), 0.06);
    color: var(--ink-200);
    font: inherit;
    font-size: 13px;
    white-space: nowrap;
    text-decoration: none;
    cursor: pointer;
    transition: background .14s ease, border-color .14s ease, color .14s ease;
}

.bouton-ligne:hover {
    background: rgba(var(--white-rgb), 0.12);
    border-color: rgba(var(--white-rgb), 0.30);
}

.bouton-ligne--danger {
    border-color: rgba(var(--red-rgb), 0.32);
    /* UNE TEINTE DE DONNEE N EST PAS UNE ENCRE. `--etat-charge` sert a REMPLIR
       une carte d'organe en charge ; pose comme texte il rend 4,15 en sombre et
       2,71 en clair, mesure. Aucun rouge unique ne passe 4,5 des deux cotes :
       il faut le role qui bascule. `--couleur-danger-doux` est ce role, pale
       sur sombre et profond sur clair, et c'est deja lui qui a repare
       `.status.active`. */
    color: var(--couleur-danger-doux);
}

.bouton-ligne--danger:hover {
    background: rgba(var(--red-rgb), 0.14);
    border-color: rgba(var(--red-rgb), 0.55);
}

.bouton-ligne:disabled {
    opacity: .55;
    cursor: default;
}

/* Le lisere de ligne reprend le ton de l'etat, comme sur la liste des comptes. */
.programme-ligne--actif   { --row-rgb: var(--teinte-verte); }
.programme-ligne--attente { --row-rgb: var(--teinte-or); }
.programme-ligne--sans    { --row-rgb: var(--teinte-bleue); }

@media (max-width: 900px) {
    .programmes-depot {
        flex: 1 1 100%;
        flex-wrap: wrap;
    }

    .programmes-fichier {
        flex: 1 1 100%;
        border-right: 1px solid rgba(var(--white-rgb), 0.12);
        border-radius: 12px;
    }

    .bouton-programme {
        flex: 1 1 100%;
        margin-top: 8px;
        border-radius: 12px;
    }

    .programmes-barre__retrait {
        margin-left: 0;
    }
}

/* ======================================================================
   LES TABLEAUX D'EXPLOITATION
   ======================================================================
   `.admin-table` etait posee dans plusieurs vues d'administration (file
   d'attente, fiche d'un compte) et traduite nulle part : le navigateur
   rendait un tableau brut, colonnes collees, sans separation de lignes.
   ====================================================================== */
.admin-table {
    width: 100%;
    /* Separees et non fusionnees : c'est la seule facon pour qu'une entete
       collante peigne son propre fond. Voir la table des operations. */
    border-collapse: separate;
    border-spacing: 0;
    font-size: 14px;
}

.admin-table th {
    padding: 8px 12px;
    text-align: left;
    color: var(--texte-discret);
    font-size: 12px;
    font-weight: 600;
    letter-spacing: .04em;
    text-transform: uppercase;
    border-bottom: 1px solid rgba(var(--white-rgb), 0.12);
    white-space: nowrap;
}

.admin-table td {
    padding: 10px 12px;
    vertical-align: top;
    border-bottom: 1px solid rgba(var(--white-rgb), 0.06);
    color: var(--ink-200);
}

.admin-table tbody tr:last-child td {
    border-bottom: none;
}

.admin-table tbody tr:hover td {
    background: rgba(var(--white-rgb), 0.04);
}

/* ======================================================================
   LA FICHE D'UNE PERSONNE : TOUT CE QUI LA CONCERNE
   ====================================================================== */
.profil-bloc + .profil-bloc {
    margin-top: 18px;
}

.profil-bloc h2 {
    margin: 0 0 4px;
}

.profil-sous-titre {
    margin: 20px 0 8px;
    font-size: 14px;
    color: var(--texte-discret);
    font-weight: 600;
}

/*
 * UNE CARTE VIDE LE DIT, ELLE NE DISPARAIT PAS.
 *
 * Un bloc absent se lit comme un bloc qu'on n'a pas pense a regarder. La
 * phrase, elle, repond a la question posee.
 */
.profil-vide {
    margin: 12px 0 0;
    padding: 14px;
    border-radius: 10px;
    border: 1px dashed rgba(var(--white-rgb), 0.12);
    color: var(--texte-discret);
    text-align: center;
}

.profil-reste {
    margin: 10px 0 0;
    color: var(--texte-discret);
    font-size: 13px;
}

.profil-lien-ecran {
    margin: 14px 0 0;
}

/* Les tableaux d'une fiche peuvent etre larges : ils defilent chez eux, la
   page ne part jamais de travers. */
.profil-tableau {
    margin-top: 12px;
    overflow-x: auto;
}

.profil-table__nombre {
    text-align: right;
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

.profil-table__quand {
    color: var(--texte-discret);
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

/* Un code technique reste un code : on ne le deguise pas en phrase. */
.profil-operation {
    display: inline-block;
    padding: 2px 8px;
    border-radius: 999px;
    background: rgba(var(--white-rgb), 0.06);
    border: 1px solid rgba(var(--white-rgb), 0.10);
    color: var(--ink-200);
    font-size: 12px;
    font-family: ui-monospace, "SFMono-Regular", Menlo, Consolas, monospace;
}

.profil-objet {
    display: block;
    color: var(--ink-200);
}

.profil-note {
    display: block;
    margin-top: 2px;
    color: var(--texte-discret);
    font-size: 12px;
}

.profil-note--erreur {
    color: rgb(var(--red-light-rgb));
}

/*
 * LE SIGNE PORTE LA COULEUR. En descendant la colonne, un debit et un credit
 * se distinguent sans lire le chiffre.
 */
.profil-delta {
    font-weight: 700;
    font-variant-numeric: tabular-nums;
}

.profil-delta--plus  { color: var(--green-soft); }
.profil-delta--moins { color: rgb(var(--red-light-rgb)); }

/* ---- La rangee de chiffres en tete de carte ---- */
.profil-chiffres {
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
    margin-top: 14px;
}

.profil-chiffre {
    display: flex;
    flex-direction: column;
    gap: 2px;
    flex: 1 1 130px;
    min-width: 0;
    padding: 12px 14px;
    border-radius: 12px;
    border: 1px solid rgba(var(--white-rgb), 0.08);
    background: rgba(var(--white-rgb), 0.04);
}

.profil-chiffre__valeur {
    font-size: 24px;
    font-weight: 700;
    line-height: 1.1;
    color: var(--ink-200);
    font-variant-numeric: tabular-nums;
}

/* L'etape n'est pas un nombre : elle garde la taille du texte. */
.profil-chiffre__valeur--texte {
    font-size: 14px;
    font-weight: 400;
}

.profil-chiffre__quoi {
    color: var(--texte-discret);
    font-size: 12px;
}

/* Ce qui attend d'etre envoye n'est pas une panne, mais ca se regarde. */
.profil-chiffre--attention {
    border-color: rgba(var(--amber-rgb), 0.35);
    background: rgba(var(--amber-rgb), 0.07);
}

.profil-chiffre--etape {
    flex: 1 1 200px;
}

/* ---- Le reseau : des paires ---- */
.profil-paires {
    display: grid;
    grid-template-columns: minmax(0, auto) minmax(0, 1fr);
    gap: 8px 18px;
    margin: 14px 0 0;
}

.profil-paires dt {
    color: var(--texte-discret);
}

.profil-paires dd {
    margin: 0;
    color: var(--ink-200);
}

.profil-liste {
    margin: 8px 0 0;
    padding: 0;
    list-style: none;
    display: grid;
    gap: 8px;
}

.profil-liste li {
    padding: 8px 12px;
    border-radius: 10px;
    background: rgba(var(--white-rgb), 0.04);
}

@media (max-width: 700px) {
    .profil-paires {
        grid-template-columns: minmax(0, 1fr);
        gap: 2px 0;
    }

    .profil-paires dd {
        margin-bottom: 10px;
    }
}

/* ----------------------------------------------------------------------
   L'HISTORIQUE DES OPERATIONS : CHERCHER ET TOURNER LES PAGES
   ----------------------------------------------------------------------
   La barre de recherche est devenue un formulaire : elle porte le champ, le
   nombre de lignes par page et le bouton, sur une seule ligne.
   ---------------------------------------------------------------------- */
.processing-transactions-search {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 10px;
    margin: 0;
}

/*
 * LES TROIS COMMANDES ONT LA MEME HAUTEUR ET LA MEME LIGNE.
 *
 * Le champ de recherche portait 16 px de marge basse, herites de la regle
 * generale des champs de formulaire : sa boite faisait 55 px de haut quand le
 * menu et le bouton en faisaient 34. Centres dans la barre, les trois se
 * calaient a trois hauteurs differentes -- champ a 743, les deux autres a 754.
 *
 * On annule la marge et on impose une hauteur commune. Selecteur a deux
 * classes : une classe seule ne l'emporterait pas sur les regles de champ de
 * cette feuille.
 */
.processing-transactions-search .admin-users-panel__search-wrap,
.processing-transactions-search .admin-users-panel__search,
.processing-transactions-search select,
.processing-transactions-search .bouton-ligne {
    margin: 0;
}

.processing-transactions-search .admin-users-panel__search,
.processing-transactions-search select,
.processing-transactions-search .bouton-ligne {
    height: 38px;
    min-height: 38px;
    box-sizing: border-box;
}

/* Le champ garde son rembourrage a droite pour la croix d'effacement. */
.processing-transactions-search .admin-users-panel__search {
    padding-top: 0;
    padding-bottom: 0;
}

.processing-par-page {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    /* C'est un `<label>` : la marge basse generale des formulaires le
       decalerait de quatre pixels par rapport a ses voisins. */
    margin: 0;
    color: var(--texte-discret);
    font-weight: 400;
    white-space: nowrap;
}

.processing-par-page select {
    margin: 0;
    min-height: 34px;
    padding: 0 8px;
}

.processing-pagination {
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: 10px 16px;
    margin-top: 14px;
    padding-top: 14px;
    border-top: 1px solid rgba(var(--white-rgb), 0.08);
}

/*
 * COMBIEN ON VOIT, SUR COMBIEN.
 *
 * Sans ce compte, une page pleine ne dit pas s'il en reste, et une recherche
 * ne dit pas ce qu'elle a trouve : deux questions qu'on se pose a chaque fois.
 */
.processing-pagination__compte {
    margin: 0;
    color: var(--texte-discret);
    font-size: 13px;
    font-variant-numeric: tabular-nums;
}

.processing-pagination .table-pagination {
    margin: 0;
}

/* ======================================================================
   LA FICHE D'UN PROGRAMME
   ======================================================================
   Les huit champs etaient empiles sur une colonne pleine page : un champ de
   onze cents pixels pour saisir « 15 ». En grille, les courts se rangent
   par deux ou trois et l'ensemble se voit d'un coup, sans defiler.
   ====================================================================== */
.programme-fiche__tete h1 {
    margin: 6px 0 12px;
}

.programme-fiche__etats {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 8px 12px;
}

/*
 * POUR QUI ON CREE. Sur la fiche d'un programme existant, le nom du client est
 * dans la commande de retour et n'a pas a etre repete. Sur un ecran de
 * CREATION, rien d'autre ne le dit : on fabrique quelque chose pour quelqu'un.
 */
.programme-fiche__pour {
    margin: 6px 0 0;
    color: var(--texte-discret);
}

.programme-fiche__type {
    color: var(--texte-discret);
    font-size: 13px;
}

/* Un nom de fichier ne se lit pas, il se reconnait : il ne merite pas de
   pousser la colonne des valeurs. */
.programme-fiche__fichier {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    font-family: ui-monospace, "SFMono-Regular", Menlo, Consolas, monospace;
    font-size: 13px;
}

/* Les paires d'une fiche ont de la place : le libelle ne se serre pas. */
.programme-paires--large {
    grid-template-columns: minmax(0, auto) minmax(0, 1fr);
    gap: 8px 20px;
    font-size: 14px;
}

.programme-paires--large dd {
    text-align: left;
}

/* ---- La grille des champs ---- */
.grille-champs {
    display: grid;
    /*
     * `auto-fit` PLUTOT QU'UN NOMBRE DE COLONNES FIXE : la fiche d'une therapie
     * a un champ de plus que celle d'une video, et le nombre de colonnes doit
     * suivre la largeur disponible, pas le contenu.
     */
    grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
    gap: 14px 18px;
    margin-bottom: 18px;
}

.champ {
    display: flex;
    flex-direction: column;
    gap: 4px;
    min-width: 0;
}

/* Ce qui s'ecrit en toutes lettres prend la ligne entiere. */
.champ--large {
    grid-column: 1 / -1;
}

/*
 * LES MARGES DES CHAMPS SONT REPRISES ICI.
 *
 * La regle generale donne huit pixels sous chaque `<label>` et seize sous
 * chaque champ. Dans une grille qui pose deja son propre ecart, ces marges
 * s'ajoutent au lieu de le remplacer : les lignes se decalent les unes par
 * rapport aux autres et rien ne s'aligne plus.
 */
.grille-champs label,
.grille-champs input,
.grille-champs textarea,
.grille-champs select {
    margin: 0;
    width: 100%;
    box-sizing: border-box;
}

.grille-champs label {
    /* `--texte-discret` rend 3,84 a 13 px sur une carte claire (mesure). Ce
       libelle est du texte de formulaire, pas une legende : il prend le meme
       cran que les autres libelles du produit. */
    color: rgba(var(--white-rgb), var(--voile-mention, 0.54));
    font-size: 13px;
    font-weight: 600;
}

.grille-champs textarea {
    min-height: 76px;
    resize: vertical;
}

/* ---- Les deux interrupteurs ---- */
.programme-fiche__bascules {
    display: flex;
    flex-wrap: wrap;
    gap: 10px 14px;
    margin-bottom: 18px;
}

.bascule {
    display: inline-flex;
    align-items: center;
    gap: 9px;
    /* Un `<label>` : sa marge basse generale desalignerait la rangee. */
    margin: 0;
    padding: 10px 14px;
    border-radius: 11px;
    border: 1px solid rgba(var(--white-rgb), 0.10);
    background: rgba(var(--white-rgb), 0.04);
    color: var(--ink-200);
    font-weight: 500;
    cursor: pointer;
}

.bascule input {
    width: auto;
    margin: 0;
}

.bascule:hover {
    border-color: rgba(var(--white-rgb), 0.24);
}

/*
 * CELUI QUI EFFACE PORTE SA COULEUR MEME AU REPOS.
 *
 * « Remettre a zero l'activation » efface l'avancement du client. Pose a cote
 * de « programme disponible » dans la meme boite grise, rien ne disait que
 * l'un est un reglage et l'autre une perte.
 */
.bascule--attention {
    border-color: rgba(var(--amber-rgb), 0.34);
    background: rgba(var(--amber-rgb), 0.07);
    color: var(--amber-pale);
}

.bascule--attention:hover {
    border-color: rgba(var(--amber-rgb), 0.58);
}

/* La carte de suppression se detache de celle qui la precede. */
.programme-fiche .card-danger {
    margin-top: 18px;
}


/* ----------------------------------------------------------------------
   LES DEUX GESTES D'UNE NOTIFICATION
   ----------------------------------------------------------------------
   « Ouvrir » emmene, « Marquer comme lu » range et laisse sur place. Cote a
   cote, et de meme facture : aucun des deux n'est plus important que l'autre,
   ils repondent a deux situations differentes.
   ---------------------------------------------------------------------- */
.notifications-item__actions {
    display: flex;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
    flex: 0 0 auto;
}

.notifications-item__actions form {
    margin: 0;
}

/* Le bouton d'export, dans la ligne du fichier de therapie. */
.programme-fiche__export {
    margin-left: 12px;
    vertical-align: middle;
}

@media (max-width: 640px) {
    .notifications-item__actions {
        width: 100%;
    }

    .notifications-item__actions form,
    .notifications-item__actions .bouton-ligne {
        flex: 1 1 auto;
    }
}

/* ======================================================================
   LA LISTE EN CARTES, SUR TELEPHONE : DEUX FUITES DE HAUTEUR
   ======================================================================
   Mesure sur un client du tableau de bord praticien, ecran de 812 px :
   UNE carte occupait 433 px. Moins de deux clients par ecran pour une liste
   qui sert justement a les parcourir.

   LA REQUETE DIT 880 px, ET C'EST LA MESURE CI-DESSUS QUI LE PROUVE : elle a
   ete prise a 812 px, largeur que l'ancienne borne de 640 excluait. Le tableau
   bascule en cartes a 880 (`.responsive-table`, lk.css) ; tout ce qui repare
   cette bascule doit commencer au meme endroit. Entre 641 et 880, les trois
   pastilles d'action heritaient donc du `width: 100%` du tableau generique et
   s'empilaient en trois barres de 740 px portant un emoji seul.
   ====================================================================== */
@media (max-width: 880px) {
    /*
     * 1. LES PASTILLES D'ACTION REPRENNENT LEUR TAILLE.
     *
     * Elles portent `btn` ET `ligne-action`. Sous 640 px, `.btn` impose
     * `width: 100%` : une classe seule ne l'emporte pas sur une autre classe
     * seule, et c'est la derniere ecrite qui gagne. Les trois pastilles de
     * 46 px devenaient donc trois barres de 270, empilees : 170 px pour trois
     * icones qui tiennent sur une ligne.
     *
     * Selecteur a deux classes, donc plus fort, et local a ces pastilles-la.
     */
    .btn.ligne-action {
        width: 46px;
        min-width: 46px;
        flex: 0 0 auto;
    }

    /*
     * ET LEUR RANGEE REDEVIENT UNE RANGEE.
     *
     * `.responsive-table__actions` passe en colonne sous 640 px, ce qui est le
     * bon reglage pour une cellule qui porte des boutons pleine largeur
     * (« Modifier », « Supprimer »). Ce n'est pas le bon pour trois pastilles
     * de 46 px, qui tiennent cote a cote meme sur le plus etroit des ecrans.
     *
     * `:has()` distingue les deux cas sans avoir a marquer le balisage : on ne
     * remet en ligne que les rangees qui portent des pastilles.
     */
    .responsive-table__actions:has(.ligne-action),
    .ligne-actions {
        flex-direction: row;
        flex-wrap: nowrap;
        width: auto;
    }

    /*
     * 2. L'ETIQUETTE SE MET A COTE DE SA VALEUR, PAS AU-DESSUS.
     *
     * Chaque cellule empilee ecrivait son intitule sur une ligne et sa valeur
     * sur la suivante : cinq cellules, dix lignes. En paire sur la meme ligne,
     * l'etiquette a gauche et la valeur a droite, on lit la meme chose en
     * cinq.
     *
     * Le titre garde son traitement : son etiquette reste cachee, il est le
     * titre de la carte.
     */
    .liste-carte tbody tr.liste-carte__ligne > td {
        display: flex;
        align-items: baseline;
        justify-content: space-between;
        gap: 10px 14px;
        flex-wrap: wrap;
    }

    .liste-carte tbody tr.liste-carte__ligne > td .responsive-table__label {
        flex: 0 0 auto;
        margin: 0;
        color: var(--texte-discret);
        font-size: 12px;
        font-weight: 600;
    }

    /* Le titre et le pied restent en bloc : l'un est un titre, l'autre une
       mention de bas de carte. */
    .liste-carte tbody tr.liste-carte__ligne > td.cellule--titre,
    .liste-carte tbody tr.liste-carte__ligne > td.cellule--pied {
        display: block;
    }

    /*
     * LES PASTILLES SE CENTRENT, elles ne se rangent pas a droite.
     *
     * Elles y etaient posees comme les valeurs des autres lignes, par une
     * marge automatique a gauche. Mais une valeur repond a une etiquette et se
     * lit en face d'elle ; ces pastilles n'ont plus d'etiquette en carte, et
     * une rangee de boutons seule, calee dans un coin, se lit comme un reste.
     * Au centre, elle se lit comme la barre de commandes de la carte.
     */
    .liste-carte tbody tr.liste-carte__ligne > td:has(.ligne-actions) .ligne-actions {
        margin-left: auto;
        margin-right: auto;
        justify-content: center;
    }

    /*
     * ET SON ETIQUETTE S'EFFACE, sinon le centre n'est pas le centre.
     *
     * « Actions » restait a gauche et poussait la rangee : les pastilles se
     * centraient dans ce qui restait, a 29 px du milieu de la carte. Ni
     * alignees ni centrees.
     *
     * Elle ne manque a personne : trois pastilles se reconnaissent seules, et
     * la liste des comptes s'en passait deja. Les deux listes cessent au
     * passage de diverger sur la meme rangee de boutons.
     */
    .liste-carte tbody tr.liste-carte__ligne > td:has(.ligne-actions) > .responsive-table__label {
        display: none;
    }
}


/* --- Pas de cadre dans le cadre -------------------------------------------
   -------------------------------------------------------------------------
   Le formulaire des reglages est deja une carte, avec sa bordure et son fond.
   Chaque bloc y posait les siens : deux cadres emboites, et l'oeil compte les
   bordures au lieu de lire les titres.

   On garde le RYTHME sans le cadre : un filet entre les blocs, et rien sur le
   premier. Les blocs depliables gardent le leur, eux : leur bordure dit qu'il
   y a quelque chose a ouvrir. */
.admin-settings-card > .processing-preset:not(.processing-preset--depliable) {
    border: 0;
    background: none;
    border-radius: 0;
    padding: 18px 0 0;
    border-top: 1px solid rgba(var(--white-rgb), 0.08);
}

.admin-settings-card > .processing-preset:not(.processing-preset--depliable):first-of-type {
    border-top: 0;
    padding-top: 0;
}

/* =========================================================================
   LE COUT D'UN TEST, REGLABLE SUR LE TABLEAU DE BORD
   =========================================================================
   Il se reglait dans une ligne du tableau des produits de `/admin/processing`.
   C'est le chiffre le plus consulte du produit, et il fallait savoir ou
   chercher : il est desormais lisible et modifiable sur la carte du
   traitement, qui menait deja a cet ecran.

   UNE SEULE LIGNE, ET ELLE SE REPLIE. Le libelle, le champ et le bouton
   tiennent cote a cote sur une carte double ; sous 560 px le champ passe a la
   ligne plutot que de se reduire a trois caracteres.

   LE CHAMP EST ETROIT A DESSEIN. Un cout tient en trois ou quatre chiffres, et
   un champ large invite a y ecrire autre chose qu'un nombre.
   ========================================================================= */
.dashboard-cout {
    display: flex;
    align-items: center;
    gap: 10px;
    flex-wrap: wrap;
    margin-top: 14px;
    padding-top: 14px;
    border-top: 1px solid rgba(var(--white-rgb), 0.08);
}

.dashboard-cout__libelle {
    font-size: 13px;
    font-weight: 600;
    color: rgba(var(--white-rgb), 0.78);
}

.dashboard-cout__champ {
    width: 92px;
    padding: 7px 10px;
    border-radius: 8px;
    border: 1px solid rgba(var(--white-rgb), 0.18);
    background: rgba(var(--black-rgb), 0.28);
    color: var(--white);
    font-size: 14px;
    font-variant-numeric: tabular-nums;
}

.dashboard-cout__champ:focus {
    outline: none;
    border-color: rgba(var(--portal-accent-rgb), 0.65);
}

/* Le meme bouton d'action que partout ailleurs, a la taille d'une ligne de
   reglage : c'est un enregistrement, pas l'action principale de la page. */
.dashboard-cout__valider {
    padding: 7px 14px;
    font-size: 13px;
}

/* =========================================================================
   LE SENS DE L'OPERATION SE LIT SUR LA PASTILLE
   =========================================================================
   Vert pour ce qui entre, rouge pour ce qui sort, comme la ligne de `/users`
   dit le type de compte par sa teinte.

   LA TEINTE RESTE SUR LA PASTILLE ET SUR LE NOMBRE, jamais sur la ligne. Un
   debit manuel est une ecriture normale et correcte ; une ligne rouge en
   ferait un incident, alors que le rouge annonce ailleurs une erreur sur ces
   ecrans. On donne la lecture d'un coup d'oeil sans faire crier une operation
   banale.

   LE MOT RESTE ECRIT dans la pastille : la couleur double l'information, elle
   ne la remplace pas. C'est la regle de `/users`, et elle vaut pour qui ne lit
   pas les couleurs comme pour qui imprime en noir et blanc.
   ========================================================================= */
.processing-transaction-type--credit {
    background: rgba(var(--green-rgb, 34, 197, 94), 0.14);
    border-color: rgba(var(--green-rgb, 34, 197, 94), 0.34);
    color: #86efac;
}

.processing-transaction-type--debit {
    background: rgba(var(--red-rgb, 239, 68, 68), 0.13);
    border-color: rgba(var(--red-rgb, 239, 68, 68), 0.32);
    color: #fca5a5;
}

/* =========================================================================
   LE MOUVEMENT ET SON RESULTAT SUR UNE SEULE LIGNE
   =========================================================================
   « +100 -> 100 » : ce qui est entre, puis ou en est le compte apres. Deux
   colonnes portaient ces deux nombres ; depuis que la reserve se tait quand
   elle est nulle, chacune n'en portait plus qu'un seul, et ils se lisent
   ensemble.

   LA FLECHE PORTE LE SENS, et elle est masquee aux lecteurs d'ecran : elle
   remplace un libelle, elle n'en ajoute pas un. Les deux nombres se suivent
   dans l'ordre de la lecture, le mouvement puis l'etat.
   ========================================================================= */
.processing-mouvement {
    display: inline-flex;
    align-items: baseline;
    gap: 8px;
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

.processing-mouvement__fleche {
    color: rgba(var(--white-rgb), 0.32);
}

/* L'etat qui suit la fleche n'est pas un mouvement : il ne prend ni le vert ni
   le rouge, sinon deux nombres de teintes differentes se disputeraient la
   lecture alors que l'un explique l'autre. */
.processing-mouvement__apres {
    color: rgba(var(--white-rgb), 0.88);
}

.processing-mouvement__reserve {
    margin-top: 4px;
    font-size: 12px;
    color: rgb(var(--amber-rgb));
    display: flex;
    align-items: baseline;
    gap: 6px;
    flex-wrap: wrap;
}

/* --- Un titre de page ne se pose pas dans une carte -----------------------
   -------------------------------------------------------------------------
   « Reglages systeme / Parametres / Modes generaux... » etait encadre comme
   les reglages qu'il annonce. Deux cartes empilees, la premiere ne se reglant
   pas : on la lisait comme un premier bloc de reglages vide.

   L ESPACE N EST PAS REPOSE ICI. `.admin-dashboard` est un flex en colonne
   avec `gap: var(--espace-section)` : le conteneur rend deja l'air. La marge
   basse de `card` s'y ajoutait -- 86 px mesures sous le titre une fois le
   cadre retire. Le conteneur decide, la piece ne redecide pas.
   ------------------------------------------------------------------------- */
.admin-dashboard__hero--nu {
    margin-bottom: 0;
}
