/* ════════════════════════════════════════════════════════════════════
   MATERIAL 3 · FONDATIONS DE SYDEPLAY
   ════════════════════════════════════════════════════════════════════
   Décision porteur (23/09/2026) : le design system suit l'organisation et
   le vocabulaire de Material 3, avec les valeurs de SydePlay.
   On adopte les RÔLES (primary, surface, outline, les paires on-…), pas
   l'apparence de Google : le rose, Noto Sans et le rayon 12 ne bougent pas.

   RÈGLE DES 44 PX (porteur, 25/09/2026) : de Material 3 on prend les noms,
   les rôles de couleur, les états et les espacements ; les TAILLES et les
   FORMES restent celles de SydePlay. Aucun élément ne dépasse 44 px de haut
   (boutons, boutons icône, champs, listes, recherche, rail, onglets, lignes
   de menu) ; les tags sont plus petits (30, compact 22). Rayon 12 par
   défaut, rayons imbriqués concentriques. Formes Material 3 gardées à la
   demande du porteur : l'interrupteur (52 × 32), le groupe de boutons
   connectés, les puces de filtre et les fenêtres au rayon 28.

   Les anciens noms (--brand, --ink, --panel…) restent valables : ils
   pointent désormais vers ces rôles, donc rien ne casse dans les pages.
   Référence : https://m3.material.io/
   ════════════════════════════════════════════════════════════════════ */

.ds-app, .ds-solo, :root {
  /* ── COULEUR · rôles Material 3, thème clair ───────────────────── */
  --md-sys-color-primary: #FF3676;
  --md-sys-color-on-primary: #FFFFFF;
  --md-sys-color-primary-container: #FFE3EC;
  --md-sys-color-on-primary-container: #7A0B2E;

  /* Secondaire : calculé par @material/material-color-utilities (SchemeTonalSpot,
     graine #FF3676). Sert aux puces choisies et au survol du rail de navigation. */
  --md-sys-color-secondary: #75565b;
  --md-sys-color-on-secondary: #FFFFFF;
  --md-sys-color-secondary-container: #ffd9de;
  --md-sys-color-on-secondary-container: #5c3f44;

  --md-sys-color-surface: #FFFFFF;                       /* la carte, le panneau */
  --md-sys-color-surface-container-lowest: #FFFFFF;
  --md-sys-color-surface-container-low: #F9FAFD;         /* le fond de page */
  --md-sys-color-surface-container: #F0F2F5;
  --md-sys-color-surface-container-high: #E7EEF8;        /* relief : barre de recherche */
  --md-sys-color-surface-container-highest: #DDE5F0;     /* champs de saisie */
  --md-sys-color-on-surface: #1B1C1E;                    /* le texte principal */
  --md-sys-color-on-surface-strong: #3a4149;             /* ajout SydePlay */
  --md-sys-color-on-surface-variant: #6b7480;            /* le texte secondaire */
  --md-sys-color-on-surface-faint: #6e7684;              /* ajout SydePlay · audit du 13/10/2026 : #9aa2ae faisait 2,6:1 ; 4,6:1 sur blanc */

  --md-sys-color-outline: #B8C0CB;                       /* bordure marquée */
  --md-sys-color-outline-variant: #E7EEF8;               /* filet discret */

  /* COULEURS D'ÉTAT (choix du porteur, 20/10/2026, planche « Monochrome + marque », variante A) : plus de
     vert, d'orange ni de rouge étrangers au site, qui cassaient l'immersion. Le validé est un gris-vert sauge
     très discret (texte 9:1 sur blanc, 7,8:1 sur son conteneur) ; l'avertissement vit dans le gris du site
     avec le rose de la marque en icône ; l'erreur et le danger prennent le rose SydePlay et sa paire
     primary-container. Teintes calculées à clarté égale (OKLCH), contrastes mesurés. */
  --md-sys-color-error: var(--md-sys-color-primary);
  --md-sys-color-on-error: var(--md-sys-color-on-primary);
  --md-sys-color-error-container: var(--md-sys-color-primary-container);
  --md-sys-color-on-error-container: var(--md-sys-color-on-primary-container);
  --md-sys-color-success: #35604A;
  --md-sys-color-success-container: #DEF5E8;
  --md-sys-color-on-success-container: #344F40;
  --md-sys-color-warning: var(--md-sys-color-primary);
  --md-sys-color-warning-container: var(--md-sys-color-surface-container-high);
  --md-sys-color-on-warning-container: var(--md-sys-color-on-surface);

  --md-sys-color-inverse-surface: #1B1C1E;               /* le noir de marque */
  --md-sys-color-inverse-on-surface: #FFFFFF;
  /* Constantes des deux thèmes : ce qui se pose sur un média (photo, vidéo) ne suit pas le thème. */
  --md-sys-color-scrim: #000000;                         /* voiles et dégradés sur un média (rôle M3 scrim) */
  --md-sys-color-shadow: #000000;                        /* ombres portées (rôle M3 shadow) */
  --md-sys-color-on-media: #FFFFFF;                      /* ajout SydePlay : texte et icônes sur un média */
  --md-sys-color-rating: #F5B301;                        /* ajout SydePlay : étoiles de note */

  /* ── AJOUTS SYDEPLAY · refonte du Studio (06/10/2026, À valider) ── */
  /* Police à chasse fixe (codes, montants alignés) : elle était écrite en dur dans .codeblock. */
  --sp-font-mono: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  /* Frise et lignes du calage (Publier) : les valeurs écrites en dur dans .wiz-tl et .wiz-row,
     reprises telles quelles et rangées ici une seule fois. */
  /* 07/10/2026 (retour du porteur : moins de couleurs) : rose SydePlay + neutres, plus de vert/orange/violet. */
  --sp-tl-before: #B8C0CB;                 /* avant le film (neutre clair) */
  --sp-tl-pause: color-mix(in srgb, #FF3676 45%, #FFFFFF);   /* pauses (rose atténué) */
  --sp-tl-after: #8A93A0;                  /* après le film (neutre foncé) */
  --sp-tl-watch: #DCE6F7;                  /* « Tu regardes » */
  --sp-tl-point: var(--md-sys-color-primary);   /* points d'ancrage */
  --sp-tl-pause-container: #FFE0EA;  --sp-on-tl-pause-container: #C2185B;   /* pastille d'une pause (rose) */
  --sp-tl-point-container: #FFE0EA;  --sp-on-tl-point-container: #E0115F;   /* pastille d'un point */
  --sp-tl-point-strong: #E0115F;           /* fond plein du badge d'un point (.bdg--point) : le même en clair et en sombre, blanc à 4,8:1 */
  --sp-on-tl-before: #16A34A;              /* icône « début » */
  --sp-on-tl-after: #7C3AED;               /* icône « fin » */
  /* Graphiques des Statistiques (07/10/2026, À valider) : 1re série = primary ; 2e série = le
     bleu vif des badges (.bdg--blue --t, ΔE daltonien 21 avec le rose), le même en clair et en
     sombre ; période précédente = gris on-surface-variant en tirets. Jamais de double axe. */
  --sp-chart-blue: #3264F8;
  --sp-chart-compare: var(--md-sys-color-on-surface-variant);

  /* ── FORME · échelle de rayons Material 3 ──────────────────────── */
  --md-sys-shape-corner-none: 0;
  --md-sys-shape-corner-extra-small: 4px;
  --md-sys-shape-corner-small: 8px;
  --md-sys-shape-corner-medium: 12px;                    /* le rayon par défaut de SydePlay */
  --md-sys-shape-corner-large: 16px;
  --md-sys-shape-corner-extra-large: 28px;
  --md-sys-shape-corner-full: 999px;
  /* Arrondis des GRANDS blocs, ceux qui suivent la taille de l'écran (bloc vedette, tuiles de
     catégories, cartes de réaction, bandeau de fiche) : ils grandissent avec l'écran pour garder
     le même aspect en dézoomant ou sur un grand écran (demande du porteur 26/09/2026). Repère :
     l'aspect sur un portable de 1440 px ; jamais moins que le cran fixe, 28 px au plus. Les
     petits éléments (boutons, champs, étiquettes) gardent leurs crans fixes. */
  --sp-shape-corner-large-fluid: clamp(16px, calc(100vw * 16 / 1440), 28px);    /* part de large (16) */
  --sp-shape-corner-medium-fluid: clamp(12px, calc(100vw * 12 / 1440), 28px);   /* part de medium (12) */

  /* ── ÉLÉVATION · les six niveaux ───────────────────────────────── */
  --md-sys-elevation-level0: none;
  --md-sys-elevation-level1: 0 1px 2px rgba(20, 30, 50, .10), 0 1px 3px 1px rgba(20, 30, 50, .05);
  --md-sys-elevation-level2: 0 1px 2px rgba(20, 30, 50, .10), 0 2px 6px 2px rgba(20, 30, 50, .07);
  --md-sys-elevation-level3: 0 1px 3px rgba(20, 30, 50, .10), 0 4px 8px 3px rgba(20, 30, 50, .08);
  --md-sys-elevation-level4: 0 2px 3px rgba(20, 30, 50, .10), 0 6px 10px 4px rgba(20, 30, 50, .08);
  --md-sys-elevation-level5: 0 4px 4px rgba(20, 30, 50, .10), 0 8px 12px 6px rgba(20, 30, 50, .08);

  /* ── ÉTATS · les couches de Material 3 ─────────────────────────── */
  --md-sys-state-hover-opacity: .08;
  --sp-hover-bg: color-mix(in srgb, var(--md-sys-color-on-surface) 8%, transparent);   /* fond de survol COMMUN (listes, lignes, tableaux, barre) = la couche d'état des menus, retour du porteur 29/09/2026 */
  --md-sys-state-focus-opacity: .10;
  --md-sys-state-pressed-opacity: .10;
  --md-sys-state-dragged-opacity: .16;
  --md-sys-state-disabled-opacity: .38;

  /* ── TYPOGRAPHIE · les 15 rôles, en Noto Sans ──────────────────── */
  --md-sys-typescale-display-large: 700 56px/1.05 "Noto Sans", ui-sans-serif, sans-serif;
  --md-sys-typescale-display-medium: 700 44px/1.1 "Noto Sans", ui-sans-serif, sans-serif;
  --md-sys-typescale-display-small: 700 34px/1.15 "Noto Sans", ui-sans-serif, sans-serif;
  --md-sys-typescale-headline-large: 700 30px/1.2 "Noto Sans", ui-sans-serif, sans-serif;
  --md-sys-typescale-headline-medium: 600 24px/1.22 "Noto Sans", ui-sans-serif, sans-serif;
  --md-sys-typescale-headline-small: 600 20px/1.25 "Noto Sans", ui-sans-serif, sans-serif;
  --md-sys-typescale-title-large: 600 16px/1.28 "Noto Sans", ui-sans-serif, sans-serif;
  --md-sys-typescale-title-medium: 600 15px/1.3 "Noto Sans", ui-sans-serif, sans-serif;
  --md-sys-typescale-title-small: 600 14px/1.3 "Noto Sans", ui-sans-serif, sans-serif;
  --md-sys-typescale-body-large: 400 16px/1.6 "Noto Sans", ui-sans-serif, sans-serif;
  --md-sys-typescale-body-medium: 400 14px/1.55 "Noto Sans", ui-sans-serif, sans-serif;
  --md-sys-typescale-body-small: 400 12.5px/1.5 "Noto Sans", ui-sans-serif, sans-serif;
  --md-sys-typescale-label-large: 500 14px/1.2 "Noto Sans", ui-sans-serif, sans-serif;
  --md-sys-typescale-label-medium: 500 12px/1.35 "Noto Sans", ui-sans-serif, sans-serif;
  --md-sys-typescale-label-small: 500 11px/1.35 "Noto Sans", ui-sans-serif, sans-serif;
  /* Jetons par propriété (M3 : md.sys.typescale.<rôle>.size / .weight / .line-height) :
     pour ne changer QUE la taille quand la graisse vient d'ailleurs (un <b>, un parent). */
  --md-sys-typescale-display-large-size: 56px; --md-sys-typescale-display-large-weight: 700; --md-sys-typescale-display-large-line-height: 1.05;
  --md-sys-typescale-display-medium-size: 44px; --md-sys-typescale-display-medium-weight: 700; --md-sys-typescale-display-medium-line-height: 1.1;
  --md-sys-typescale-display-small-size: 34px; --md-sys-typescale-display-small-weight: 700; --md-sys-typescale-display-small-line-height: 1.15;
  --md-sys-typescale-headline-large-size: 30px; --md-sys-typescale-headline-large-weight: 700; --md-sys-typescale-headline-large-line-height: 1.2;
  --md-sys-typescale-headline-medium-size: 24px; --md-sys-typescale-headline-medium-weight: 600; --md-sys-typescale-headline-medium-line-height: 1.22;
  --md-sys-typescale-headline-small-size: 20px; --md-sys-typescale-headline-small-weight: 600; --md-sys-typescale-headline-small-line-height: 1.25;
  --md-sys-typescale-title-large-size: 16px; --md-sys-typescale-title-large-weight: 600; --md-sys-typescale-title-large-line-height: 1.28;
  --md-sys-typescale-title-medium-size: 15px; --md-sys-typescale-title-medium-weight: 600; --md-sys-typescale-title-medium-line-height: 1.3;
  --md-sys-typescale-title-small-size: 14px; --md-sys-typescale-title-small-weight: 600; --md-sys-typescale-title-small-line-height: 1.3;
  --md-sys-typescale-body-large-size: 16px; --md-sys-typescale-body-large-weight: 400; --md-sys-typescale-body-large-line-height: 1.6;
  --md-sys-typescale-body-medium-size: 14px; --md-sys-typescale-body-medium-weight: 400; --md-sys-typescale-body-medium-line-height: 1.55;
  --md-sys-typescale-body-small-size: 12.5px; --md-sys-typescale-body-small-weight: 400; --md-sys-typescale-body-small-line-height: 1.5;
  --md-sys-typescale-label-large-size: 14px; --md-sys-typescale-label-large-weight: 500; --md-sys-typescale-label-large-line-height: 1.2;
  --md-sys-typescale-label-medium-size: 12px; --md-sys-typescale-label-medium-weight: 500; --md-sys-typescale-label-medium-line-height: 1.35;
  --md-sys-typescale-label-small-size: 11px; --md-sys-typescale-label-small-weight: 500; --md-sys-typescale-label-small-line-height: 1.35;
}

/* ── COULEUR · thème sombre (mêmes rôles, autres valeurs) ────────── */
[data-theme="dark"] .ds-app, [data-theme="dark"] .ds-solo, [data-theme="dark"]:root,
.ds-sec--dark, .tbar-dd-panel.is-dark, .tbar-search-panel.is-dark {   /* + aperçus sombres de l'atelier */
  --md-sys-color-surface: #1b1c1e;
  --md-sys-color-surface-container-lowest: #121214;
  --md-sys-color-surface-container-low: #121214;
  --md-sys-color-surface-container: #212327;   /* entre surface et surface-container-high : les boutons non choisis restent visibles sur une carte */
  --md-sys-color-surface-container-high: #25272b;
  --md-sys-color-surface-container-highest: #2f3237;
  --md-sys-color-on-surface: #fafafa;
  --md-sys-color-on-surface-strong: #c7ccd3;
  --md-sys-color-on-surface-variant: #9aa1a9;
  --md-sys-color-on-surface-faint: #8d939c;   /* audit du 13/10/2026 : #7c828b faisait 4,4:1 ; 5,5:1 sur surface, 4,8:1 sur surface-container-high */
  --md-sys-color-outline: #3a3d42;
  --md-sys-color-outline-variant: #2a2c30;
  --md-sys-color-inverse-surface: #FFFFFF;
  --md-sys-color-inverse-on-surface: #1B1C1E;
  --md-sys-color-secondary: #e4bdc2;
  --md-sys-color-on-secondary: #43292e;
  --md-sys-color-secondary-container: #5c3f44;
  --md-sys-color-on-secondary-container: #ffd9de;
  --md-sys-color-primary-container: #4A1226;
  --md-sys-color-on-primary-container: #FFD9E4;
  /* État en sombre (20/10/2026) : sauge #AFCDBB, 10:1 sur surface et 7,3:1 sur son conteneur ; avertissement
     et erreur par les jetons de la marque, comme en clair. */
  --md-sys-color-success: #AFCDBB;
  --md-sys-color-success-container: #2F3534;
  --md-sys-color-on-success-container: #AFCDBB;
  --md-sys-color-warning-container: var(--md-sys-color-surface-container-high);
  --md-sys-color-on-warning-container: var(--md-sys-color-on-surface);
  --md-sys-color-error-container: var(--md-sys-color-primary-container);
  --md-sys-color-on-error-container: var(--md-sys-color-on-primary-container);
  --sp-tl-watch: #2B3445;
  --sp-tl-pause-container: rgba(255, 54, 118, .14);  --sp-on-tl-pause-container: #FFB3CA;
  --sp-tl-point-container: rgba(255, 54, 118, .18);  --sp-on-tl-point-container: #FF8FB1;
  --sp-on-tl-before: #4ADE80;
  --sp-on-tl-after: #A78BFA;
}

/* ── TYPOGRAPHIE · les tailles d'affichage s'adaptent à la largeur ───
   Material 3 : les styles expressifs (Display) changent de taille selon
   l'écran, contrairement aux styles du produit qui restent fixes.
   Sous 760px, chaque Display descend d'un cran. */
@media (max-width: 760px) {
  .ds-app, .ds-solo, :root {
    --md-sys-typescale-display-large: 700 44px/1.1 "Noto Sans", ui-sans-serif, sans-serif;
    --md-sys-typescale-display-medium: 700 34px/1.15 "Noto Sans", ui-sans-serif, sans-serif;
    --md-sys-typescale-display-small: 700 28px/1.2 "Noto Sans", ui-sans-serif, sans-serif;
    --md-sys-typescale-display-large-size: 44px; --md-sys-typescale-display-medium-size: 34px; --md-sys-typescale-display-small-size: 28px;
  }
}
@media (max-width: 420px) {
  .ds-app, .ds-solo, :root {
    --md-sys-typescale-display-large: 700 34px/1.15 "Noto Sans", ui-sans-serif, sans-serif;
    --md-sys-typescale-display-medium: 700 28px/1.2 "Noto Sans", ui-sans-serif, sans-serif;
    --md-sys-typescale-display-large-size: 34px; --md-sys-typescale-display-medium-size: 28px;
  }
}

/* ── TYPOGRAPHIE · classes utilitaires, une par rôle ─────────────── */
.type-display-large { font: var(--md-sys-typescale-display-large); letter-spacing: -.03em; }
.type-display-medium { font: var(--md-sys-typescale-display-medium); letter-spacing: -.025em; }
.type-display-small { font: var(--md-sys-typescale-display-small); letter-spacing: -.02em; }
.type-headline-large { font: var(--md-sys-typescale-headline-large); letter-spacing: -.02em; }
.type-headline-medium { font: var(--md-sys-typescale-headline-medium); letter-spacing: -.015em; }
.type-headline-small { font: var(--md-sys-typescale-headline-small); letter-spacing: -.01em; }
.type-title-large { font: var(--md-sys-typescale-title-large); }
.type-title-medium { font: var(--md-sys-typescale-title-medium); }
.type-title-small { font: var(--md-sys-typescale-title-small); }
.type-body-large { font: var(--md-sys-typescale-body-large); }
.type-body-medium { font: var(--md-sys-typescale-body-medium); }
.type-body-small { font: var(--md-sys-typescale-body-small); }
.type-label-large { font: var(--md-sys-typescale-label-large); }
.type-label-medium { font: var(--md-sys-typescale-label-medium); }
.type-label-small { font: var(--md-sys-typescale-label-small); letter-spacing: .02em; }

/* ── UTILITAIRES GLOBAUX (refonte du Studio, 06/10/2026, À valider) ─────
   .sr-only : texte réservé aux lecteurs d'écran (pastilles, boutons à icône, légendes de
   tableau, régions live). Défini UNE fois ici ; les copies locales (.dlg-field .sr-only,
   .wiz-step .sr-only) restent jusqu'au ménage.
   .sp-spin : l'icône loader-circle qui tourne (spinner, jamais de squelette) ; figée sous
   prefers-reduced-motion, le texte à côté reste. */
.sr-only { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden;
  clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; border: 0; }
.sp-spin { animation: sp-spin .8s linear infinite; }
/* ── Petits utilitaires demandés par les pages du Studio (intégration, 07/10/2026, À valider) ──
   .txt-body / .txt-sub : une phrase de bloc sans autre rôle (body-medium, on-surface / on-surface-variant),
   sans marge ; au lieu de détourner .lrow-name ou .phead-sub.
   .ic-brand : icône à la couleur primary (épingle, repère), sur le svg ou sur son span.
   .code-inline : code en ligne (code cadeau, clé) à chasse fixe, à la taille du texte autour.
   .is-target : cible d'un lien profond ou du sommaire, contour primary 2 px qui s'efface en 2 s
   (le script retire la classe après 2 s ; contour fixe sous animations réduites, bloc de fin). */
.txt-body { margin: 0; font: var(--md-sys-typescale-body-medium); color: var(--md-sys-color-on-surface); }
.txt-sub { margin: 0; font: var(--md-sys-typescale-body-medium); color: var(--md-sys-color-on-surface-variant); }
.ic-brand { flex: none; color: var(--md-sys-color-primary); }
span.ic-brand { display: inline-flex; align-items: center; }
.code-inline { padding: 0 4px; border-radius: var(--md-sys-shape-corner-extra-small); background: var(--md-sys-color-surface-container-high);
  color: inherit; font-family: var(--sp-font-mono); font-size: inherit; letter-spacing: .02em; overflow-wrap: anywhere; }
.is-target { outline: 2px solid var(--md-sys-color-primary); outline-offset: 4px; animation: sp-target 2s ease-out forwards; }
@keyframes sp-target { 0%, 50% { outline-color: var(--md-sys-color-primary); } 100% { outline-color: transparent; } }

/* ════════════════════════════════════════════════════════════════════
   Atelier Design System — habillage auto-suffisant.
   La page APPLIQUE ses propres fondations (dogfooding) : rôles de couleur
   Material 3, police Noto Sans, rayon 12px, contours outline / outline-variant,
   élévation par surface puis par ombre. Les jetons sont en tête de ce fichier.
   ════════════════════════════════════════════════════════════════════ */

*, *::before, *::after { box-sizing: border-box; }

body.ds {
  /* L'atelier applique désormais SES PROPRES fondations (dogfooding) :
     couleurs de la palette, rayon 12px, 1px #B8C0CB, police Noto Sans. */
  --brand:  #FF3676;   /* Redpink */
  --paper:  #F9FAFD;   /* Élévation Niveau 1 · fond (Grisblue1) */
  --panel:  #FFFFFF;   /* Élévation Niveau 2 · surface (Blanc) */
  --raised: #E7EEF8;   /* Élévation Niveau 3 · mise en avant (Grisblue2) */
  --ink:    #1B1C1E;   /* Black */
  --ink-2:  #3a4149;
  --muted:  #6b7480;
  --faint:  #6e7684;
  --line:   #E7EEF8;   /* filet léger (Grisblue2) */
  --line-2: #B8C0CB;   /* bordure / séparateur standard 1px (Grisblue3) */
  --dash:   #B8C0CB;
  --chip:   #E7EEF8;   /* fond de puce (Grisblue2) */
  --dot:    #E7EEF8;
  --radius: 12px;      /* rayon par défaut du DS */
  --radius-sm: 12px;
  --wrap: 1060px;

  margin: 0;
  color: var(--md-sys-color-on-surface);
  background-color: var(--md-sys-color-surface-container-low);
  background-image: radial-gradient(var(--dot) 1px, transparent 1.4px);
  background-size: 24px 24px;
  background-position: -12px -12px;
  font-family: "Noto Sans", ui-sans-serif, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  line-height: 1.5;
}

/* ── Barre du haut ── */
.ds-top {
  position: sticky; top: 0; z-index: 20;
  background: rgba(249, 250, 253, 0.85);
  backdrop-filter: saturate(180%) blur(10px);
  border-bottom: 1px solid var(--md-sys-color-outline-variant);
}
.ds-top-in {
  max-width: var(--wrap); margin: 0 auto;
  padding: 14px 24px;
  display: flex; align-items: center; justify-content: space-between; gap: 16px;
}
.ds-brand { display: flex; align-items: center; gap: 10px; }
.ds-brand-name { font-weight: 700; font-size: var(--md-sys-typescale-title-medium-size, 15px); letter-spacing: -0.02em; }
.ds-brand-tag {
  font-size: var(--md-sys-typescale-label-small-size, 11px); font-weight: 600; letter-spacing: 0.02em;
  color: var(--md-sys-color-primary); background: rgba(255, 54, 118, .10);
  padding: 4px 9px; border-radius: var(--md-sys-shape-corner-full); border: 1px solid rgba(255, 54, 118, .22);
}
.ds-progress { display: flex; align-items: center; gap: 10px; }
.ds-progress-track {
  width: 120px; height: 5px; border-radius: var(--md-sys-shape-corner-full);
  background: var(--md-sys-color-outline); overflow: hidden;
}
.ds-progress-track > i {
  display: block; height: 100%; width: 0%;
  background: var(--md-sys-color-primary); border-radius: var(--md-sys-shape-corner-full);
  transition: width .4s ease;
}
.ds-progress-lbl {
  font-size: var(--md-sys-typescale-label-medium-size, 12px); color: var(--md-sys-color-on-surface-variant);
  font-variant-numeric: tabular-nums; white-space: nowrap;
}

/* ── Conteneur ── */
.ds-main { max-width: var(--wrap); margin: 0 auto; padding: 48px 24px 120px; }

/* ── En-tête ── */
.ds-hero { max-width: 640px; margin-bottom: 40px; }
.ds-kicker {
  margin: 0 0 14px; font-size: var(--md-sys-typescale-label-medium-size, 12px); font-weight: 600;
  text-transform: uppercase; letter-spacing: 0.12em; color: var(--md-sys-color-on-surface-faint);
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
}
.ds-hero h1 {
  margin: 0 0 16px; font-size: 40px; line-height: 1.05;
  font-weight: 700; letter-spacing: -0.03em;
}
.ds-lead { margin: 0 0 12px; font-size: var(--md-sys-typescale-body-large-size, 16px); line-height: 1.6; color: var(--md-sys-color-on-surface-strong); }
.ds-lead b { color: var(--md-sys-color-on-surface); font-weight: 650; }
.ds-hint { margin: 0; font-size: var(--md-sys-typescale-body-medium-size, 14px); color: var(--md-sys-color-on-surface-variant); }

/* ── Zone Composants (2e bande, après les fondations) ── */
.ds-band { margin-top: 56px; padding-top: 40px; border-top: 1px solid var(--md-sys-color-outline); }
.ds-band-head { margin-bottom: 4px; }
.ds-band-title-row { display: flex; align-items: baseline; justify-content: space-between; gap: 16px; flex-wrap: wrap; }
.ds-band-title { margin: 0 0 12px; font-size: var(--md-sys-typescale-headline-large-size, 30px); font-weight: 700; letter-spacing: -0.02em; }
.ds-band-lead { margin: 4px 0 0; font-size: var(--md-sys-typescale-body-large-size, 16px); color: var(--md-sys-color-on-surface-strong); max-width: 640px; line-height: 1.6; }
.ds-band-lead b { color: var(--md-sys-color-on-surface); font-weight: 650; }

/* ── BOUTON · formes SydePlay ─────────────────────────────────────────
   RÈGLE DU PORTEUR : 44 px de haut pour tout élément (boutons, champs,
   recherche…), jamais plus. Bouton : hauteur 44, marges 20, rayon 12,
   libellé 14 / 500 à interligne 1 (bien centré), icône 20, écart 8.
   De Material 3 on garde les rôles de couleur et la couche d'état : au
   survol, la couleur du texte à 8 % par-dessus le fond (10 % au focus et
   à l'appui), sans couleur écrite à la main. */
.cbtn {
  position: relative; isolation: isolate;
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  height: 44px; padding: 0 20px; border: 0; cursor: pointer;
  border-radius: var(--md-sys-shape-corner-medium);
  font: var(--md-sys-typescale-label-large); line-height: 1; letter-spacing: .01em; text-decoration: none;
}
/* Icône 18 et côté icône à 16 (comme Material 3) : les icônes Lucide ont du vide autour
   du dessin, avec 20 / 20 le « + » de « Publier » paraissait décollé du texte (retour du
   porteur 25/09/2026). */
.cbtn svg { width: 18px; height: 18px; flex: none; }
.cbtn:has(> svg:first-child) { padding-left: 16px; }
.cbtn:has(> svg:last-child):not(:has(> svg:first-child)) { padding-right: 16px; }
/* Couche d'état : la couleur du contenu, à 8 % au survol, 10 % au focus et à l'appui. */
.cbtn::after { content: ""; position: absolute; inset: 0; border-radius: inherit; background: currentColor;
  opacity: 0; pointer-events: none; transition: opacity .15s ease; }
.cbtn:hover::after { opacity: var(--md-sys-state-hover-opacity); }
.cbtn:focus-visible::after { opacity: var(--md-sys-state-focus-opacity); }
.cbtn:active::after { opacity: var(--md-sys-state-pressed-opacity); }
.cbtn:focus-visible { outline: 3px solid var(--md-sys-color-primary); outline-offset: 2px; }
.cbtn:disabled, .cbtn[aria-disabled="true"] { opacity: var(--md-sys-state-disabled-opacity); pointer-events: none; }
/* Sans ça, `display:inline-flex` l'emporte sur le [hidden] du navigateur : un bouton
   « masqué » restait visible (ex. « Afficher plus » sous une liste vide). */
.cbtn[hidden], .ibtn[hidden] { display: none; }

/* Styles de couleur (rôles Material 3). */
.cbtn--redpink       { background: var(--md-sys-color-primary); color: var(--md-sys-color-on-primary); }          /* plein rose */
.cbtn--noir          { background: var(--md-sys-color-inverse-surface); color: var(--md-sys-color-inverse-on-surface); } /* plein noir (blanc en sombre) */
.cbtn--blanc         { background: #fff; color: #1B1C1E; }                                                              /* plein blanc, sur fond sombre */
.cbtn--contour       { background: transparent; color: var(--md-sys-color-on-surface); border: 1px solid var(--md-sys-color-outline); } /* contour */
.cbtn--contour-clair { background: transparent; color: #fff; border: 1px solid rgba(255, 255, 255, .6); }             /* contour sur fond sombre */
/* Boutons d'ÉTAT (retour du porteur 29/09/2026, bloc Extension des Paramètres) : le bouton porte l'état à la
   place d'un badge. Vert « À jour » (success), orange « Mettre à jour » (warning), rose « Installer ». À décider.
   Audit du 13/10/2026 : le blanc sur vert (2,1:1) et sur orange (2,5:1) était illisible ; paires
   conteneur / texte, déclinées en sombre (vert 6,3:1, orange 6,2:1). */
.cbtn--vert          { background: var(--md-sys-color-success-container); color: var(--md-sys-color-on-success-container); }
.cbtn--orange        { background: transparent; color: var(--md-sys-color-on-surface); border: 1px solid var(--md-sys-color-primary); }   /* contour rose, icône rose (20/10/2026) */
.cbtn--orange svg    { color: var(--md-sys-color-primary); }


/* ── BOUTON ICÔNE · 44×44, icône 22, rayon 12, couche d'état ───────── */
.ibtn {
  position: relative; isolation: isolate;
  display: inline-flex; align-items: center; justify-content: center;
  width: 44px; height: 44px; border: 0; border-radius: var(--md-sys-shape-corner-medium);
  background: transparent; color: var(--md-sys-color-on-surface-variant); cursor: pointer;
}
.ibtn svg { width: 22px; height: 22px; }
.ibtn::after { content: ""; position: absolute; inset: 0; border-radius: inherit; background: currentColor;
  opacity: 0; pointer-events: none; transition: opacity .15s ease; }
.ibtn:hover::after { opacity: var(--md-sys-state-hover-opacity); }
.ibtn:focus-visible::after { opacity: var(--md-sys-state-focus-opacity); }
.ibtn:active::after { opacity: var(--md-sys-state-pressed-opacity); }
.ibtn:focus-visible { outline: 3px solid var(--md-sys-color-primary); outline-offset: 2px; }
/* Sélectionné (nav actif) : pastille pleine, qui s'inverse en sombre. */
.ibtn--active { background: var(--md-sys-color-inverse-surface); color: var(--md-sys-color-inverse-on-surface); }
/* Indisponible (refonte du Studio, À valider) : disabled, ou aria-disabled="true" quand il doit rester
   atteignable au clavier (ligne occupée, action sans objet). Opacité d'état désactivé, plus de couche
   d'état, curseur interdit ; le clic reste capté (curseur visible), le script ignore l'action. */
.ibtn:disabled, .ibtn[aria-disabled="true"] { opacity: var(--md-sys-state-disabled-opacity); cursor: not-allowed; }
.ibtn:disabled::after, .ibtn[aria-disabled="true"]::after { opacity: 0; }

/* Panneaux de démo (fond clair / fond sombre selon l'usage) */
.cbtn-panels { display: flex; gap: 16px; flex-wrap: wrap; }
.cbtn-panel {
  flex: 1; min-width: 300px; display: flex; flex-wrap: wrap; gap: 12px; align-items: center;
  padding: 20px; border-radius: var(--md-sys-shape-corner-medium); background: #F9FAFD; border: 1px solid #B8C0CB;
}
.cbtn-panel--dark { background: #1B1C1E; border-color: #34363b; }
.cbtn-panel-lbl { width: 100%; font-size: var(--md-sys-typescale-label-small-size, 11px); text-transform: uppercase; letter-spacing: .05em; color: var(--md-sys-color-on-surface-variant); }
.cbtn-panel .cbtn-panel-lbl { color: #6b7480; }
.cbtn-panel--dark .cbtn-panel-lbl { color: #9aa1a9; }
.cbtn-icons {
  margin: 16px 0 0; display: flex; gap: 12px; align-items: center; flex-wrap: wrap;
  padding: 20px; border-radius: var(--md-sys-shape-corner-medium); background: var(--md-sys-color-surface-container-low); border: 1px solid var(--md-sys-color-outline);
}
.cbtn-icons-note { font-size: var(--md-sys-typescale-label-medium-size, 12px); color: var(--md-sys-color-on-surface-faint); }

/* ── Composant Badge / tag (couleur pilotée par --f = "r,g,b" et --t = texte) ── */
.ds-group-sub { margin: 26px 0 14px; font-size: var(--md-sys-typescale-body-small-size, 12.5px); font-weight: 650; color: var(--md-sys-color-on-surface-strong); }
/* Tags : PLEINS et SANS contour (retour du porteur 25/09/2026) : fond de la couleur
   en version foncée (--s), texte et icône blancs ; contraste ≥ 4,5:1 pour chaque
   couleur. Les tags de nature (Film, Série, Animé) n'ont plus d'icône. */
.bdg { font: var(--md-sys-typescale-label-medium); line-height: 1; display: inline-flex; align-items: center; justify-content: center; gap: 4px; height: 30px; padding: 0 8px; border-radius: var(--md-sys-shape-corner-small); background: var(--s, #4B5563); border: 0; color: #fff; transition: filter .15s ease, box-shadow .15s ease;}
.bdg svg { width: 14px; height: 14px; }
.bdg--icon { width: 30px; padding: 0; }   /* icône seule : carré 30×30 */
.bdg--dark { background: rgba(0, 0, 0, .7); color: #fff; }  /* durée / overlay sombre */
.bdg--focus { box-shadow: 0 0 0 2px var(--md-sys-color-surface), 0 0 0 4px var(--s, #4B5563); }   /* sélectionné : anneau de sa couleur */
.bdg--btn { cursor: pointer; }
.bdg--btn:hover, .bdg--hover { filter: brightness(1.15); }  /* survol des tags cliquables */
/* Palette FERMÉE des badges (Figma « Badge & tag », variables color/tag/*) : une classe par
   couleur. --s = fond plein du tag ; --t (couleur vive) et --pastel restent pour les
   autres usages de la teinte (pastilles d'icône, graphiques). */
/* Les trois tags d'ÉTAT (20/10/2026, planche « Monochrome + marque », variante A) : « Vérifiée », « En ligne »
   (.bdg--green) en rose doux plein ; « À vérifier », « Modifié » (.bdg--orange) en gris du site, icône rose ;
   « À régler », « À corriger » (.bdg--red) en gris du site, texte rose vif. --t et --pastel suivent. */
.bdg--orange { --s: var(--md-sys-color-surface-container-highest); --f: 255, 54, 118; --t: var(--md-sys-color-primary); --pastel: var(--md-sys-color-primary-container); color: var(--md-sys-color-on-surface); }
.bdg--orange svg { color: var(--md-sys-color-primary); }
.bdg--blue   { --s: #1D4ED8; --f: 50, 100, 248;  --t: #3264F8; --pastel: #D6E0FE; }
.bdg--violet { --s: #6D28D9; --f: 139, 107, 244; --t: #8B6BF4; --pastel: #E8E1FD; }
.bdg--yellow { --s: #A16207; --f: 192, 174, 0;   --t: #C0AE00; --pastel: #F2EFCC; }
.bdg--green  { --s: var(--md-sys-color-primary-container); --f: 255, 54, 118; --t: var(--md-sys-color-success); --pastel: var(--md-sys-color-success-container); color: var(--md-sys-color-on-primary-container); }
.bdg--red    { --s: var(--md-sys-color-surface-container-highest); --f: 255, 54, 118; --t: var(--md-sys-color-primary); --pastel: var(--md-sys-color-primary-container); color: var(--md-sys-color-primary); }
.bdg--gray   { --s: #4B5563; --f: 93, 101, 113;  --t: #5D6571; --pastel: #F0F2F5; }
/* Nature d'œuvre (Film, Série, Animé) : palette « projection » (07/10/2026, la même que le Studio,
   .st-kind--*) : série indigo, film ambre, animé turquoise, en fonds clairs et texte foncé de la même
   teinte (9 à 11:1). Réservées à ces tags, partout où ils apparaissent (cartes, fenêtre de réaction,
   Découvrir, listes, Mes œuvres, admin), identiques en clair et en sombre. */
.bdg--film  { --s: #F7C873; --t: #F7C873; color: #2A1700; }
.bdg--serie { --s: #AEB8FF; --t: #AEB8FF; color: #0E1240; }
.bdg--anime { --s: #72E4DD; --t: #72E4DD; color: #032826; }
/* Point d'ancrage du calage (refonte du Studio, À valider) : le rose des points de la frise
   (famille --sp-tl-point), en fond plein foncé comme les autres badges (blanc à 4,8:1),
   à côté de la pause en .bdg--orange (« Ce que tu as réglé » du compositeur). */
.bdg--point { --s: var(--sp-tl-point-strong); --t: var(--sp-tl-point); --pastel: var(--sp-tl-point-container); }
/* Taille compacte (sur une image, dans une liste dense) : remplace l'ancien .tag--xs. */
.bdg--sm { font: var(--md-sys-typescale-label-small); height: 22px; padding: 0 6px; }
.bdg--sm svg { width: 12px; height: 12px; }
/* Menu « trois points » d'une carte (retour du porteur 25/09/2026) : remplace l'icône
   « enregistrer ». Bouton icône du DS (.ibtn, icône 22 comme les autres icônes) calé
   dans le coin, sans agrandir la carte ; le menu (.menu) s'ouvre en surimpression :
   « Enregistrer pour regarder plus tard », « Partager » (26/09), « Signaler ». */
.rcard-more { flex: none; margin: -11px -12px -11px 0; }
/* Survol plus discret (retours du porteur 26/09/2026 : « trop gros », puis « moins de
   radius, ça fait quasi arrondi ») : la pastille d'état et l'anneau de focus font
   32 px au centre du bouton, rayon small (8) ; la zone cliquable reste de 44 px. */
.rcard-more { border-radius: var(--md-sys-shape-corner-small); }
.rcard-more::after { inset: 6px; }
.rcard-more:focus-visible { outline-offset: -3px; }
.rcard-menu { position: fixed; z-index: 90; min-width: 280px; }
.bdg-row--onimg { background: var(--sp-grad-banner); padding: 12px; border-radius: var(--md-sys-shape-corner-small); }
.bdg-group { margin-bottom: 20px; }
.bdg-lbl { display: block; font-size: var(--md-sys-typescale-label-small-size, 11px); text-transform: uppercase; letter-spacing: .05em; color: var(--md-sys-color-on-surface-variant); margin-bottom: 10px; }
.bdg-row { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }
.bdg-note { display: block; font-size: var(--md-sys-typescale-label-medium-size, 12px); color: var(--md-sys-color-on-surface-faint); margin-top: 8px; }

/* ════════════════════════════════════════════════════════════════════
   EXEMPLES de composants (propositions, à remplacer par le vrai design).
   Construits sur les fondations : couleurs, Noto Sans, rayon 12px, etc.
   ════════════════════════════════════════════════════════════════════ */
.ds-state.is-example { border-style: dashed; border-color: var(--md-sys-color-outline); color: var(--md-sys-color-on-surface-variant); }
.ex-row { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }

/* Chips */
/* ── PUCE (filtre, plateforme) · refaite le 07/10/2026 (demande du porteur, à valider) ──
   Pilule pleine : hauteur 36, rayon plein, marges 16, icône 16, libellé 14 / 600.
   Au repos : fond tonal (surface-container-high), texte on-surface, pas de contour.
   Choisie : pastille contrastée inverse-surface (blanche en sombre, noire en clair),
   lisible d'un coup d'œil (l'ancien secondary-container « marron » était terne).
   Couche d'état au survol, léger enfoncement à l'appui, couleurs en fondu ; rien de
   tout ça si l'utilisateur demande moins d'animations. */
.chip { position: relative; isolation: isolate; display: inline-flex; align-items: center; gap: 8px;
  height: 36px; padding: 0 16px; border-radius: var(--md-sys-shape-corner-full);
  background: var(--md-sys-color-surface-container-high); border: 1px solid transparent; color: var(--md-sys-color-on-surface);
  font: var(--md-sys-typescale-label-large); font-weight: 600; line-height: 1; cursor: pointer; text-decoration: none;
  transition: background-color .18s ease, color .18s ease, transform .12s ease; }
.chip svg { width: 16px; height: 16px; flex: none; }
.chip::after { content: ""; position: absolute; inset: 0; border-radius: inherit; background: currentColor;
  opacity: 0; pointer-events: none; transition: opacity .15s ease; }
.chip:hover::after { opacity: var(--md-sys-state-hover-opacity); }
.chip:focus-visible::after { opacity: var(--md-sys-state-focus-opacity); }
.chip:active::after { opacity: var(--md-sys-state-pressed-opacity); }
.chip:active { transform: scale(.96); }
.chip:focus-visible { outline: 3px solid var(--md-sys-color-primary); outline-offset: 2px; }
.chip--on { background: var(--md-sys-color-inverse-surface); border-color: transparent; color: var(--md-sys-color-inverse-on-surface); }
@media (prefers-reduced-motion: reduce) { .chip { transition: none; } .chip:active { transform: none; } }

/* Bloc de specs d'un composant (clé/valeur, lisible et modifiable) */
/* Bouton « Spécifications » : disclosure natif (<details>) qui déplie le panneau */
.ds-specs { margin: 20px 0 0; max-width: 760px; }
.ds-specs-btn { display: inline-flex; align-items: center; gap: 8px; height: 32px; padding: 0 12px 0 14px; border-radius: var(--md-sys-shape-corner-small);
  background: var(--md-sys-color-surface); border: 1px solid var(--md-sys-color-outline); color: var(--md-sys-color-on-surface);
  font-family: "Noto Sans", ui-sans-serif, sans-serif; font-size: var(--md-sys-typescale-body-small-size, 12.5px); font-weight: 600;
  cursor: pointer; list-style: none; user-select: none; width: fit-content;
  transition: border-color .15s ease, background-color .15s ease; }
.ds-specs-btn::-webkit-details-marker { display: none; }
.ds-specs-btn:hover { border-color: var(--md-sys-color-on-surface); background: var(--md-sys-color-surface-container-low); }
.ds-specs-btn svg { color: var(--md-sys-color-on-surface-variant); }
.ds-specs-caret { transition: transform .2s ease; }
.ds-specs[open] .ds-specs-caret { transform: rotate(180deg); }
.ds-specs:not([open]) .ds-spec { display: none; }   /* masquage explicite (indépendant du moteur) */
.ds-spec { margin: 10px 0 0; max-width: 760px; display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
  gap: 1px; background: var(--md-sys-color-outline); border: 1px solid var(--md-sys-color-outline); border-radius: var(--md-sys-shape-corner-medium); overflow: hidden; }
.ds-spec > div { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; padding: 9px 14px; background: var(--md-sys-color-surface); }
.ds-spec dt { font-size: var(--md-sys-typescale-label-medium-size, 12px); color: var(--md-sys-color-on-surface-variant); }
.ds-spec dd { margin: 0; font-size: var(--md-sys-typescale-label-medium-size, 12px); font-weight: 600; color: var(--md-sys-color-on-surface); text-align: right; }

/* ── CHAMPS DE FORMULAIRE · le champ SydePlay (retour du porteur 25/09/2026) ──
   44 px de haut, marges 12, rayon 12, fond gris bleuté (surface-container-high),
   contour 1 px invisible qui devient rose (primary) quand on écrit dedans,
   texte 14. Libellé au-dessus : 12 / 600, écart 6. Zone de texte : 80 px
   minimum. Le Material 3 « filled » (56 px, trait fin) a été abandonné. */
.ex-fields { display: grid; grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); gap: 14px; }
.ex-field { display: flex; flex-direction: column; gap: 6px; }
.ex-field--full { grid-column: 1 / -1; }
.ex-lbl, .sp-auth label { font: var(--md-sys-typescale-label-medium); font-weight: 600; color: var(--md-sys-color-on-surface-strong); }
.ex-field input, .ex-field select, .ex-select > select, .ex-field textarea, .sp-auth input {
  box-sizing: border-box; width: 100%; height: 44px; padding: 0 12px;
  font: var(--md-sys-typescale-body-medium); color: var(--md-sys-color-on-surface);
  background: var(--md-sys-color-surface-container-high);
  border: 1px solid transparent; border-radius: var(--md-sys-shape-corner-medium); }
/* Texte indicatif (placeholder) : on-surface-variant faisait 4,05:1 sur le fond du champ (audit du
   13/10/2026). Un cran vers on-surface-strong : 5,5:1 en clair, 7:1 en sombre, toujours plus pâle que le texte saisi. */
.ex-field input::placeholder, .ex-field textarea::placeholder, .sp-auth input::placeholder { color: color-mix(in srgb, var(--md-sys-color-on-surface-variant) 60%, var(--md-sys-color-on-surface-strong)); opacity: 1; }
/* Remplissage automatique (Chrome, Safari) : le navigateur peint son propre rectangle bleu dans le
   champ. On le recouvre avec le fond du champ (ombre interne), même couleur de texte, mêmes coins,
   pour TOUS les champs du site (retour du porteur du 29/09/2026). */
:is(.ex-field, .sp-auth) :is(input, select, textarea):-webkit-autofill,
:is(.ex-field, .sp-auth) :is(input, select, textarea):-webkit-autofill:hover,
:is(.ex-field, .sp-auth) :is(input, select, textarea):-webkit-autofill:focus {
  -webkit-box-shadow: 0 0 0 1000px var(--md-sys-color-surface-container-high) inset;
  -webkit-text-fill-color: var(--md-sys-color-on-surface);
  caret-color: var(--md-sys-color-on-surface);
  border-radius: inherit;
  transition: background-color 9999s ease-out 0s;
}
.ex-field input:focus, .ex-field select:focus, .ex-select > select:focus, .ex-field textarea:focus, .sp-auth input:focus { outline: none; border-color: var(--md-sys-color-primary); }
.ex-field [aria-invalid="true"], .sp-auth input[aria-invalid="true"] { border-color: var(--md-sys-color-error); }
.ex-field input:disabled, .ex-field select:disabled, .ex-select > select:disabled, .ex-field textarea:disabled { opacity: var(--md-sys-state-disabled-opacity); cursor: not-allowed; }
.ex-field textarea { height: auto; min-height: 80px; padding: 10px 12px; resize: vertical; }
/* Zone de texte d'une ligne qui grandit avec le texte (titre des compositeurs, audit break-ui du 15/10/2026) :
   44 au départ comme un champ, la hauteur suit le texte (posée par le JS, rows="1"). */
.ex-field textarea.ex-grow { min-height: 44px; resize: none; }
/* Préfixe / suffixe et bouton de fin (« @ » devant un pseudo, œil du mot de passe) :
   le conteneur porte le fond, le rayon et le contour ; l'input à l'intérieur est nu.
   Le contour est une ombre intérieure : le bouton icône de 44 garde toute la hauteur. */
.ex-affix { display: flex; align-items: center; gap: 4px; box-sizing: border-box; height: 44px; padding: 0 12px;
  background: var(--md-sys-color-surface-container-high); color: var(--md-sys-color-on-surface-variant);
  border-radius: var(--md-sys-shape-corner-medium); box-shadow: inset 0 0 0 1px transparent; font: var(--md-sys-typescale-body-medium); }
.ex-affix:focus-within { box-shadow: inset 0 0 0 1px var(--md-sys-color-primary); }
.ex-affix > i { flex: none; font-style: normal; }
.ex-affix > svg { flex: none; width: 18px; height: 18px; }
.ex-affix:has(> .ibtn:last-child) { padding-right: 0; }   /* bouton icône en fin, collé au bord droit */
.ex-field .ex-affix input { flex: 1; min-width: 0; height: 100%; padding: 0; background: transparent; border: 0; border-radius: 0; }
.ex-select { position: relative; display: block; }
.ex-select select { display: block; width: 100%; }   /* bloc : pas d'espace de ligne sous la liste (reste à 44) */
/* Peau du champ aussi pour un .ex-select hors .ex-field (et là où select-menu.js n'agit pas : /watch,
   tactile) : sinon le select natif reste brut. */
.ex-field select, .ex-select > select { appearance: none; -webkit-appearance: none; padding-right: 38px; cursor: pointer; }
/* Champ de carte (Stripe) : le champ sécurisé de Stripe (une iframe) posé dans la peau des
   champs du DS : 44 px, fond surface-container-high, rayon 12, contour primary au focus.
   Stripe ajoute ses classes d'état (.StripeElement--focus, --invalid) sur ce conteneur. */
.ex-stripe { box-sizing: border-box; height: 44px; padding: 13px 12px 0; background: var(--md-sys-color-surface-container-high);
  border: 1px solid transparent; border-radius: var(--md-sys-shape-corner-medium); }
.ex-stripe.StripeElement--focus { border-color: var(--md-sys-color-primary); }
.ex-stripe.StripeElement--invalid { border-color: var(--md-sys-color-error); }
.ex-select > svg { position: absolute; right: 12px; top: 50%; transform: translateY(-50%); width: 18px; height: 18px; color: var(--md-sys-color-on-surface-variant); pointer-events: none; }
/* Liste déroulante du DS (shared/select-menu.js) : le <select> reste sous un bouton qui porte le choix
   courant ; la liste s'ouvre dans un menu du DS (survol gris, coche rose). Retour du porteur 29/09/2026 :
   plus de liste native bleue. Sur écran tactile, la liste native reste. */
.ex-select--menu select { position: absolute; inset: 0; width: 100%; opacity: 0; pointer-events: none; }
.ex-select-btn { display: block; width: 100%; box-sizing: border-box; height: 44px; padding: 0 38px 0 12px; border: 1px solid transparent;
  border-radius: var(--md-sys-shape-corner-medium); background: var(--md-sys-color-surface-container-high); color: var(--md-sys-color-on-surface);
  font: var(--md-sys-typescale-body-medium); text-align: left; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; cursor: pointer; }
.ex-select-btn:focus-visible, .ex-select-btn[aria-expanded="true"] { outline: none; border-color: var(--md-sys-color-primary); }
.ex-select-btn:disabled { opacity: var(--md-sys-state-disabled-opacity); cursor: not-allowed; }
.ex-select-menu { position: absolute; left: 0; right: 0; top: calc(100% + 8px); z-index: 70; max-height: 320px; overflow-y: auto; }
.ex-select-menu [role="menuitemradio"] > span { overflow: hidden; text-overflow: ellipsis; }
/* Sélecteur à menu (.ex-selbtn) : un bouton à la peau du champ (fond gris bleuté, 44 px,
   marges 12, rayon 12) qui ouvre un menu du DS au lieu de la liste du navigateur.
   Libellé label-large on-surface, icône de fin 18 on-surface-variant, couche d'état au
   survol ; contour primary quand son menu est ouvert ou au clavier, comme un champ où
   l'on écrit. Version carrée à icône seule (.ex-selbtn--icon, 44 × 44, icône 22) quand
   la place manque. Né pour la barre de liste (Filtre, Trier par), à côté de la recherche :
   les trois de la même famille (référence « Funnels » du porteur, 27/09/2026). */
.ex-selbtn { position: relative; isolation: isolate; display: inline-flex; align-items: center; gap: 8px; box-sizing: border-box;
  height: 44px; padding: 0 12px; border: 1px solid transparent; border-radius: var(--md-sys-shape-corner-medium);
  background: var(--md-sys-color-surface-container-high); color: var(--md-sys-color-on-surface);
  font: var(--md-sys-typescale-label-large); line-height: 1; white-space: nowrap; cursor: pointer; }
.ex-selbtn svg { flex: none; width: 18px; height: 18px; color: var(--md-sys-color-on-surface-variant); }
.ex-selbtn::after { content: ""; position: absolute; inset: 0; border-radius: inherit; background: currentColor;
  opacity: 0; pointer-events: none; transition: opacity .15s ease; }
.ex-selbtn:hover::after { opacity: var(--md-sys-state-hover-opacity); }
.ex-selbtn:active::after { opacity: var(--md-sys-state-pressed-opacity); }
.ex-selbtn:focus-visible, .ex-selbtn[aria-expanded="true"] { outline: none; border-color: var(--md-sys-color-primary); }
.ex-selbtn--icon { width: 44px; padding: 0; justify-content: center; }
.ex-selbtn--icon svg { width: 22px; height: 22px; }

/* ── BARRE DE RECHERCHE (.ex-search) : LA recherche, partout (décision du porteur
   du 27/09/2026 : une seule barre dans tout le produit). Même peau que les
   champs : 44 px, marges 12, rayon 12, fond gris bleuté, loupe 18 en tête,
   écart 8, contour rose quand on écrit. La barre du haut la réutilise telle
   quelle (.tbar-search n'ajoute que le placement, section Barre du haut). */
.ex-search { box-sizing: border-box; display: inline-flex; align-items: center; gap: 8px; height: 44px; padding: 0 12px;
  border: 1px solid transparent; border-radius: var(--md-sys-shape-corner-medium); background: var(--md-sys-color-surface-container-high);
  color: var(--md-sys-color-on-surface-variant); }
.ex-search > span { display: inline-flex; flex: none; }
.ex-search svg { width: 18px; height: 18px; flex: none; }
.ex-search input { flex: 1; min-width: 0; height: 100%; padding: 0; border: 0; outline: none; background: transparent;
  -webkit-appearance: none; appearance: none; font: var(--md-sys-typescale-label-large); color: var(--md-sys-color-on-surface); }
.ex-search input::placeholder { color: color-mix(in srgb, var(--md-sys-color-on-surface-variant) 60%, var(--md-sys-color-on-surface-strong)); opacity: 1; }
.ex-search:focus-within { border-color: var(--md-sys-color-primary); }
/* Focus des champs (audit d'accessibilité du 13/10/2026) : le seul filet rose de 1 px (3:1 sur
   le fond du champ) se perdait au clavier, alors que boutons, puces et interrupteurs ont un
   anneau de 3 px. On ajoute un anneau rose de 2 px AUTOUR du champ (3,5:1 sur la page) : une
   ombre plutôt qu'une bordure plus épaisse, le texte ne bouge pas et [aria-invalid] garde la
   bordure. Le champ nu d'un .ex-affix n'en porte pas : c'est son conteneur qui l'a. */
.ex-field input:focus, .ex-field select:focus, .ex-select > select:focus, .ex-field textarea:focus, .sp-auth input:focus,
.ex-select-btn:focus-visible, .ex-selbtn:focus-visible, .ex-search:focus-within, .wiz-row-note:focus,
.ex-stripe.StripeElement--focus, .tf:has(.tf-in:focus-visible) { box-shadow: 0 0 0 2px var(--md-sys-color-primary); }
.ex-field .ex-affix input:focus { box-shadow: none; }
.ex-affix:focus-within { box-shadow: inset 0 0 0 1px var(--md-sys-color-primary), 0 0 0 2px var(--md-sys-color-primary); }
:is(.ex-field, .sp-auth) :is(input, select, textarea):-webkit-autofill:focus {
  -webkit-box-shadow: 0 0 0 1000px var(--md-sys-color-surface-container-high) inset, 0 0 0 2px var(--md-sys-color-primary); }
/* Champ de recherche désactivé (ex. quota de recommandations épuisé) : il doit en avoir l'air. */
.ex-search:has(input:disabled) { opacity: var(--md-sys-state-disabled-opacity, .38); cursor: not-allowed; }
.ex-search:has(input:disabled) input { cursor: not-allowed; }

/* ── SÉLECTEUR À CHOIX EXCLUSIF (.ex-seg) : thème, période, état de la FAQ ──
   CONNECTED BUTTON GROUP Material 3 Expressive (version refaite, retenue par
   le porteur le 25/09/2026) : boutons séparés de 40 de haut, écart 2, coins 8,
   fond surface-container et texte on-surface-variant ; le bouton choisi prend
   la forme pleine (pilule) en primary / on-primary. Couche d'état au survol. */
/* Refait le 07/10/2026 (demande du porteur, à valider) : MÊME habit que les puces .chip, partout
   (période, aperçu, « Vu par », FAQ…) : pilules séparées de 36, fond tonal, texte on-surface ;
   le bouton choisi prend la pastille contrastée inverse-surface (plus de rose plein). */
/* Des liens peuvent remplacer les boutons (14/10/2026) : vues d'une même rubrique sur deux pages
   (Réactions : « Par œuvre » / « En liste »). L'élément choisi porte aria-current="page". */
.ex-seg { display: inline-flex; flex-wrap: wrap; gap: 8px; }
.ex-seg a { text-decoration: none; }
.ex-seg :is(button, a) { position: relative; isolation: isolate; display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  min-width: 48px; height: 36px; padding: 0 16px; border: 0; cursor: pointer; white-space: nowrap;
  border-radius: var(--md-sys-shape-corner-full); background: var(--md-sys-color-surface-container-high); color: var(--md-sys-color-on-surface);
  font: var(--md-sys-typescale-label-large); font-weight: 600; transition: background-color .18s ease, color .18s ease, transform .12s ease; }
.ex-seg :is(button, a):active { transform: scale(.96); }
@media (prefers-reduced-motion: reduce) { .ex-seg :is(button, a) { transition: none; } .ex-seg :is(button, a):active { transform: none; } }
.ex-seg :is(button, a)::after { content: ""; position: absolute; inset: 0; border-radius: inherit; background: currentColor; opacity: 0; pointer-events: none; transition: opacity .15s ease; }
.ex-seg :is(button, a):hover::after { opacity: var(--md-sys-state-hover-opacity); }
.ex-seg :is(button, a):focus-visible { outline: 3px solid var(--md-sys-color-primary); outline-offset: 2px; }
.ex-seg :is(button, a):focus-visible::after { opacity: var(--md-sys-state-focus-opacity); }
.ex-seg :is(button, a):active::after { opacity: var(--md-sys-state-pressed-opacity); }
.ex-seg button.on, .ex-seg button[aria-pressed="true"], .ex-seg button[aria-checked="true"], .ex-seg a[aria-current="page"] { background: var(--md-sys-color-inverse-surface); color: var(--md-sys-color-inverse-on-surface); }
.ex-seg button em { font-style: normal; }
/* ── THEME SWITCH (pastille de thème) ─ version C choisie par le porteur le 29/09/2026 ──
   Une seule pastille surface-container-high, rayon plein, marge 3 ; trois boutons icône de 34
   (Système, Clair, Sombre). Le choix est posé sur une pastille claire en relief (élévation 1),
   sans rose. Le nom de chaque choix : infobulle et nom accessible. */
.thm-pill { display: inline-flex; gap: 2px; padding: 3px; border-radius: var(--md-sys-shape-corner-full); background: var(--md-sys-color-surface-container-high); }
.thm-pill button { position: relative; isolation: isolate; display: inline-flex; align-items: center; justify-content: center; width: 34px; height: 34px; padding: 0; border: 0;
  border-radius: var(--md-sys-shape-corner-full); background: transparent; color: var(--md-sys-color-on-surface-variant); cursor: pointer; transition: background-color .15s ease, color .15s ease, box-shadow .15s ease; }
.thm-pill button svg { width: 18px; height: 18px; flex: none; }
.thm-pill button::after { content: ""; position: absolute; inset: 0; border-radius: inherit; background: currentColor; opacity: 0; pointer-events: none; transition: opacity .15s ease; }
.thm-pill button:hover::after { opacity: var(--md-sys-state-hover-opacity); }
.thm-pill button:focus-visible { outline: 3px solid var(--md-sys-color-primary); outline-offset: 1px; }
.thm-pill button.on { background: var(--md-sys-color-surface-container-lowest); color: var(--md-sys-color-on-surface); box-shadow: var(--md-sys-elevation-level1); }
[data-theme="dark"] .thm-pill button.on { background: color-mix(in srgb, var(--md-sys-color-on-surface) 12%, var(--md-sys-color-surface-container-high)); }

/* ── CASES & INTERRUPTEURS ──
   Case : 20×20, rayon 4, contour 1,5 px outline, cochée = rose (primary) avec
   la coche Lucide blanche. Interrupteur SWITCH Material 3 (version refaite,
   retenue par le porteur le 25/09/2026) : piste 52×32 (forme pleine, contour
   2 px outline, fond surface-container-highest), poignée 16 outline ; activé
   = piste primary, poignée 24 on-primary ; pressé = poignée 28 ; halo rond de
   40 au survol. L'input natif reste dans la page (invisible) : le clavier et
   les lecteurs d'écran l'atteignent. Libellé 14, écart 8 (12 pour l'interrupteur). */
.ex-check, .ex-toggle { position: relative; display: inline-flex; align-items: center; gap: 8px;
  font: var(--md-sys-typescale-body-medium); color: var(--md-sys-color-on-surface); cursor: pointer; }
.ex-check input { width: 18px; height: 18px; accent-color: var(--md-sys-color-primary); }
/* Case à cocher dessinée (coche = icône Lucide). Elle s'aligne sur la première
   ligne du libellé, même quand il en fait plusieurs (consentements). */
.ex-check--box { align-items: flex-start; }
.ex-check--box .ex-box { margin-top: 1px; }
.ex-check--box input { position: absolute; left: 0; top: 1px; width: 20px; height: 20px; margin: 0; opacity: 0; cursor: pointer; }
.ex-box { display: inline-flex; align-items: center; justify-content: center; flex: none; box-sizing: border-box; width: 20px; height: 20px;
  border-radius: var(--md-sys-shape-corner-extra-small); border: 1.5px solid var(--md-sys-color-outline);
  background: var(--md-sys-color-surface); color: var(--md-sys-color-on-primary); transition: background-color .15s ease, border-color .15s ease; }
.ex-check--box:hover .ex-box { border-color: var(--md-sys-color-on-surface-variant); }
.ex-box svg { width: 14px; height: 14px; opacity: 0; transition: opacity .1s ease; }
.ex-check--box input:checked + .ex-box { background: var(--md-sys-color-primary); border-color: var(--md-sys-color-primary); }
.ex-check--box input:checked + .ex-box svg { opacity: 1; }
.ex-check--box input:focus-visible + .ex-box { outline: 3px solid var(--md-sys-color-primary); outline-offset: 2px; }
.ex-check--box input:disabled + .ex-box { opacity: var(--md-sys-state-disabled-opacity); }

/* Interrupteur (switch Material 3) */
.ex-toggle { gap: 12px; }
.ex-toggle input { position: absolute; width: 1px; height: 1px; margin: 0; opacity: 0; pointer-events: none; }
.ex-toggle-tr { position: relative; flex: none; box-sizing: border-box; width: 52px; height: 32px; border-radius: var(--md-sys-shape-corner-full);
  background: var(--md-sys-color-surface-container-highest); border: 2px solid var(--md-sys-color-outline);
  transition: background-color .15s ease, border-color .15s ease; }
.ex-toggle-tr::after { content: ""; position: absolute; left: 6px; top: 6px; width: 16px; height: 16px; border-radius: 50%;
  background: var(--md-sys-color-outline); transition: left .15s ease, top .15s ease, width .15s ease, height .15s ease, background-color .15s ease; }
.ex-toggle-tr::before { content: ""; position: absolute; left: -6px; top: -6px; width: 40px; height: 40px; border-radius: 50%;
  background: var(--md-sys-color-on-surface); opacity: 0; pointer-events: none; transition: opacity .15s ease, left .15s ease; }
.ex-toggle:hover .ex-toggle-tr::before { opacity: var(--md-sys-state-hover-opacity); }
.ex-toggle:hover .ex-toggle-tr::after { background: var(--md-sys-color-on-surface-variant); }
.ex-toggle:active .ex-toggle-tr::after { left: 0; top: 0; width: 28px; height: 28px; }
.ex-toggle input:checked + .ex-toggle-tr { background: var(--md-sys-color-primary); border-color: var(--md-sys-color-primary); }
.ex-toggle input:checked + .ex-toggle-tr::after { left: 22px; top: 2px; width: 24px; height: 24px; background: var(--md-sys-color-on-primary); }
.ex-toggle input:checked + .ex-toggle-tr::before { left: 14px; background: var(--md-sys-color-primary); }
.ex-toggle:hover input:checked + .ex-toggle-tr::after { background: var(--md-sys-color-primary-container); }
.ex-toggle:active input:checked + .ex-toggle-tr::after { left: 20px; top: 0; width: 28px; height: 28px; }
.ex-toggle input:focus-visible + .ex-toggle-tr { outline: 3px solid var(--md-sys-color-primary); outline-offset: 2px; }
.ex-toggle input:disabled + .ex-toggle-tr { opacity: var(--md-sys-state-disabled-opacity); }
/* Interrupteur qui attend sa requête (aria-disabled : reste atteignable au clavier) : estompé comme
   :disabled, sans halo de survol, curseur interdit (refonte du Studio, À valider). */
.ex-toggle input[aria-disabled="true"] + .ex-toggle-tr { opacity: var(--md-sys-state-disabled-opacity); }
.ex-toggle:has(input:disabled, input[aria-disabled="true"]) { cursor: not-allowed; }
.ex-toggle:has(input:disabled, input[aria-disabled="true"]) .ex-toggle-tr::before { opacity: 0; }

/* ── SÉLECTEUR VISUEL (.pick) : nouveau le 28/09/2026, validé par le porteur le même jour ──
   Créé pour l'éditeur d'avatar de l'inscription (retour du porteur du 23/09/2026) :
   un choix exclusif qui se VOIT au lieu de se lire (une forme, une couleur, un fond).
   Rangée qui passe à la ligne (.pick-row, écart 8). Tuile de 40, rayon 8, fond
   surface-container, dessin 26 on-surface-variant. Pastille de 36 remplie par --pick :
   ronde pour une couleur (.pick--dot), carrée rayon 8 pour un fond (.pick--fill).
   Choisie (role="radio", aria-checked) : anneau primary 2 px, à 2 px du bord.
   Sous la règle des 44 px. Couche d'état au survol et à l'appui, comme la puce. */
.pick-row { display: flex; flex-wrap: wrap; gap: 8px; }
.pick { position: relative; isolation: isolate; flex: none; display: grid; place-items: center; width: 40px; height: 40px; padding: 0;
  border: 0; border-radius: var(--md-sys-shape-corner-small); background: var(--md-sys-color-surface-container);
  color: var(--md-sys-color-on-surface-variant); cursor: pointer; }
.pick svg { display: block; width: 26px; height: 26px; }
.pick::after { content: ""; position: absolute; inset: 0; border-radius: inherit; background: currentColor;
  opacity: 0; pointer-events: none; transition: opacity .15s ease; }
.pick:hover::after { opacity: var(--md-sys-state-hover-opacity); }
.pick:active::after { opacity: var(--md-sys-state-pressed-opacity); }
.pick[aria-checked="true"] { outline: 2px solid var(--md-sys-color-primary); outline-offset: 2px; color: var(--md-sys-color-primary); }
.pick:focus-visible { outline: 3px solid var(--md-sys-color-primary); outline-offset: 2px; }
.pick--dot, .pick--fill { width: 36px; height: 36px; background: var(--pick); box-shadow: inset 0 0 0 1px var(--md-sys-color-outline-variant); }
.pick--dot { border-radius: var(--md-sys-shape-corner-full); }
/* Carte de choix (.choice) : un choix exclusif illustré (icône, nom, description), radio caché.
   Nouveau le 29/09/2026 pour « Que veux-tu publier ? » (Studio › Publier). À décider. */
.choice-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: 10px; }
.choice { position: relative; display: block; cursor: pointer; }
.choice input { position: absolute; opacity: 0; width: 0; height: 0; }
.choice-card { display: flex; flex-direction: column; align-items: flex-start; gap: 6px; box-sizing: border-box;
  padding: 12px; border: 1px solid var(--md-sys-color-outline-variant); border-radius: var(--md-sys-shape-corner-medium);
  background: var(--md-sys-color-surface); color: var(--md-sys-color-on-surface-variant); transition: border-color .15s, color .15s, background .15s; }
.choice:hover .choice-card { border-color: var(--md-sys-color-primary); }
/* Carte cochée : contour rose de 2 px (le filet de 1 px + une ombre intérieure de 1 px, le contenu
   ne bouge pas). Audit du 13/10/2026 : au survol le contour devient déjà rose en 1 px, la carte
   choisie ne s'en distinguait que par une teinte de fond à 8 %, peu visible pour un daltonien. */
.choice input:checked + .choice-card { border-color: var(--md-sys-color-primary); color: var(--md-sys-color-on-surface);
  background: color-mix(in srgb, var(--md-sys-color-primary) 8%, transparent); box-shadow: inset 0 0 0 1px var(--md-sys-color-primary); }
.choice input:checked + .choice-card svg { color: var(--md-sys-color-primary); }
.choice input:focus-visible + .choice-card { outline: 3px solid var(--md-sys-color-primary); outline-offset: 2px; }
.choice-name { font: var(--md-sys-typescale-label-large); font-weight: 700; line-height: 1.2; color: var(--md-sys-color-on-surface); }
.choice-desc { font: var(--md-sys-typescale-body-small); font-weight: 500; line-height: 1.3; }

/* ── TIER CARD (carte de palier, page des tarifs) ─ refaite sur retour du porteur 29/09/2026 ──
   Toutes les cartes portent le MÊME habit (fini le noir, le rose et le blanc selon le rang).
   « Recommandé » est choisi par le créateur : contour on-surface et bandeau AU-DESSUS de la
   carte, collé à elle ; le contenu de toutes les cartes démarre donc à la même hauteur.
   Rayon 20 partout : le bandeau porte les coins du haut, la carte ceux du bas.
   Rangées alignées d'une carte à l'autre (sous-grille) : en-tête, prix, accroche, liste, bouton. */
.tp-grid { display: grid; grid-auto-flow: column; grid-auto-columns: minmax(280px, 360px); grid-template-rows: auto auto auto 1fr auto;
  justify-content: center; column-gap: 14px; row-gap: 14px; padding-top: 30px; }
.tp-card { position: relative; min-width: 0; display: grid; grid-row: 1 / -1; grid-template-rows: subgrid; padding: 28px; box-sizing: border-box;
  border-radius: 20px; border: 1px solid var(--md-sys-color-outline); background: var(--md-sys-color-surface); color: var(--md-sys-color-on-surface); }
.tp-card--reco { border-color: var(--md-sys-color-on-surface); box-shadow: 0 0 0 1px var(--md-sys-color-on-surface); border-top-left-radius: 0; border-top-right-radius: 0; }
.tp-reco { position: absolute; left: -2px; right: -2px; bottom: calc(100% + 1px); height: 30px; display: flex; align-items: center; justify-content: center;
  border-radius: 20px 20px 0 0; background: var(--md-sys-color-on-surface); color: var(--md-sys-color-surface);
  font: var(--md-sys-typescale-label-small); font-weight: 700; letter-spacing: .04em; text-transform: uppercase; }
/* Arrivée depuis un contenu verrouillé : le palier qui le débloque, en rose. */
.tp-card--hl { border-color: var(--md-sys-color-primary); box-shadow: 0 0 0 1px var(--md-sys-color-primary); }
.tp-card--hl .tp-reco { background: var(--md-sys-color-primary); color: var(--md-sys-color-on-primary); }
.tp-h { display: flex; align-items: center; gap: 14px; min-width: 0; }
.tp-ic { flex: none; width: 56px; height: 56px; border-radius: 16px; display: grid; place-items: center; overflow: hidden;
  background: color-mix(in srgb, var(--md-sys-color-primary) 12%, transparent); color: var(--md-sys-color-primary); }
.tp-ic img { width: 100%; height: 100%; object-fit: cover; display: block; }   /* image choisie par le créateur (Studio › Paliers) */
.tp-name { min-width: 0; font: var(--md-sys-typescale-headline-small); font-weight: 700; line-height: 1.2; overflow-wrap: anywhere; }
.tp-price { display: flex; align-items: baseline; gap: 6px; flex-wrap: wrap; align-self: start; }
.tp-amount { font: var(--md-sys-typescale-display-medium); font-weight: 700; line-height: 1.1; letter-spacing: -0.03em; }
.tp-per { font: var(--md-sys-typescale-body-medium); color: var(--md-sys-color-on-surface-variant); }
.tp-approx { width: 100%; font: var(--md-sys-typescale-body-small); color: var(--md-sys-color-on-surface-variant); }
.tp-approx:empty { display: none; }
.tp-tag { margin: 0; align-self: start; font: var(--md-sys-typescale-body-medium); line-height: 1.5; color: var(--md-sys-color-on-surface-strong); }
.tp-list { list-style: none; margin: 0; padding: 16px 0 0; border-top: 1px solid var(--md-sys-color-outline-variant); display: flex; flex-direction: column; gap: 12px; align-self: start; }
.tp-list li { display: flex; align-items: flex-start; gap: 10px; font: var(--md-sys-typescale-body-medium); line-height: 1.4; }
.tp-list li svg { flex: none; width: 20px; height: 20px; color: var(--md-sys-color-primary); }
.tp-inherit { color: var(--md-sys-color-on-surface-variant); font-style: italic; }
.tp-inherit svg { color: var(--md-sys-color-on-surface-variant) !important; }
.tp-perk svg { color: var(--md-sys-color-primary); }   /* avantage écrit par le créateur : le cadeau le distingue */
.tp-cta { width: 100%; justify-content: center; align-self: end; }


/* Rangée de liste (.lrow) : sa section de documentation a été retirée de l'atelier le
   22/09/2026, mais six pages s'en servent encore (réglages, abonnements, abonnés,
   notifications, publications, admin). Sa mise en page de base reste donc ici,
   sinon leurs lignes s'empilent au lieu de s'aligner. */
.lrow-list { display: flex; flex-direction: column; gap: 4px; }
.lrow { display: flex; align-items: center; gap: 12px; padding: 8px 10px; border-radius: var(--md-sys-shape-corner-small); }
.lrow:hover { background: var(--sp-hover-bg); }
/* LIGNE SIGNALÉE (30/09/2026, à valider) : la ligne qui attend une décision (commentaire signalé dans
   Studio › Commentaires). Teinte primary 4 % sur la surface et liseré primary de 3 à gauche. */
.row-flag { background: color-mix(in srgb, var(--md-sys-color-primary) 4%, var(--md-sys-color-surface)); box-shadow: inset 3px 0 0 var(--md-sys-color-primary); }
/* ── MATRICE DES PALIERS (30/09/2026, à valider) ──────────────────────────────────────
   Studio › Abonnements, « Ce que chaque palier ouvre » : une ligne par service, une colonne par
   palier (et « Personne »). Cliquer une case ouvre le service À PARTIR de ce palier : la case
   choisie est pleine (primary), les paliers au-dessus s'allument (primary 26 %). La colonne des
   noms est fixe (--svc-w) et la largeur minimale est la même pour toutes les lignes : les cases
   tombent toujours en face de leur titre, et le tableau défile plutôt que de s'écraser. */
.tier-matrix { --svc-w: 190px; border: 1px solid var(--md-sys-color-outline-variant); border-radius: var(--md-sys-shape-corner-medium); overflow-x: auto; }
.tier-mx-head, .tier-mx-row { display: grid; grid-template-columns: var(--svc-w) repeat(var(--cols, 5), minmax(58px, 1fr));
  align-items: center; gap: 6px; padding: 8px 12px; min-width: calc(var(--svc-w) + var(--cols, 5) * 74px); }
.tier-mx-grp, .tier-mx-note { min-width: calc(var(--svc-w) + var(--cols, 5) * 74px); }
.tier-mx-head { font: var(--md-sys-typescale-label-small); font-weight: 700; color: var(--md-sys-color-on-surface-variant);
  background: var(--md-sys-color-surface-container); border-bottom: 1px solid var(--md-sys-color-outline); }
.tier-mx-col { text-align: center; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; padding: 0 2px; }
.tier-mx-row + .tier-mx-row { border-top: 1px solid var(--md-sys-color-outline); }
.tier-mx-svc { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; font: var(--md-sys-typescale-body-small); color: var(--md-sys-color-on-surface); }
.tier-mx-c { height: 26px; border-radius: var(--md-sys-shape-corner-small); border: 1px solid var(--md-sys-color-outline);
  background: transparent; cursor: pointer; transition: background .12s, border-color .12s; }
.tier-mx-c:hover { border-color: var(--md-sys-color-primary); }
.tier-mx-c:focus-visible { outline: 3px solid var(--md-sys-color-primary); outline-offset: 2px; }
.tier-mx-c.is-on { background: color-mix(in srgb, var(--md-sys-color-primary) 26%, transparent); border-color: transparent; }
.tier-mx-c.is-start { background: var(--md-sys-color-primary); }
.tier-mx-c--no.is-on { background: var(--md-sys-color-on-surface-variant); }
.tier-mx-row.is-off { opacity: .55; }   /* service éteint sur le mur : réglable, sans effet */
.tier-mx-grp { display: flex; align-items: center; gap: 8px; padding: 10px 12px 6px; font: var(--md-sys-typescale-label-small); font-weight: 700;
  letter-spacing: .4px; text-transform: uppercase; color: var(--md-sys-color-on-surface-variant);
  border-top: 1px solid var(--md-sys-color-outline); background: color-mix(in srgb, var(--md-sys-color-surface-container) 55%, transparent); }
.tier-mx-grp:first-of-type { border-top: 0; }
.tier-mx-note { margin: 0; padding: 8px 12px 12px; font: var(--md-sys-typescale-label-medium); line-height: 1.5; color: var(--md-sys-color-on-surface-variant); }
@media (max-width: 720px) {
  .tier-mx-head, .tier-mx-row { grid-template-columns: 1fr; gap: 4px; }
  .tier-mx-head { display: none; }
  .tier-mx-row { padding: 12px; }
  .tier-mx-row .tier-mx-c { height: 30px; }
}
.lrow-txt { flex: 1; min-width: 0; }
.lrow-name { font: var(--md-sys-typescale-title-small); color: var(--md-sys-color-on-surface); }
.lrow-sub { font: var(--md-sys-typescale-body-small); color: var(--md-sys-color-on-surface-variant); }

/* Avatars. flex: none : à côté d'un nom long, l'avatar ne se tasse plus (retour terrain, page de lecture à 320 px). */
.ava { display: inline-flex; flex: none; align-items: center; justify-content: center; width: 44px; height: 44px; border-radius: var(--md-sys-shape-corner-medium);
  background: var(--md-sys-color-primary); color: var(--md-sys-color-on-primary); font-family: "Noto Sans", sans-serif; font-size: 15px; font-weight: 600; position: relative; }
.ava svg { width: 18px; height: 18px; }
.ava--sm { width: 30px; height: 30px; border-radius: var(--md-sys-shape-corner-small); font-size: 12px; }
.ava--lg { width: 60px; height: 60px; border-radius: var(--md-sys-shape-corner-medium); font-size: 20px; }
.ava--on i { position: absolute; right: 0; bottom: 0; width: 11px; height: 11px; border-radius: var(--md-sys-shape-corner-extra-small); background: var(--md-sys-color-primary); }   /* présence : le rose de la marque (20/10/2026) */
.ava--add { background: transparent; border: 1.5px dashed var(--md-sys-color-outline); color: var(--md-sys-color-on-surface-variant); }
.ava img { width: 100%; height: 100%; object-fit: cover; border-radius: inherit; display: block; }
/* Avec une photo, plus de fond rose : il débordait en fin liseré autour de l'image
   (retour du porteur 29/09/2026, « vieux contour rose » sur la page de la chaîne). */
.ava:has(> img) { background: transparent; }

/* Icônes de plateformes : tuiles carrées de logos de marque (30×30, rayon 7px) */
.ex-platforms { display: flex; flex-wrap: wrap; gap: 12px 22px; }
.plat { font: var(--md-sys-typescale-body-medium); display: inline-flex; align-items: center; gap: 8px; color: var(--md-sys-color-on-surface); }
.plat img { width: 30px; height: 30px; border-radius: var(--md-sys-shape-corner-small); display: block; flex: none; object-fit: cover; }
/* Icônes de SOURCE (YouTube/Vimeo/Drive/Dailymotion) : fond blanc (certaines ont
   l'intérieur en découpe transparente, ex. le « V » de Vimeo). Pas sur les plateformes
   streaming (dont certaines sont des logos sur transparent qui doivent le rester). */
.plat--src img { background: #fff; }

/* Boutons lien : lien texte + flèche (Figma « Link bouton ») */
.ex-links { display: flex; flex-wrap: wrap; gap: 16px 28px; align-items: center; }
.lnk { font: var(--md-sys-typescale-label-large); display: inline-flex; align-items: center; gap: 6px; text-decoration: none; cursor: pointer;
  padding: 0; border: 0; background: none; position: relative; }   /* aussi en <button> */
/* Zone de clic d'au moins 24 px de haut (audit du 13/10/2026 : « S'inscrire » faisait 15 px).
   Une bande invisible centrée sur le lien, hors du flux : rien ne bouge autour, et les liens
   déjà rehaussés à 44 px par leur page gardent leur hauteur. */
.lnk::before { content: ""; position: absolute; left: 0; right: 0; top: 50%; height: 24px; margin-top: -12px; }
.lnk svg { width: 16px; height: 16px; transition: transform .15s ease; }
.lnk:hover span { text-decoration: underline; text-underline-offset: 3px; }
.lnk:hover svg { transform: translateX(2px); }
/* Lien « Retour » : la même flèche, en tête (arrow-left), qui recule au survol. */
.lnk:hover svg:first-child:not(:last-child) { transform: translateX(-2px); }
.lnk:focus-visible { outline: 3px solid var(--md-sys-color-primary); outline-offset: 2px; border-radius: var(--md-sys-shape-corner-extra-small); }
.lnk--brand { color: var(--md-sys-color-primary); }
.lnk--ink { color: var(--md-sys-color-on-surface); }
.lnk--light { color: #fff; }
.lnk-dark { display: inline-flex; padding: 8px 12px; border-radius: var(--md-sys-shape-corner-small); background: #1B1C1E; }

/* Barre du haut partagée app / admin / marketing (Figma) — responsive testable */
.ds-nav { max-width: 900px; }
.ds-nav-hint { display: flex; align-items: center; gap: 6px; margin: 0 0 10px; font-size: var(--md-sys-typescale-label-medium-size, 12px); color: var(--md-sys-color-on-surface-variant); }
.ds-nav-hint svg { flex: none; color: var(--md-sys-color-on-surface-faint); }
.ds-nav-lbl { display: block; margin: 22px 0 8px; font-size: var(--md-sys-typescale-label-small-size, 11px); font-weight: 700; letter-spacing: .04em; text-transform: uppercase; color: var(--md-sys-color-on-surface-faint); }
.ds-nav-scroll { overflow-x: auto; padding: 2px 2px 10px; }

/* Cadre redimensionnable (poignée en bas à droite) + contexte container query */
.nav-frame { container-type: inline-size; container-name: nav; width: 100%; min-width: 320px; max-width: 1180px;
  position: relative; border-radius: var(--md-sys-shape-corner-medium); }
.nav-grip { position: absolute; right: -5px; top: 50%; transform: translateY(-50%); width: 6px; height: 42px; border-radius: var(--md-sys-shape-corner-extra-small);
  background: var(--md-sys-color-outline); cursor: ew-resize; z-index: 4; touch-action: none; transition: background-color .15s ease; }
.nav-grip:hover { background: var(--md-sys-color-on-surface-variant); }

.tbar { box-sizing: border-box; width: 100%; display: flex; align-items: center; gap: 26px; height: 72px; padding: 0 16px;
  background: var(--md-sys-color-surface); border: 1px solid var(--md-sys-color-outline); border-radius: var(--md-sys-shape-corner-medium);
  /* clip (PAS hidden : hidden créerait un conteneur de scroll et couperait aussi
     verticalement les menus déroulants sous la barre). Le panneau compte fermé
     (.tbar-account) reste rendu, translaté hors écran à droite : sans ce clip il
     élargit le scrollWidth de la page → barre de défilement horizontale. */
  overflow-x: clip; }
.tbar-logo { flex: none; height: 24px; max-height: 24px; width: auto; display: block; }
/* Logo en SVG dans la page (shared/logo.js) : couleur = currentColor, noir sur fond clair,
   blanc sur fond sombre. Les <img> -b / -w restent pour les pages statiques. */
svg.tbar-logo { color: #1B1C1E; }
.tbar--dark svg.tbar-logo, .ds-sec--dark svg.tbar-logo { color: #fff; }
.tbar-logo-w { display: none; }
.tbar--dark .tbar-logo-b, .ds-sec--dark .tbar-logo-b { display: none; }
.tbar--dark .tbar-logo-w, .ds-sec--dark .tbar-logo-w { display: block; }
/* Recherche de la barre du haut : LE MÊME composant que la recherche des pages
   (.ex-search, plus haut : 44, rayon 12, fond gris bleuté, loupe 18 à gauche,
   contour rose quand on écrit). Décision du porteur du 27/09/2026 (PDF des
   doublons) : une seule barre de recherche dans tout le produit, fini la pilule
   à loupe à droite. Ici seulement le placement : largeur 340 ; la loupe est un
   bouton (Entrée ou clic → Découvrir ; sur petit écran il ouvre la barre repliée).
   Variante repliée (.tbar-search--mini, vitrine) : la loupe seule (44), qui
   s'ouvre en barre de 340 × 44 (règles juste en dessous). */
.tbar-search { flex: 0 1 auto; width: 340px; min-width: 44px; max-width: 100%; margin: 0; overflow: hidden;
  transition: background-color .15s ease, border-color .15s ease; }
/* Croix NATIVE du navigateur masquée (input type=search). */
.tbar-search input::-webkit-search-cancel-button,
.tbar-search input::-webkit-search-decoration { -webkit-appearance: none; appearance: none; display: none; }
/* La loupe (et la croix de la variante repliée) : LE bouton icône du DS (.ibtn, 44 × 44, couche
   d'état). Dans le champ ouvert, il est collé au bord gauche (marge −12 = le padding du champ)
   pour que la loupe reste exactement à la place de l'icône de .ex-search, et le texte suit le
   bouton (marge −8 = l'écart du champ) ; l'icône garde les 18 du champ (.ex-search svg).
   Replié (écrans moyens, vitrine), c'est le .ibtn entier, sans marge. */
.tbar-search-go { flex: none; margin: 0 -8px 0 -12px; color: inherit; }
.tbar-search.is-focus { border-color: var(--md-sys-color-primary); }   /* aperçu « au clic » de l'atelier */
/* Variante REPLIÉE (vitrine) : la loupe seule, 44 ; au clic, la barre de 340 × 44
   s'ouvre avec une croix pour la refermer (shell-mkt-ds.js). Sélecteurs doublés
   (.tbar-search.tbar-search--mini) : même poids qu'avant leur arrivée ici. */
.tbar-search.tbar-search--mini { flex: none; width: 44px; padding: 0; justify-content: center; background: transparent; border-color: transparent; transition: width .2s ease, background-color .15s ease; }
.tbar-search.tbar-search--mini input, .tbar-search.tbar-search--mini .tbar-search-close { display: none; }
.tbar-search.tbar-search--mini .tbar-search-open { margin: 0; color: var(--md-sys-color-on-surface-strong); }   /* .ibtn tel quel */
.tbar-search.tbar-search--mini.is-expanded { width: 340px; padding: 0 12px; justify-content: flex-start; background: var(--md-sys-color-surface-container-high); }
.tbar-search.tbar-search--mini.is-expanded:focus-within { border-color: var(--md-sys-color-primary); }
.tbar-search.tbar-search--mini.is-expanded .tbar-search-open { margin: 0 -8px 0 -12px; color: inherit; }
.tbar-search.tbar-search--mini.is-expanded input { display: block; }
.tbar-search.tbar-search--mini.is-expanded .tbar-search-close { display: inline-flex; margin: 0 -12px 0 0; color: var(--md-sys-color-on-surface-variant); }
/* Vignette d'œuvre dans les résultats (affiche 32 × 44). */
.tbar-sr-cover { flex: none; width: 32px; height: 44px; border-radius: var(--md-sys-shape-corner-extra-small); overflow: hidden;
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--md-sys-color-surface-container-high); color: var(--md-sys-color-on-surface-variant); }
.tbar-sr-cover img { width: 100%; height: 100%; object-fit: cover; }
.tbar-right { margin-left: auto; align-self: stretch; display: flex; align-items: center; gap: 8px; flex: none; }
/* Séparateur vertical : trait 2×26, arrondi 10, 16px d'espace de chaque côté
   (8px de marge + 8px de gap flex de .tbar-right = 16px net). Specs Figma. */
.tbar-sep { flex: none; width: 2px; height: 26px; border-radius: var(--md-sys-shape-corner-small); margin: 0 8px; background: var(--md-sys-color-outline); }
/* Boutons icône de la barre (thème, langue, cloche, extension, menu) : LE bouton icône du DS
   (.ibtn) ; .tbar-ic ne fait que le placer (il ne rétrécit pas dans la barre). */
.tbar-ic { flex: none; }
.tbar-user { flex: 0 1 auto; min-width: 0; display: inline-flex; align-items: center; gap: 8px; height: 44px; padding: 0 8px; cursor: pointer;
  border: 0; border-radius: var(--md-sys-shape-corner-medium); background: transparent; transition: background-color .15s ease; }
.tbar-user:hover { background: var(--sp-hover-bg); }
.tbar-user-txt { display: flex; flex-direction: column; line-height: 1.15; text-align: left; }
.tbar-user-txt b { font: var(--md-sys-typescale-label-large); font-weight: 600; color: var(--md-sys-color-on-surface); white-space: nowrap;
  max-width: 22ch; overflow: hidden; text-overflow: ellipsis; }   /* un nom de 40 ne mange plus la recherche (nom entier : title) */
.tbar-user-txt i { font: var(--md-sys-typescale-label-small); font-style: normal; color: var(--md-sys-color-on-surface-variant); }
.tbar-user > svg { flex: none; color: var(--md-sys-color-on-surface-variant); }
.tbar-links { flex: none; display: flex; align-items: center; gap: 2px; }
.tbar-link { font: var(--md-sys-typescale-label-large); display: inline-flex; align-items: center; gap: 4px; height: 44px; padding: 0 12px; border-radius: var(--md-sys-shape-corner-medium); cursor: pointer; color: var(--md-sys-color-on-surface); text-decoration: none; white-space: nowrap; }
.tbar-link:hover { background: var(--sp-hover-bg); }
.tbar-link svg { flex: none; color: var(--md-sys-color-on-surface-variant); }
.tbar-signin { flex: none; }
.tbar-cta { flex: none; }
/* Bouton « Publier » (créateur) : UN seul bouton noir « + Publier | ⌄ » qui ouvre
   le menu des formats (réaction, vidéo libre, photos, texte, sondage). Même
   mécanique que les autres .tbar-dd. */
.tbar-publish-dd { margin-left: 2px; }
/* Le bouton reste NOIR quand son menu est ouvert (la règle générique des déclencheurs
   .tbar-dd-t l'éclaircissait) : il garde son rôle inverse-surface, en clair comme en sombre. */
.tbar-publish-dd .cbtn--noir.tbar-dd-t[aria-expanded="true"] { background: var(--md-sys-color-inverse-surface); color: var(--md-sys-color-inverse-on-surface); }
/* « + Publier | ⌄ » : filet fin puis chevron, qui se retourne quand le menu est ouvert. */
.tbar-publish { min-width: 190px; }
/* « + » de Publier → chevron à l'ouverture du menu (retour du porteur 25/09/2026) : les deux
   traits pivotent d'un huitième de tour et se raccourcissent (pointillé) en deux branches
   de chevron vers le haut, comme les autres menus ouverts. Mêmes tracés que Lucide. */
.tbar-pub-ic { flex: none; overflow: visible; }
.tbar-pub-ic path { transform-box: view-box; transform-origin: 12px 12px; stroke-dasharray: 14 100; stroke-dashoffset: 0;
  transition: transform .3s cubic-bezier(.2, 0, 0, 1), stroke-dasharray .3s cubic-bezier(.2, 0, 0, 1), stroke-dashoffset .3s cubic-bezier(.2, 0, 0, 1); }
.tbar-publish-dd[data-open] .tbar-pub-a { transform: translate(-3px, 0) rotate(-45deg); stroke-dasharray: 8.49 100; stroke-dashoffset: -2.76; }
.tbar-publish-dd[data-open] .tbar-pub-b { transform: translate(3px, 0) rotate(-45deg); stroke-dasharray: 8.49 100; stroke-dashoffset: -2.76; }
@media (prefers-reduced-motion: reduce) { .tbar-pub-ic path { transition: none; } }
/* Items du menu Publier : règle MENUS commune (plus bas). */
.tbar .tbar-burger-dd { display: none; margin-left: auto; }
.tbar-burger { display: inline-flex; align-items: center; justify-content: center; width: 44px; height: 44px;
  border: 0; border-radius: var(--md-sys-shape-corner-medium); background: transparent; color: var(--md-sys-color-on-surface); cursor: pointer; }
.tbar-burger:hover { background: var(--sp-hover-bg); }
/* Menu mobile (burger), contenu empilé, réutilise nos composants */
.tbar-mobile { min-width: 280px; max-width: 320px; display: flex; flex-direction: column; gap: 2px; }
.tbar-mobile .tbar-m-search { display: inline-flex; align-items: center; gap: 8px; height: 44px; padding: 0 12px; margin-bottom: 2px; background: var(--md-sys-color-surface-container-high); border-radius: var(--md-sys-shape-corner-small); color: var(--md-sys-color-on-surface-variant); }
.tbar-mobile .tbar-m-search input { font: var(--md-sys-typescale-body-medium); flex: 1; min-width: 0; border: 0; background: transparent; outline: none; color: var(--md-sys-color-on-surface); }
.tbar-mobile .tbar-m-cta { width: 100%; margin: 2px 0; }
/* Items du menu mobile : règle MENUS commune (plus bas) ; seule la déconnexion garde sa couleur. */
.tbar-mobile [role="menuitem"].danger, .tbar-mobile [role="menuitem"].danger svg { color: var(--md-sys-color-primary); }
.tbar-mobile .tbar-m-signin { justify-content: center; height: 44px; margin: 2px 0; border: 1px solid var(--md-sys-color-outline); border-radius: var(--md-sys-shape-corner-medium); }

/* Variante SOMBRE de la barre (bascule via la lune) — logo blanc + couleurs sombres */
.tbar--dark { background: #1B1C1E; border-color: #33363b; }
.tbar--dark .tbar-search { background: #25272B; color: #9aa1a9; }   /* barre sombre de la doc : surface-container-high du thème sombre */
.tbar--dark .tbar-search input { color: #fff; }
.tbar--dark .tbar-ic { color: #c7ccd3; }
.tbar--dark .tbar-sep { background: #33363b; }
.tbar--dark .tbar-ic:hover,
.tbar--dark .tbar-user:hover,
.tbar--dark .tbar-link:hover,
.tbar--dark .tbar-burger:hover,
.tbar--dark .tbar-dd-t[aria-expanded="true"] { background: #25272B; }
.tbar--dark .tbar-user-txt b { color: #fff; }
.tbar--dark .tbar-user-txt i,
.tbar--dark .tbar-user > svg,
.tbar--dark .tbar-link svg { color: #9aa1a9; }
.tbar--dark .tbar-link,
.tbar--dark .tbar-signin,
.tbar--dark .tbar-burger { color: #fff; }

/* Menus déroulants de la barre (avatar / notifications / langue) */
.tbar-dd { position: relative; flex: none; display: inline-flex; align-self: stretch; align-items: center; }
.tbar-dd-t[aria-expanded="true"] { background: var(--md-sys-color-surface-container-high); }
.tbar-caret { transition: transform .2s ease; }
.tbar-dd[data-open] .tbar-caret { transform: rotate(180deg); }
/* PASTILLE DE COMPTEUR (.tbar-dot) : LA seule pastille du DS, partout où un chiffre se pose
   sur un bouton (cloche, extension, Filtre), un onglet, une entrée du rail ou une vignette
   (unification des doublons validée par le porteur le 27/09/2026 : plus de .sbar-badge, de
   badge rouge ni de rond maison). Un ROND plein de 16, chiffre 11 / 700 centré, sans anneau
   (l'anneau blanc mordait sur la cloche et dessinait un demi-cercle ; 18 jugé trop gros,
   retours du porteur 25/09/2026). Au-delà de 9, elle s'allonge en pilule. En coin par défaut
   (absolue) ; dans le flux d'un onglet ou du rail déplié, elle suit le libellé (règles plus
   bas, dans chaque composant). */
.tbar-dot { font: var(--md-sys-typescale-label-small); font-size: var(--md-sys-typescale-label-small-size, 11px); font-weight: 700; line-height: 1; font-variant-numeric: tabular-nums; position: absolute; top: 6px; right: 6px; min-width: 16px; height: 16px; padding: 0 4px; box-sizing: border-box; border-radius: var(--md-sys-shape-corner-full); background: var(--md-sys-color-primary); border: 0; color: var(--md-sys-color-on-primary); font-style: normal; display: flex; align-items: center; justify-content: center;}
/* Piège : le « display: flex » ci-dessus l’emporte sur le [hidden] du navigateur, donc
   « dot.hidden = true » ne masquait RIEN. Le point de l’extension restait allumé même à
   jour, et la cloche affichait « 0 » en permanence. */
.tbar-dot[hidden] { display: none; }
/* NOMBRE DE RÉSULTATS (.count) : la seule façon d'écrire « il y en a 56 » à côté d'un titre,
   d'un onglet ou d'un libellé, ou seul sous une barre de liste (« 10 publications sur 26 ») :
   label-large, on-surface-variant, chiffres tabulaires, 6 px après ce qu'il compte. Pas de
   pastille ici : la pastille est pour ce qui attend (à examiner, non lu, nouveautés). */
.count { font: var(--md-sys-typescale-label-large); color: var(--md-sys-color-on-surface-variant); font-variant-numeric: tabular-nums; }
:is(h1, h2, h3, h4, button, a, label) > .count { margin-left: 6px; }
/* TITRES : trois titres et un sur-titre, une classe chacun (unification des doublons validée
   par le porteur le 27/09/2026 : 14 classes de page pour 3 tailles, plus une seule). La balise
   (h1, h2, h3) reste la structure de la page, la classe donne le style, la page ne règle que
   ses marges. .h-page : titre de page, headline-medium 24 / 700 (20 sur téléphone).
   .h-sec : titre de section, headline-small 20 / 700. .h-sub : sous-titre, title-medium
   15 / 700. .h-eyebrow : sur-titre, label-small 11 / 700 en capitales, primary. */
.h-page { font: var(--md-sys-typescale-headline-medium); font-weight: 700; letter-spacing: -0.01em; margin: 0; color: var(--md-sys-color-on-surface); }
.h-sec { font: var(--md-sys-typescale-headline-small); font-weight: 700; letter-spacing: -0.01em; margin: 0; color: var(--md-sys-color-on-surface); }
.h-sub { font: var(--md-sys-typescale-title-medium); font-weight: 700; margin: 0; color: var(--md-sys-color-on-surface); display: flex; align-items: center; gap: 8px; }   /* icône + texte + nombre : 8 px entre eux */
.h-sub > .count { margin-left: 0; }
.h-sub[hidden] { display: none; }
.h-eyebrow { font: var(--md-sys-typescale-label-small); font-weight: 700; letter-spacing: .08em; text-transform: uppercase; margin: 0; color: var(--md-sys-color-primary); }
@media (max-width: 560px) { .h-page { font-size: var(--md-sys-typescale-headline-small-size); } }
/* Le conteneur (.tbar-dd) prend toute la hauteur de la barre : le panneau démarre 8 px SOUS
   la barre (100 % + 8 px) et son bord droit s'aligne sur le bord droit de son bouton. Il ne
   mord jamais sur la barre (retour du porteur du 29/09/2026 : « le point qui m'énerve le plus »). */
.tbar-dd-panel { position: absolute; top: calc(100% + 8px); right: 0; z-index: 60; display: none; min-width: 200px; }
/* (Le dessin du panneau, fond, filet, rayon 12, ombre, est celui du composant Menu, plus
   bas : une seule règle pour tous les panneaux, décision du porteur du 27/09/2026.) */
.tbar-dd[data-open] .tbar-dd-panel { display: block; }
.tbar-menu-sep { height: 1px; margin: 4px 6px; background: var(--md-sys-color-outline-variant); }

/* Panneau compte = menu profil, déroulant FLOTTANT (réf. Figma 48096564).
   Panneau haut de 277px, contenu en DEUX groupes avec un espace au milieu :
   le haut (profil … langue) et le bas ANCRÉ en bas (aide, commentaires, déco). */
/* Fermé = hors écran à droite (translateX 100%), invisible et inerte. On garde le
   panneau RENDU (pas de display:none) pour pouvoir l'animer À LA FERMETURE aussi. */
.tbar-account { display: flex; width: 277px; max-width: 92vw; height: calc(100vh - 88px);
  padding: 12px; flex-direction: column; justify-content: space-between; gap: 8px; overflow-y: auto;
  /* +24px au-delà de 100% : le bord droit du panneau étant à ~16px du bord d'écran,
     un translateX(100%) laisserait un liseré visible que la visibility ferait
     "claquer". On le pousse ENTIÈREMENT hors écran → fermeture propre. */
  transform: translateX(calc(100% + 24px)); visibility: hidden; pointer-events: none;
  transition: transform .26s cubic-bezier(.22, 1, .36, 1), visibility 0s linear .28s; }
/* Volet PLEINE HAUTEUR, comme au départ (retour du porteur du 29/09/2026) : il démarre 8 px sous
   la barre (règle commune .tbar-dd-panel) et s'arrête 8 px avant le bas de l'écran. Son seul défaut
   était de chevaucher la barre du haut : c'est le « top » commun qui le corrige. */
.tbar-dd[data-open] .tbar-account { display: flex; transform: translateX(0); visibility: visible; pointer-events: auto;
  transition: transform .26s cubic-bezier(.22, 1, .36, 1), visibility 0s; }
@media (prefers-reduced-motion: reduce) {
  .tbar-account, .tbar-dd[data-open] .tbar-account { transition: none; }
}
.tbar-acc-grp { display: flex; flex-direction: column; width: 100%; }
/* Quatre groupes (moi / créateur / SydePlay / aide) : ils se suivent SANS espace vide entre
   eux — un filet fin les sépare —, et seul le DERNIER (aide, commentaires, déconnexion)
   reste collé en bas du volet (space-between les dispersait sur toute la hauteur). */
.tbar-account { justify-content: flex-start; }
/* Séparateur : un filet dans la couleur des contours du DS, de la largeur des lignes (marges 12 px). */
.tbar-acc-grp + .tbar-acc-grp { position: relative; padding-top: 9px; margin-top: 4px; }
.tbar-acc-grp + .tbar-acc-grp::before { content: ""; position: absolute; top: 0; left: 12px; right: 12px; height: 1px; background: var(--md-sys-color-outline-variant); }
.tbar-acc-grp:last-child { margin-top: auto; }
/* Lignes du menu compte : 44 de haut (règle des 44 px), marges 12, écart 10, rayon 12,
   libellé 14 / 500, couche d'état ; marche pour <button> ET <a>. */
.tbar-account [role="menuitem"] { position: relative; isolation: isolate; display: flex; align-items: center; gap: 10px; width: 100%; height: 44px; padding: 0 12px; border: 0; border-radius: var(--md-sys-shape-corner-medium);
  background: transparent; font: var(--md-sys-typescale-label-large); color: var(--md-sys-color-on-surface); text-decoration: none; cursor: pointer; text-align: left; }
.tbar-account [role="menuitem"]::after { content: ""; position: absolute; inset: 0; border-radius: inherit; background: currentColor; opacity: 0; pointer-events: none; transition: opacity .15s ease; }
.tbar-account [role="menuitem"]:hover::after { opacity: var(--md-sys-state-hover-opacity); }
.tbar-account [role="menuitem"]:active::after { opacity: var(--md-sys-state-pressed-opacity); }
.tbar-account [role="menuitem"] svg { flex: none; color: var(--md-sys-color-on-surface-variant); }
.tbar-account [role="menuitem"].danger, .tbar-account [role="menuitem"].danger svg { color: var(--md-sys-color-primary); }
/* Ligne « Thème » (menu du compte et menu mobile) : libellé comme une ligne du menu, segment à droite. */
.tbar-acc-theme { display: flex; align-items: center; justify-content: space-between; gap: 10px; width: 100%; min-height: 44px; padding: 0 12px; box-sizing: border-box; }
.tbar-acc-theme-lbl { display: inline-flex; align-items: center; gap: 10px; font: var(--md-sys-typescale-label-large); color: var(--md-sys-color-on-surface); }
.tbar-acc-theme-lbl svg { flex: none; color: var(--md-sys-color-on-surface-variant); }

/* Panneau notifications : panneau flottant, formes SydePlay. En-tête : titre,
   filtre Toutes / Non lues en puces du DS, bouton « tout supprimer » de 32.
   Notifications : visuel rond 40, titre 14 / 600, texte 13, couche d'état au
   survol. */
.tbar-notif { width: 420px; max-width: 92vw; padding: 0; overflow: hidden; }
.tbar-dd-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; padding: 8px 12px; font: var(--md-sys-typescale-label-small); letter-spacing: .04em; text-transform: uppercase; color: var(--md-sys-color-on-surface-faint); }
.tbar-notif-head { display: flex; align-items: center; gap: 8px; padding: 14px 16px 10px; }
.tbar-notif-head > span { font: var(--md-sys-typescale-title-large); color: var(--md-sys-color-on-surface); margin-right: auto; }
.tbar-notif-readall { display: inline-flex; align-items: center; justify-content: center; width: 32px; height: 32px; border: 0; border-radius: var(--md-sys-shape-corner-small);
  background: transparent; color: var(--md-sys-color-on-surface-variant); cursor: pointer; }
.tbar-notif-readall:hover { background: var(--sp-hover-bg); }
.tbar-notif-readall span { display: none; }
/* Filtre Toutes / Non lues : puces de filtre du DS (.chip, .chip--on), version refaite retenue le 25/09/2026. */
.tbar-notif-filter { display: inline-flex; gap: 8px; }
.tbar-notif-list { max-height: 60vh; overflow-y: auto; }
.tbar-notif-item { position: relative; isolation: isolate; display: flex; align-items: flex-start; gap: 12px; width: 100%; box-sizing: border-box; padding: 14px 16px;
  border: 0; border-top: 1px solid var(--md-sys-color-outline-variant); border-radius: 0;
  background: transparent; text-align: left; color: var(--md-sys-color-on-surface); text-decoration: none; cursor: pointer; }
.tbar-notif-item::after { content: ""; position: absolute; inset: 0; background: currentColor; opacity: 0; pointer-events: none; transition: opacity .15s ease; }
.tbar-notif-item:not(.is-info):hover::after { opacity: var(--md-sys-state-hover-opacity); }
.tbar-notif-item.is-info { cursor: default; }
/* Carré aux coins arrondis, pas un rond : à cette taille on ne fait quasiment pas de
   cercles (retour du porteur 25/09/2026), comme les avatars. */
.tbar-notif-ic { flex: none; display: inline-flex; width: 40px; height: 40px; align-items: center; justify-content: center; border-radius: var(--md-sys-shape-corner-medium);
  background: var(--md-sys-color-surface-container-high); color: var(--md-sys-color-on-surface-variant); }
.tbar-notif-item.is-unread .tbar-notif-ic { background: var(--md-sys-color-primary-container); color: var(--md-sys-color-primary); }
/* Photo de la personne concernée (shared/notif-visuel.js, 20/10/2026), à la place de l'icône : même
   carré arrondi de 40 px que les avatars (initiales sans photo), et la pastille ronde du type de
   notification posée sur le coin, détourée par le fond de la liste. */
.ntf-acteur { position: relative; flex: none; width: 40px; height: 40px; --ntf-detour: var(--md-sys-color-surface); }
.ntf-acteur-ava { position: relative; display: flex; width: 100%; height: 100%; align-items: center; justify-content: center; overflow: hidden;
  border-radius: var(--md-sys-shape-corner-medium); background: var(--md-sys-color-surface-container-high); color: var(--md-sys-color-on-surface-variant);
  font: var(--md-sys-typescale-label-large); font-weight: 700; }
.ntf-acteur-ava img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.ntf-acteur-type { position: absolute; right: -5px; bottom: -5px; display: flex; width: 20px; height: 20px; align-items: center; justify-content: center;
  border-radius: 50%; background: var(--md-sys-color-primary); color: var(--md-sys-color-on-primary); box-shadow: 0 0 0 2px var(--ntf-detour); }
.ntf-acteur-type svg { width: 12px; height: 12px; }
.tbar-notif-txt { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 3px; }
.tbar-notif-txt > span { font: var(--md-sys-typescale-title-small); color: var(--md-sys-color-on-surface); }
/* Non lu : le titre passe en gras (pas seulement la couleur de l'icône, WCAG 1.4.1). */
.tbar-notif-item.is-unread .tbar-notif-txt > span { font-weight: 700; }
.tbar-notif-txt > span small { font: var(--md-sys-typescale-body-small); color: var(--md-sys-color-on-surface-variant); margin-left: 8px; white-space: nowrap; }
.tbar-notif-txt > i { font: var(--md-sys-typescale-body-small); font-style: normal; color: var(--md-sys-color-on-surface-variant); display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.tbar-notif-dot { flex: none; width: 8px; height: 8px; margin-top: 6px; border-radius: var(--md-sys-shape-corner-full); background: var(--md-sys-color-primary); }
.tbar-notif-go { display: none; }
.tbar-notif-empty { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 8px; min-height: 260px; padding: 24px; text-align: center; }
.tbar-notif-empty-ic { display: inline-flex; align-items: center; justify-content: center; width: 52px; height: 52px; margin-bottom: 8px; border-radius: var(--md-sys-shape-corner-full);
  background: var(--md-sys-color-surface-container-high); color: var(--md-sys-color-on-surface-variant); }
.tbar-notif-empty b { font: var(--md-sys-typescale-title-large); color: var(--md-sys-color-on-surface); }
.tbar-notif-empty i { font: var(--md-sys-typescale-body-medium); font-style: normal; color: var(--md-sys-color-on-surface-variant); max-width: 300px; }
.tbar-notif.is-empty .tbar-notif-filter, .tbar-notif.is-empty .tbar-notif-readall { display: none; }
.tbar-notif-all { position: relative; isolation: isolate; display: flex; align-items: center; justify-content: center; gap: 6px; margin: 0; padding: 12px 8px;
  border-top: 1px solid var(--md-sys-color-outline-variant); border-radius: 0 0 8px 8px; color: var(--md-sys-color-primary); text-decoration: none;
  font: var(--md-sys-typescale-label-large); font-size: var(--md-sys-typescale-body-small-size, 12.5px); font-weight: 600; }
.tbar-notif-all::after { content: ""; position: absolute; inset: 0; background: currentColor; opacity: 0; pointer-events: none; transition: opacity .15s ease; }
.tbar-notif-all:hover::after { opacity: var(--md-sys-state-hover-opacity); }
.tbar-notif-all svg { flex: none; }

/* Panneau langue */
.tbar-lang { min-width: 180px; }
.tbar-lang-item { display: flex; align-items: center; justify-content: space-between; gap: 12px; width: 100%; border: 0;
  background: transparent; cursor: pointer; font: var(--md-sys-typescale-label-large); color: var(--md-sys-color-on-surface); }
.tbar-lang-item svg { flex: none; color: var(--md-sys-color-primary); opacity: 0; }
.tbar-lang-item.is-active svg { opacity: 1; }

/* Liens marketing avec menu déroulant (panneau = .tbar-dd-panel) */
button.tbar-link { background: transparent; border: 0; font-family: "Noto Sans", ui-sans-serif, sans-serif; }
.tbar-link-dd { position: relative; flex: none; }
.tbar-linkmenu { min-width: 230px; }
.tbar-linkmenu-item { display: flex; align-items: center; gap: 10px; width: 100%;
  border: 0; background: transparent; color: var(--md-sys-color-on-surface); cursor: pointer; text-align: left; text-decoration: none;
  font: var(--md-sys-typescale-label-large); }
.tbar-linkmenu-item svg { flex: none; color: var(--md-sys-color-on-surface-variant); }

/* ── Barre latérale (rail de gauche), Figma « Bar de gauche » ──
   Formes SydePlay (règle des 44 px) : déplié 220, replié 84 ; lignes de 44,
   rayon 12, marge 10, écart icône-libellé 10, icônes 22, libellé 14 / 500,
   10 entre les lignes. Couleurs (rôles Material 3) : inactif on-surface ;
   survol secondary-container (rose pâle) ; actif inverse-surface + inverse-
   on-surface (noir en clair, blanc en sombre) ; appui = couche d'état ; focus
   clavier = anneau primary. Pastille de compteur : primary / on-primary. */
.sbar-demo { display: flex; gap: 32px; align-items: flex-start; flex-wrap: wrap; }
.sbar-demo-col { display: flex; flex-direction: column; gap: 10px; }
.sbar-demo-lbl { font-size: var(--md-sys-typescale-label-medium-size, 12px); font-weight: 600; color: var(--md-sys-color-on-surface-variant); }
.sbar { display: flex; flex-direction: column; justify-content: space-between; width: 220px; height: 540px;
  background: transparent; overflow: hidden; transition: width .2s ease; }
.sbar.is-collapsed { width: 84px; }
.sbar-top { flex: 1; min-height: 0; position: relative; display: flex; flex-direction: column; align-items: center;
  gap: 16px; padding: 24px 20px 0; overflow: hidden; }
.sbar.is-collapsed .sbar-top { padding: 24px 16px 0; }
.sbar-scroll { flex: 1; min-height: 0; width: 100%; overflow-y: auto; overflow-x: hidden; padding-bottom: 20px; scrollbar-width: none; }
.sbar-scroll::-webkit-scrollbar { display: none; }
.sbar-nav { flex: none; display: flex; flex-direction: column; gap: 10px; width: 100%; }
.sbar-btn, .sbar-creator { position: relative; isolation: isolate; display: flex; align-items: center; gap: 10px; width: 100%; height: 44px; padding: 0 10px; border: 0;
  background: transparent; border-radius: var(--md-sys-shape-corner-medium); cursor: pointer; color: var(--md-sys-color-on-surface);
  font: var(--md-sys-typescale-label-large); text-align: left; text-decoration: none;
  transition: width .22s ease, padding .22s ease, background-color .15s ease, color .15s ease; }
.sbar-btn::after, .sbar-creator::after { content: ""; position: absolute; inset: 0; border-radius: inherit; background: currentColor; opacity: 0; pointer-events: none; transition: opacity .15s ease; }
.sbar-btn:hover::after, .sbar-creator:hover::after { opacity: var(--md-sys-state-hover-opacity); }   /* survol gris (couche d'état), plus de rose : retour du porteur 29/09/2026 */
.sbar-btn:active::after, .sbar-creator:active::after { opacity: var(--md-sys-state-pressed-opacity); }
.sbar-btn:focus-visible, .sbar-creator:focus-visible { outline: 3px solid var(--md-sys-color-primary); outline-offset: -3px; }
.sbar-btn.on, .sbar-btn.on:hover { background: var(--md-sys-color-inverse-surface); color: var(--md-sys-color-inverse-on-surface); }
.sbar-btn svg { flex: none; width: 22px; height: 22px; }
/* Pastille du rail (« Mes œuvres » : compteur de nouveautés) : la pastille de compteur du DS
   (.tbar-dot), poussée à droite dans la ligne quand le rail est déplié, en coin quand il est
   replié. Pas de couleur inversée sur la ligne active : une seule pastille, rose. */
.sbar-btn .tbar-dot { position: static; margin-left: auto; flex: none; }
.sbar.is-collapsed .sbar-btn .tbar-dot { position: absolute; top: 3px; right: 3px; margin: 0; }
/* Un libellé trop long pour le rail finit par « … » au lieu de sortir du rail (retour du porteur 26/09/2026). */
.sbar-label { min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 160px; opacity: 1; transition: max-width .22s ease, opacity .18s ease; }
.sbar-sep { flex: none; width: 26px; height: 2px; background: var(--md-sys-color-outline); border-radius: var(--md-sys-shape-corner-extra-small); }
.sbar-creators { display: flex; flex-direction: column; gap: 2px; width: 100%; }
.sbar-creator { padding: 0 10px 0 9px; }
/* Avatar 24 : son centre tombe exactement sur celui des icônes (22) des boutons du rail. */
.sbar-creator .ava { flex: none; width: 24px; height: 24px; border-radius: var(--md-sys-shape-corner-small); font-size: 10px; }
.sbar-subs-head { height: 40px; margin-top: 2px; }
.sbar-subs-head .sbar-label { flex: 1; font-weight: 600; }
.sbar-subs-head svg { width: 18px; height: 18px; color: var(--md-sys-color-on-surface-variant); }
.sbar-subs-head:hover svg { color: inherit; }
.sbar-more .sbar-label { font-weight: 500; }
.sbar-cname { flex: 1; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  max-width: 160px; opacity: 1; transition: max-width .22s ease, opacity .18s ease;
  font: var(--md-sys-typescale-body-medium); color: inherit; text-align: left; }
.sbar-fade { position: absolute; left: 0; right: 0; bottom: 0; height: 40px; pointer-events: none;
  background: linear-gradient(to bottom, transparent, var(--md-sys-color-surface)); }
.sbar-foot { display: flex; justify-content: flex-end; padding: 16px 20px 20px; }
/* Replier / déplier : bouton discret (icône 18, cible 44 × 44, rayon 8), couche d'état au survol. */
.sbar-toggle { position: relative; isolation: isolate; display: inline-flex; align-items: center; justify-content: center; width: 44px; height: 44px; padding: 0; border: 0;
  background: transparent; border-radius: var(--md-sys-shape-corner-small); color: var(--md-sys-color-on-surface-variant); cursor: pointer; }
.sbar-toggle::after { content: ""; position: absolute; inset: 0; border-radius: inherit; background: currentColor; opacity: 0; pointer-events: none; transition: opacity .15s ease; }
.sbar-toggle:hover { color: var(--md-sys-color-on-surface); }
.sbar-toggle:hover::after { opacity: var(--md-sys-state-hover-opacity); }
.sbar-toggle:active::after { opacity: var(--md-sys-state-pressed-opacity); }
.sbar-toggle:focus-visible { outline: 3px solid var(--md-sys-color-primary); outline-offset: 1px; }
.sbar.is-collapsed .sbar-label, .sbar.is-collapsed .sbar-cname { max-width: 0; opacity: 0; }
.sbar.is-collapsed .sbar-nav, .sbar.is-collapsed .sbar-creators { align-items: center; }
/* Replié : chaque ligne devient un carré de 44 centré (l'avatar aussi). */
.sbar.is-collapsed .sbar-btn, .sbar.is-collapsed .sbar-creator { width: 44px; justify-content: center; padding: 0; gap: 0; }
.sbar.is-collapsed .sbar-subs-head { display: none; }
.sbar.is-collapsed .sbar-creator .ava { margin: 0 auto; }
.sbar.is-collapsed .sbar-foot { justify-content: center; padding: 16px 0 20px; }
/* Sous 1000 px, le rail de l'application est replié d'office : même rendu que .is-collapsed. */
@media (max-width: 1000px) {
  .ds-app .sbar { width: 84px; }
  .ds-app .sbar .sbar-top { padding: 24px 16px 0; }
  .ds-app .sbar .sbar-label, .ds-app .sbar .sbar-cname, .ds-app .sbar .sbar-subs-head { display: none; }
  .ds-app .sbar .sbar-nav, .ds-app .sbar .sbar-creators { align-items: center; }
  .ds-app .sbar .sbar-btn, .ds-app .sbar .sbar-creator { width: 44px; justify-content: center; padding: 0; gap: 0; }
  .ds-app .sbar .sbar-creator .ava { margin: 0 auto; }
  .ds-app .sbar .sbar-btn .tbar-dot { position: absolute; top: 3px; right: 3px; margin: 0; }
  .ds-app .sbar .sbar-foot { justify-content: center; padding: 16px 0 20px; }
}

/* Logo cliquable */
.tbar-logo-link { flex: none; display: inline-flex; align-items: center; }

/* Fondation Logo (blocs/cartes SVG auto-portés : fond + bordure intégrés) */
.ds-logo-row { display: flex; flex-wrap: wrap; gap: 16px; }
.ds-logo-card { height: 76px; width: auto; display: block; }

/* Fondation Favicon (le « S » dans le carré arrondi : 3 couleurs, chacune sur sa tuile) */
.ds-favi-row { display: flex; flex-wrap: wrap; gap: 16px; }
.ds-favi { display: flex; flex-direction: column; align-items: center; gap: 10px; margin: 0; }
.ds-favi-tile { width: 104px; height: 104px; border-radius: var(--md-sys-shape-corner-medium); display: flex; align-items: center; justify-content: center; }
.ds-favi-tile img { width: 56px; height: 56px; display: block; }
/* Fonds FIXES (indépendants du thème de la carte) : chaque déclinaison doit
   toujours s'afficher sur le fond qui la met en valeur. */
.ds-favi-tile--light { background: #F4F5F7; border: 1px solid rgba(24, 24, 27, .10); }
.ds-favi-tile--dark { background: #121214; border: 1px solid #121214; }
.ds-favi-cap { font-size: var(--md-sys-typescale-label-medium-size, 12px); color: var(--md-sys-color-on-surface-variant); text-align: center; }

/* Container queries : repli aux breakpoints Figma */
@container nav (max-width: 819px) { .tbar--app .tbar-search:not(.is-open) { flex: 0 0 44px; width: 44px; padding: 0; justify-content: center; background: transparent; border-color: transparent; }
  .tbar--app .tbar-search:not(.is-open) .tbar-search-go { margin: 0; color: var(--md-sys-color-on-surface-strong); }   /* .ibtn seul */
  .tbar--app .tbar-search input { display: none; } }
@container nav (max-width: 979px) { .tbar--app .tbar-o1 { display: none; } }   /* laisse sa place à la barre de recherche fixe */
@container nav (max-width: 539px) { .tbar--app .tbar-cta, .tbar--app .tbar-publish-dd, .tbar--app .tbar-user-txt { display: none; } }
@container nav (max-width: 399px) { .tbar--app .tbar-search, .tbar--app .tbar-right { display: none; } .tbar--app .tbar-burger-dd { display: inline-flex; } }
@container nav (max-width: 739px) { .tbar--admin .tbar-cta { display: none; } }
@container nav (max-width: 399px) { .tbar--admin .tbar-right { display: none; } .tbar--admin .tbar-burger-dd { display: inline-flex; } }
@container nav (max-width: 899px) { .tbar--mkt .tbar-links, .tbar--mkt .tbar-right { display: none; } .tbar--mkt .tbar-burger-dd { display: inline-flex; } }

/* Recherche : panneau de résultats (portail), formes SydePlay : fond surface,
   filet, rayon 12, marge 6, élévation 3, largeur 300 à 420 ; résultats compacts
   (visuel 34 au rayon 8, titre title-small, texte body-small), couche d'état
   au survol ; intertitres en petites capitales. */
.tbar-search-panel { box-sizing: border-box; min-width: 300px; max-width: 420px; max-height: 62vh; overflow-y: auto;
  background: var(--md-sys-color-surface); border: 1px solid var(--md-sys-color-outline-variant); border-radius: var(--md-sys-shape-corner-medium);
  box-shadow: var(--md-sys-elevation-level3); padding: 6px; }
.tbar-sr-grp { padding: 8px 10px 4px; font: var(--md-sys-typescale-label-small); font-weight: 600; letter-spacing: .04em;
  text-transform: uppercase; color: var(--md-sys-color-on-surface-faint); }
.tbar-sr-item { position: relative; isolation: isolate; box-sizing: border-box; width: 100%; display: flex; align-items: center; gap: 10px; padding: 8px 10px;
  border: 0; background: transparent; border-radius: var(--md-sys-shape-corner-small); cursor: pointer; text-align: left; text-decoration: none; color: var(--md-sys-color-on-surface); }
.tbar-sr-item::after { content: ""; position: absolute; inset: 0; border-radius: inherit; background: currentColor; opacity: 0; pointer-events: none; transition: opacity .15s ease; }
.tbar-sr-item:hover::after { opacity: var(--md-sys-state-hover-opacity); }
.tbar-sr-item:focus-visible { outline: 3px solid var(--md-sys-color-primary); outline-offset: -3px; }
.tbar-sr-item:focus-visible::after { opacity: var(--md-sys-state-focus-opacity); }
.tbar-sr-ic { flex: none; width: 34px; height: 34px; display: inline-flex; align-items: center; justify-content: center; overflow: hidden;
  background: var(--md-sys-color-surface-container-high); border-radius: var(--md-sys-shape-corner-small); color: var(--md-sys-color-on-surface-variant); }
.tbar-sr-item .ava { width: 34px; height: 34px; }
.tbar-sr-txt { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.tbar-sr-txt b { font: var(--md-sys-typescale-title-small); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.tbar-sr-txt i { font: var(--md-sys-typescale-body-small); font-style: normal; color: var(--md-sys-color-on-surface-variant); }
.tbar-sr-go { flex: none; color: var(--md-sys-color-on-surface-faint); }
.tbar-sr-empty { display: flex; align-items: center; gap: 8px; padding: 16px 12px; font: var(--md-sys-typescale-body-medium); color: var(--md-sys-color-on-surface-variant); }
.tbar--app .tbar-search.is-open { position: absolute; left: 52px; right: 12px; top: 14px; z-index: 50;
  flex: none; width: auto; padding: 0 12px; justify-content: flex-start; background: var(--md-sys-color-surface-container-high);
  border-color: var(--md-sys-color-primary); }
.tbar--app .tbar-search.is-open input { display: block; }

/* Bloc utilisateur : états de session affichés/masqués sans re-câblage (data-auth sur la barre) */
.tbar-auth { display: none; }
.tbar[data-auth="creator"] .tbar-auth--creator,
.tbar[data-auth="viewer"] .tbar-auth--viewer,
.tbar[data-auth="guest"] .tbar-auth--guest,
.tbar[data-auth="member"] .tbar-auth--member { display: contents; }
/* Réservé au créateur (ex. « Update réaction ») : masqué pour un viewer */
.tbar-creator-only.is-hidden { display: none; }
/* En-tête du menu compte : identité dynamique (nom + rôle + photo/initiales) */
.tbar-account-head { display: flex; align-items: center; gap: 10px; padding: 8px 10px 4px; }
.tbar-account-id { display: flex; flex-direction: column; min-width: 0; }
.tbar-account-id b { font: var(--md-sys-typescale-title-small); color: var(--md-sys-color-on-surface); }
.tbar-account-id i { font: var(--md-sys-typescale-body-small); font-style: normal; color: var(--md-sys-color-on-surface-variant); }
/* Bloc utilisateur condensé (avatar + chevron) quand la place manque — admin & marketing, comme l'app */
@container nav (max-width: 639px) { .tbar--admin .tbar-user-txt { display: none; } }
@container nav (max-width: 1040px) { .tbar--mkt .tbar-user-txt { display: none; } }
/* Bascule de démo « état de connexion » au-dessus des barres */
.ds-nav-lblrow { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
.ds-auth-seg { display: inline-flex; gap: 2px; padding: 3px; background: var(--md-sys-color-surface-container-high); border-radius: var(--md-sys-shape-corner-small); }
.ds-auth-seg button { border: 0; background: transparent; padding: 5px 12px; border-radius: var(--md-sys-shape-corner-small);
  font-family: "Noto Sans", sans-serif; font-size: var(--md-sys-typescale-label-medium-size, 12px); font-weight: 600; color: var(--md-sys-color-on-surface-variant); cursor: pointer; }
.ds-auth-seg button.on { background: var(--md-sys-color-surface); color: var(--md-sys-color-on-surface); box-shadow: var(--md-sys-elevation-level1); }

/* Menus déroulants en thème sombre : le panneau est en portail (hors de la barre),
   donc on remappe ses variables localement — tous les items suivent automatiquement. */
.tbar-dd-panel.is-dark, .tbar-search-panel.is-dark {
  --panel: #212327; --raised: #2E3136; --ink: #EDEFF2; --ink-2: #C8CCD2;
  --muted: #969CA6; --faint: #8d939c; --line: rgba(255, 255, 255, .09); --line-2: rgba(255, 255, 255, .14);
  box-shadow: var(--md-sys-elevation-level4);
}
/* Résultats de recherche affichés en ligne dans le burger (mobile) */
.tbar-m-results { display: flex; flex-direction: column; max-height: 44vh; overflow-y: auto; }
.tbar-m-results:not(:empty) { margin: 2px 0 4px; }

/* Carte générique */
.ex-card { width: 280px; background: var(--md-sys-color-surface); border: 1px solid var(--md-sys-color-outline); border-radius: var(--md-sys-shape-corner-medium); overflow: hidden; }
.ex-card-media { height: 130px; background: linear-gradient(135deg, #3a0f1c, var(--md-sys-color-primary)); }
.ex-card-body { padding: 16px; }
.ex-card-body h4 { font: var(--md-sys-typescale-title-large); margin: 0 0 6px; }
.ex-card-body p { font: var(--md-sys-typescale-body-medium); line-height: 1.5; margin: 0 0 14px; color: var(--md-sys-color-on-surface-variant);}

/* Carte de réaction */
/* Carte de réaction — l'habit « séance » (2026-10-23) : carton de 18 px,
   bouton lecture de la marque, pastilles de plateformes et de durée en verre dépoli,
   survol rosé avec soulèvement. Le mécanisme (html[data-survol], trois effets) est inchangé. */
.rcard { --rcard-amber: var(--md-sys-color-primary);   /* le rose de la marque (plus de doré, retour terrain 24/10/2026) */ width: 358px; max-width: 100%; background: var(--md-sys-color-surface); border: 1px solid var(--md-sys-color-outline-variant); border-radius: 18px; overflow: hidden; cursor: pointer;
  box-shadow: 0 6px 18px -12px rgba(0, 0, 0, .45); transition: box-shadow .25s ease, border-color .15s ease, transform .25s ease; }
/* Survol (choix du porteur, 20/10/2026, après comparaison sur l'accueil) : plus de zoom de la jaquette.
   Trois effets, sélectionnés par html[data-survol] (shared/survol-cartes.js, réglage dans Paramètres) :
   « lancer » par défaut, « projecteur », « relief ». Les badges, plateformes et durée restent fixes.
   Souris seulement (hover: hover) : au doigt, l'état collerait après le toucher. */
.rcard-media { position: relative; isolation: isolate; aspect-ratio: 16 / 9; padding: 12px; display: flex; flex-direction: column; justify-content: space-between;
  overflow: hidden; background: var(--md-sys-color-surface-container-high); }
/* Deux couches posées par reaction-ui.js dans .rcard-media : la lumière (.rcard-shine : voile sombre en
   Lancer, reflet rose en Projecteur et Relief) et le bouton lecture (.rcard-play, Lancer, vidéos seulement). */
.rcard-shine, .rcard-play { position: absolute; inset: 0; pointer-events: none; }
.rcard-shine { z-index: 0; opacity: 0; transition: opacity .25s ease;
  background: radial-gradient(circle at 50% 50%, rgba(0, 0, 0, .32), rgba(0, 0, 0, .08) 62%), linear-gradient(to top, rgba(0, 0, 0, .42), transparent 46%); }
.rcard-play { z-index: 2; display: flex; align-items: center; justify-content: center; }
.rcard-play i { display: flex; align-items: center; justify-content: center; width: clamp(56px, 16%, 68px); aspect-ratio: 1; border-radius: var(--md-sys-shape-corner-full);
  background: var(--md-sys-color-primary); color: var(--md-sys-color-on-primary); box-shadow: 0 12px 30px -6px rgba(0, 0, 0, .55);
  opacity: 0; transform: scale(.8); transition: opacity .16s ease, transform .34s cubic-bezier(.16, 1, .3, 1); }
.rcard-play svg { width: 42%; height: 42%; fill: currentColor; margin-left: 6%; }
@media (hover: hover) {
  /* Lancer : bouton lecture au centre, image assombrie, contour rose, la carte se soulève. */
  html[data-survol="lancer"] .rcard:hover { border-color: color-mix(in srgb, var(--md-sys-color-primary) 75%, transparent); box-shadow: 0 18px 38px -16px rgba(0, 0, 0, .6); transform: translateY(-3px); }
  html[data-survol="lancer"] .rcard:hover .rcard-shine { opacity: 1; }
  html[data-survol="lancer"] .rcard:hover .rcard-play i { opacity: 1; transform: none; }
  html[data-survol="lancer"] .rcard:active .rcard-play i { transform: scale(.93); transition-duration: .1s; }
  /* Projecteur : la carte se soulève, l'image s'éclaire, un reflet rose la traverse une fois (0,62 s, réglé par le porteur). */
  html[data-survol="projecteur"] .rcard { transition: transform .4s cubic-bezier(.16, 1, .3, 1), box-shadow .4s cubic-bezier(.16, 1, .3, 1), border-color .15s ease; }
  html[data-survol="projecteur"] .rcard:hover { transform: translateY(-4px); box-shadow: 0 16px 32px -14px rgba(0, 0, 0, .7); }
  html[data-survol="projecteur"] .rcard-img { transition: filter .4s ease; }
  html[data-survol="projecteur"] .rcard:hover .rcard-img { filter: brightness(1.07) saturate(1.12); }
  html[data-survol="projecteur"] .rcard-shine { z-index: 2; opacity: 1; transition: none; mix-blend-mode: screen; transform: translateX(-75%);
    background: linear-gradient(105deg, transparent 34%, color-mix(in srgb, var(--md-sys-color-primary) 22%, transparent) 44%, color-mix(in srgb, var(--md-sys-color-primary) 55%, transparent) 50%, color-mix(in srgb, var(--md-sys-color-primary) 22%, transparent) 56%, transparent 66%); }
  html[data-survol="projecteur"] .rcard:hover .rcard-shine { animation: rcard-sweep .62s cubic-bezier(.3, .1, .3, 1) .04s both; }
  /* Relief : la carte s'incline vers la souris (variables posées par survol-cartes.js), une lueur rose suit le pointeur. */
  html[data-survol="relief"] .rcard { transform: perspective(900px) rotateX(var(--rcard-rx, 0deg)) rotateY(var(--rcard-ry, 0deg));
    transition: transform .5s cubic-bezier(.16, 1, .3, 1), box-shadow .5s cubic-bezier(.16, 1, .3, 1), border-color .15s ease; }
  html[data-survol="relief"] .rcard.is-tilting { transition: transform .1s linear, box-shadow .3s ease; box-shadow: 0 20px 36px -18px rgba(0, 0, 0, .75); will-change: transform; }
  html[data-survol="relief"] .rcard-shine { z-index: 2; transition: opacity .3s ease; mix-blend-mode: screen;
    background: radial-gradient(circle at var(--rcard-gx, 50%) var(--rcard-gy, 50%), color-mix(in srgb, var(--md-sys-color-primary) 50%, transparent), color-mix(in srgb, var(--md-sys-color-primary) 14%, transparent) 30%, transparent 60%); }
  html[data-survol="relief"] .rcard.is-tilting .rcard-shine { opacity: 1; }
}
@keyframes rcard-sweep { to { transform: translateX(75%); } }
/* Couche image : le visuel est fourni par l'app via la variable --rcard-cover
   (image ou dégradé) ; fallback = dégradé de démo. C'est CETTE couche qui zoome. */
.rcard-media::before { content: ""; position: absolute; inset: 0; z-index: 0;
  background: var(--rcard-cover, var(--sp-grad-banner)) center / cover no-repeat; }
/* La jaquette en <img> (reaction-ui.js, 14/10/2026) : posée exactement comme la couche ::before (même place,
   même cadrage cover), elle laisse le navigateur charger d'abord les jaquettes visibles. */
.rcard-img { position: absolute; inset: 0; z-index: 0; width: 100%; height: 100%; object-fit: cover; object-position: center; }
/* Cartes texte et sondage : ni jaquette ni film, la vignette montre un APERÇU du contenu (début
   du message, premières réponses) plutôt qu'un aplat vide. Texte on-media sur un voile scrim. */
.rcard-prev { position: absolute; inset: 0; z-index: 1; display: flex;
  flex-direction: column; justify-content: center; gap: 8px; padding: 44px 18px 18px; pointer-events: none; }
.rcard-prev--text p { font: var(--md-sys-typescale-body-medium); font-weight: 500; line-height: 1.5; margin: 0; color: var(--md-sys-color-on-media);
  white-space: pre-wrap; overflow: hidden; display: -webkit-box; -webkit-line-clamp: 6; -webkit-box-orient: vertical;
  text-shadow: 0 1px 3px color-mix(in srgb, var(--md-sys-color-shadow) 45%, transparent); }
/* Réponses du sondage : pastilles empilées, la lecture donne le sujet d'un coup. */
.rcard-prev--poll { align-items: flex-start; }
.rcard-prev-opt { font: var(--md-sys-typescale-label-medium); font-weight: 600; line-height: 1.2; max-width: 100%; padding: 5px 11px; border-radius: var(--md-sys-shape-corner-extra-small);
  background: color-mix(in srgb, var(--md-sys-color-scrim) 55%, transparent); border: 1px solid color-mix(in srgb, var(--md-sys-color-on-media) 16%, transparent);
  color: var(--md-sys-color-on-media); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.rcard-prev-more,
.rcard-prev-votes { font: var(--md-sys-typescale-label-small); font-weight: 600; color: color-mix(in srgb, var(--md-sys-color-on-media) 82%, transparent);
  text-shadow: 0 1px 3px color-mix(in srgb, var(--md-sys-color-shadow) 45%, transparent); }
/* Le voile assombrit l'aplat pour que le texte blanc reste lisible. */
.rcard--text .rcard-media::after,
.rcard--poll .rcard-media::after { content: ""; position: absolute; inset: 0;
  background: linear-gradient(to bottom, color-mix(in srgb, var(--md-sys-color-scrim) 30%, transparent), color-mix(in srgb, var(--md-sys-color-scrim) 55%, transparent)); }
.rcard-top { position: relative; z-index: 1; display: flex; gap: 8px; align-items: center; }
.rcard-plat { width: 30px; height: 30px; border-radius: var(--md-sys-shape-corner-small); display: block; flex: none; }
/* Classification (âge conseillé) sur la carte : 12+/16+ neutres, 18+ en rouge marque. */
.rcard-mat { font: var(--md-sys-typescale-label-small); font-weight: 800; display: inline-flex; align-items: center; height: 22px; padding: 0 8px; border-radius: var(--md-sys-shape-corner-small); letter-spacing: .02em; background: rgba(0,0,0,.55); color: #fff; backdrop-filter: blur(2px); }
.rcard-mat--18 { background: var(--md-sys-color-primary); color: var(--md-sys-color-on-primary); }
.rcard-bottom { position: relative; z-index: 1; display: flex; justify-content: space-between; align-items: center; gap: 8px; min-width: 0; }
/* La durée (ou le nombre de photos) reste à droite et entière ; la pastille de verrou, à gauche, se coupe.
   Les deux passent en pastille de verre dépoli (même langage que les plateformes). */
.rcard-bottom > .bdg { flex: none; margin-left: auto; }
.rcard-bottom > .bdg--dark { border-radius: 999px; background: color-mix(in srgb, var(--md-sys-color-scrim) 62%, transparent); backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px); }
/* Conteneur des icônes de plateformes du bandeau haut (peut en contenir plusieurs), posé sur un pilulier de verre. */
.rcard-plats { display: inline-flex; align-items: center; gap: 6px; padding: 3px 5px; border-radius: 10px;
  background: color-mix(in srgb, var(--md-sys-color-scrim) 55%, transparent); backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px); }
/* Icône de SOURCE de la réaction (YouTube/Vimeo/Dailymotion/Drive) : repère TEMPORAIRE
   de test, tout à droite, DÉTACHÉE des plateformes de streaming par un séparateur. */
.rcard-src { display: inline-flex; align-items: center; margin-left: 2px; padding-left: 8px;
  border-left: 1px solid rgba(255, 255, 255, .3); }
/* Même taille que les tuiles plateformes (30px). Fond BLANC : certaines icônes de
   marque (ex. le « V » de Vimeo) ont l'intérieur en découpe transparente — sur Figma
   elles sont posées sur du blanc, donc on remet ce fond pour qu'elles s'affichent bien. */
.rcard-src img { width: 30px; height: 30px; border-radius: var(--md-sys-shape-corner-small); display: block; object-fit: cover; background: #fff; }
/* Pied (maquette Figma « Reaction card » du 27/09/2026) : l'avatar est centré sur le
   TITRE, qu'il tienne sur une ou deux lignes ; l'œuvre et la méta passent dessous,
   alignées sur le titre ; les trois points sont en bas à droite. .rcard-txt s'efface
   (display: contents) pour que ses lignes se rangent dans la grille. */
.rcard-body { position: relative; z-index: 1; display: grid; grid-template-columns: auto minmax(0, 1fr) auto; column-gap: 10px; align-items: center; padding: 14px 16px 16px; background: var(--md-sys-color-surface); }
.rcard-body > .ava { grid-column: 1; grid-row: 1; }
.rcard-txt { display: contents; }
.rcard-title { grid-column: 2; grid-row: 1; font: var(--md-sys-typescale-title-large); letter-spacing: -0.01em; line-height: 1.28; color: var(--md-sys-color-on-surface); display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;}
.rcard-body > .rcard-more { grid-column: 3; grid-row: 1 / span 3; align-self: end; }
/* Ligne de l'œuvre et de l'épisode : entre le titre et le créateur. */
.rcard-ep { grid-column: 2; font: var(--md-sys-typescale-label-medium); margin-top: 4px; color: var(--md-sys-color-on-surface-strong); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* Œuvre coupée par « … » (title complet), épisode court jamais coupé : motif de la barre de lecture.
   L'épisode se colle à l'œuvre derrière un point médian, en couleur secondaire (retour du porteur du
   21/10/2026 : rejeté à l'autre bout de la ligne, il semblait décalé) ; un nom de série trop long
   est coupé AVANT lui, l'épisode reste donc toujours lisible. */
.rcard-ep:has(> .rcard-ep-work, > .rcard-ep-n) { display: flex; gap: 6px; min-width: 0; }
.rcard-ep-work { flex: 0 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.rcard-ep-n { flex: none; max-width: 100%; overflow: hidden; text-overflow: ellipsis; color: var(--md-sys-color-on-surface-variant); }
.rcard-ep-work + .rcard-ep-n::before { content: "·"; margin-right: 6px; }
/* Nom du créateur puis ancienneté de la publication, chacun précédé d'une icône
   Lucide de 13 px (circle-user, calendar), 4 px entre icône et texte, 12 px entre
   les deux. Le nom se coupe par « … », jamais la date. La durée est sur la vignette
   (cardDurationHTML : .bdg--dark en bas à droite, avec l'horloge). */
.rcard-meta { grid-column: 2; font: var(--md-sys-typescale-label-medium); margin-top: 4px; color: var(--md-sys-color-on-surface-variant); display: flex; align-items: center; gap: 12px; white-space: nowrap; min-width: 0; }
.rcard-meta-it { display: inline-flex; align-items: center; gap: 4px; min-width: 0; }
.rcard-meta-it svg { flex: none; }
.rcard-meta-it > span { overflow: hidden; text-overflow: ellipsis; }
.rcard-meta-date { flex: none; }


/* Onglets */
/* Onglets SydePlay : libellé 14 / 500 (on-surface-variant, rose quand actif),
   marges 10 × 14, soulignement 2 px rose sous l'onglet actif, filet sous la
   rangée, écart 4 ; hauteur 44 (règle des 44 px ; 39 avant l'audit du 13/10/2026).
   Couche d'état au survol, anneau au focus clavier. */
.ex-tabs { display: flex; gap: 4px; overflow-x: auto; scrollbar-width: none; border-bottom: 1px solid var(--md-sys-color-outline-variant); }
/* Indice de défilement (audit du 13/10/2026) : sans barre visible, rien ne disait sur téléphone
   qu'il reste des onglets à droite. Quand la rangée déborde, son bord droit s'estompe tant qu'on
   n'est pas au bout. Sans débordement, la frise de défilement est inactive : aucun fondu.
   Navigateurs sans animation-timeline : rendu inchangé. */
@supports (animation-timeline: scroll()) {
  .ex-tabs { animation: ex-tabs-suite linear both; animation-timeline: scroll(self inline); }
}
@keyframes ex-tabs-suite {
  0%, 96% { -webkit-mask-image: linear-gradient(90deg, #000 calc(100% - 32px), transparent); mask-image: linear-gradient(90deg, #000 calc(100% - 32px), transparent); }
  100% { -webkit-mask-image: none; mask-image: none; }
}
/* Un onglet est un bouton (panneaux de la même page) ou un lien (pages sœurs,
   ex. Communauté du Studio : Abonnés | Signalements) : même rendu. */
.ex-tabs :is(button, a) { position: relative; isolation: isolate; flex: none; display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  min-height: 44px; padding: 10px 14px; margin-bottom: -1px; border: 0; border-bottom: 2px solid transparent; background: transparent; cursor: pointer;
  font: var(--md-sys-typescale-label-large); color: var(--md-sys-color-on-surface-variant); text-decoration: none; }
.ex-tabs :is(button, a)::after { content: ""; position: absolute; inset: 0; background: currentColor; opacity: 0; pointer-events: none; transition: opacity .15s ease; }
.ex-tabs :is(button, a):hover::after { opacity: var(--md-sys-state-hover-opacity); }
.ex-tabs :is(button, a):focus-visible { outline: 3px solid var(--md-sys-color-primary); outline-offset: -3px; }
.ex-tabs :is(button, a):focus-visible::after { opacity: var(--md-sys-state-focus-opacity); }
.ex-tabs :is(button, a):active::after { opacity: var(--md-sys-state-pressed-opacity); }
.ex-tabs :is(button, a).on { color: var(--md-sys-color-primary); border-bottom-color: var(--md-sys-color-primary); }
.ex-tabs :is(button, a) svg { width: 18px; height: 18px; }
/* Dans un onglet : le nombre de résultats (.count) après le libellé ; ce qui attend le
   créateur (signalements à examiner) = la pastille de compteur, dans le flux. */
.ex-tabs :is(button, a) .tbar-dot { position: static; flex: none; }
.ex-tabs :is(button, a) .count { margin-left: 0; }

/* Dialog : démonstration dans la doc. Le composant lui-même (conteneur,
   titre, texte, actions) est défini une seule fois, section OVERLAYS. */
.ex-modal-wrap { padding: 24px; border-radius: var(--md-sys-shape-corner-medium); background: rgba(0, 0, 0, .7); display: inline-block; }
.ex-modal { width: 320px; }

/* Notifications & états */
.ex-fb { display: flex; flex-direction: column; align-items: flex-start; gap: 16px; }
/* Le toast de succès utilise désormais le skin badge (.bdg vert) — plus de style bespoke. */
/* État vide et chargement : ceux du PRODUIT (shared/states.js : .empty-*, .grid-state), plus de démo à part.
   Le squelette de chargement a été retiré du produit le 15/09/2026 (décision porteur). */
/* Chargement, erreur ou attente d'une liste : icône + texte centrés ; seule l'icône de chargement tourne.
   Quand il porte l'état vide illustré, il s'efface (pas de double marge). */
.grid-state { padding: 30px; text-align: center; font: var(--md-sys-typescale-body-medium); color: var(--md-sys-color-on-surface-variant); }
.grid-state .big { font-size: var(--md-sys-typescale-headline-medium-size); margin-bottom: 6px; }
.grid-state .big.spin svg { animation: sp-spin .8s linear infinite; }
@keyframes sp-spin { to { transform: rotate(360deg); } }
.grid-state:has(.empty-state) { padding: 0; }
.ex-fb-demo { max-width: 520px; border: 1px dashed var(--md-sys-color-outline-variant); border-radius: var(--md-sys-shape-corner-medium); }   /* cadre de démo de l'atelier */

/* ── Sommaire des fondations ── */
.ds-toc {
  display: flex; flex-wrap: wrap; gap: 8px;
  padding: 16px 0 28px; margin-bottom: 8px;
  border-bottom: 1px solid var(--md-sys-color-outline-variant);
}
.ds-toc-chip {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 7px 13px 7px 8px; border-radius: var(--md-sys-shape-corner-full);
  background: var(--md-sys-color-surface); border: 1px solid var(--md-sys-color-outline-variant);
  color: var(--md-sys-color-on-surface-strong); text-decoration: none;
  font-size: var(--md-sys-typescale-body-small-size, 12.5px); font-weight: 550;
  transition: border-color .15s ease, transform .15s ease, color .15s ease;
}
.ds-toc-chip:hover { border-color: var(--md-sys-color-on-surface); color: var(--md-sys-color-on-surface); transform: translateY(-1px); }
.ds-toc-num {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: var(--md-sys-typescale-label-small-size, 11px); color: var(--md-sys-color-on-surface-variant);
  background: var(--chip); border-radius: var(--md-sys-shape-corner-full);
  width: 22px; height: 22px; display: inline-flex; align-items: center; justify-content: center;
}

/* ── Sections de fondation ── */
.ds-sections { display: flex; flex-direction: column; gap: 18px; margin-top: 28px; }
.ds-sec {
  background: var(--md-sys-color-surface); border: 1px solid var(--md-sys-color-outline-variant);
  border-radius: var(--md-sys-shape-corner-medium); padding: 26px 28px;
  scroll-margin-top: 90px;
  transition: border-color .18s ease, box-shadow .18s ease;
}
.ds-sec:hover {
  border-color: var(--md-sys-color-outline);
}
/* Retrait de documentation : tout ce qui suit l'en-tête d'une section de
   l'atelier s'aligne sur son titre (52 px). Les composants eux-mêmes n'ont
   AUCUNE marge extérieure : ils se posent tels quels dans les pages. */
.ds-sec > :not(.ds-sec-head) { margin-left: 52px; }
@media (max-width: 640px) { .ds-sec > :not(.ds-sec-head) { margin-left: 0; } }
/* Largeurs de démonstration (atelier seulement) : dans les pages, ces composants prennent
   la place que la page leur donne. */
.ds-sec > .ex-fields { max-width: 640px; }
.ds-sec > .ex-platforms { max-width: 660px; }
.ds-sec > .feat { max-width: 640px; }
.ds-sec > .rlist { max-width: 340px; }
.ds-sec > .statc-grid { max-width: 680px; }
.ds-sec > .banner { max-width: 620px; }
.ds-sec > .accord-list { max-width: 520px; }
.ds-sec > .dstable-wrap { max-width: 620px; }
.ds-sec > .launch { width: auto; max-width: 860px; }
.ds-sec-head { display: flex; align-items: center; gap: 14px; margin-bottom: 10px; }
.ds-sec-num {
  flex: none; width: 38px; height: 38px; border-radius: var(--md-sys-shape-corner-small);
  background: var(--md-sys-color-inverse-surface); color: var(--md-sys-color-inverse-on-surface);
  display: inline-flex; align-items: center; justify-content: center;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: var(--md-sys-typescale-body-medium-size, 14px); font-weight: 600;
}
.ds-sec-head h2 { margin: 0; font-size: var(--md-sys-typescale-headline-small-size, 20px); font-weight: 650; letter-spacing: -0.01em; flex: 1; }
.ds-state {
  flex: none; font-size: var(--md-sys-typescale-label-medium-size, 12px); font-weight: 600; color: var(--md-sys-color-on-surface-variant);
  padding: 4px 11px; border-radius: var(--md-sys-shape-corner-full);
  border: 1px dashed var(--md-sys-color-outline); background: var(--md-sys-color-surface-container-low);
  text-transform: uppercase; letter-spacing: 0.04em;
}
.ds-sec-desc { margin: 0 0 18px; color: var(--md-sys-color-on-surface-variant); font-size: var(--md-sys-typescale-title-medium-size, 15px); line-height: 1.55; max-width: 60ch; }

/* Zone vide « à remplir ensemble » */
.ds-empty {
    min-height: 116px; border-radius: var(--md-sys-shape-corner-medium);
  border: 1.5px dashed var(--md-sys-color-outline);
  background: repeating-linear-gradient(-45deg, transparent, transparent 9px, rgba(24,24,27,.015) 9px, rgba(24,24,27,.015) 18px);
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 4px;
  text-align: center; padding: 20px;
}
.ds-empty .ds-empty-t { font-size: var(--md-sys-typescale-body-medium-size, 14px); font-weight: 600; color: var(--md-sys-color-on-surface-strong); }
.ds-empty .ds-empty-s { font-size: var(--md-sys-typescale-body-small-size, 12.5px); color: var(--md-sys-color-on-surface-faint); }

/* ── Pied ── */
.ds-foot {
  margin-top: 40px; padding: 22px 24px;
  border: 1px dashed var(--md-sys-color-outline); border-radius: var(--md-sys-shape-corner-medium);
  background: transparent;
}
.ds-foot p { margin: 0; font-size: var(--md-sys-typescale-body-medium-size, 14px); color: var(--md-sys-color-on-surface-variant); line-height: 1.6; }
.ds-foot b { color: var(--md-sys-color-on-surface-strong); font-weight: 650; }

/* ── État « posée » (base validée) ── */
.ds-state.is-done {
  border-style: solid; border-color: var(--md-sys-color-on-surface);
  color: var(--md-sys-color-on-surface); background: transparent;
}
/* ── État « à décider » (composant manquant, proposition à valider) ── */
.ds-state.is-todecide {
  border-style: solid; border-color: var(--md-sys-color-primary);
  color: var(--md-sys-color-primary); background: transparent;
}

/* ── Contenu d'une base : nuancier de couleurs ── */
.ds-source {
  margin: 0 0 18px; font-size: var(--md-sys-typescale-body-small-size, 12.5px); color: var(--md-sys-color-on-surface-faint);
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
}
.ds-swatches {
    display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
  gap: 18px 16px;
}
.ds-swatch { display: flex; flex-direction: column; gap: 4px; }
.ds-swatch-chip {
  height: 66px; border-radius: var(--md-sys-shape-corner-small);
  border: 1px solid rgba(24, 24, 27, .10);
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .04);
}
.ds-swatch-name { font-size: var(--md-sys-typescale-body-medium-size, 14px); font-weight: 650; margin-top: 2px; }
.ds-swatch-hex {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: var(--md-sys-typescale-label-medium-size, 12px); color: var(--md-sys-color-on-surface-variant);
}
.ds-swatch-role { font-size: var(--md-sys-typescale-label-medium-size, 12px); color: var(--md-sys-color-on-surface-faint); line-height: 1.35; }
.ds-note-derived { margin: 16px 0 0; font-size: var(--md-sys-typescale-label-medium-size, 12px); font-style: italic; color: var(--md-sys-color-on-surface-faint); max-width: 62ch; line-height: 1.5; }
.ds-note-derived b { color: var(--md-sys-color-on-surface-variant); font-style: normal; font-weight: 650; }

/* Section entière en mode sombre (base « Couleurs sombres ») */
.ds-sec--dark {
  --paper: #121214; --panel: #1b1c1e; --raised: #25272b;
  --ink: #fafafa; --ink-2: #c7ccd3; --muted: #9aa1a9; --faint: #8d939c;
  --line: #2a2c30; --line-2: #3a3d42;
  background: var(--md-sys-color-surface); border-color: var(--md-sys-color-outline-variant); color: var(--md-sys-color-on-surface);
}
.ds-sec--dark:hover { border-color: #3a3d42; box-shadow: none; }
.ds-sec--dark .ds-sec-head h2 { color: #fafafa; }
.ds-sec--dark .ds-sec-num { background: #fafafa; color: #121214; }
.ds-sec--dark .ds-sec-desc { color: #a7adb5; }
.ds-sec--dark .ds-source { color: #6f757d; }
.ds-sec--dark .ds-state { color: #c7ccd3; border-color: #3a3d42; }
.ds-sec--dark .ds-state.is-done { border-color: #7c828b; color: #eef1f4; }
.ds-sec--dark .ds-swatch-name { color: #fafafa; }
.ds-sec--dark .ds-swatch-hex { color: #9aa1a9; }
.ds-sec--dark .ds-swatch-role { color: #7c828b; }
.ds-sec--dark .ds-swatch-chip { border-color: rgba(255, 255, 255, .14); }
.ds-sec--dark .ds-note-derived { color: #7c828b; }
.ds-sec--dark .ds-note-derived b { color: #c7ccd3; }
/* Bouton d'aperçu clair / sombre, présent sur chaque carte */
.ds-theme-btn { flex: none; width: 30px; height: 30px; display: inline-flex; align-items: center; justify-content: center;
  border: 1px solid var(--md-sys-color-outline); background: var(--md-sys-color-surface-container-low); border-radius: var(--md-sys-shape-corner-small); color: var(--md-sys-color-on-surface-variant); cursor: pointer;
  transition: border-color .15s ease, color .15s ease; }
.ds-theme-btn:hover { border-color: var(--md-sys-color-on-surface); color: var(--md-sys-color-on-surface); }
.ds-sec--dark .ds-theme-btn { border-color: #3a3d42; background: #25272b; color: #c7ccd3; }
/* Carte générique : bouton Noir en clair, Blanc en sombre (visible sur fond sombre) */
.ex-card-btn-dark { display: none; }
.ds-sec--dark .ex-card-btn-light { display: none; }
.ds-sec--dark .ex-card-btn-dark { display: inline-flex; }

/* ── Contenu d'une base : échelle typographique ── */
.ds-type { display: flex; flex-direction: column; gap: 26px; }
.ds-type-row { display: flex; gap: 28px; align-items: baseline; flex-wrap: wrap; }
.ds-type-meta { flex: none; width: 178px; display: flex; flex-direction: column; gap: 3px; }
.ds-type-role { font-size: var(--md-sys-typescale-body-small-size, 12.5px); font-weight: 650; color: var(--md-sys-color-on-surface); }
.ds-type-specs {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: var(--md-sys-typescale-label-small-size, 11px); color: var(--md-sys-color-on-surface-variant); line-height: 1.45;
}
.ds-type-sample {
  margin: 0; flex: 1; min-width: 240px; color: var(--md-sys-color-on-surface);
  font-family: "Noto Sans", ui-sans-serif, -apple-system, sans-serif;
}

/* ── Contenu d'une base : échelle d'espacement ── */
.ds-scale { display: flex; flex-direction: column; gap: 11px; }
.ds-scale-row { display: flex; align-items: center; gap: 14px; }
.ds-scale-val {
  flex: none; width: 30px; text-align: right;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: var(--md-sys-typescale-label-medium-size, 12px); color: var(--md-sys-color-on-surface-variant);
}
.ds-scale-bar { flex: none; height: 14px; background: var(--md-sys-color-on-surface); border-radius: var(--md-sys-shape-corner-extra-small); }
.ds-scale-use { font-size: var(--md-sys-typescale-body-small-size, 12.5px); color: var(--md-sys-color-on-surface-faint); }

/* ── Contenu d'une base : layout / grille (specs + petit schéma) ── */
.ds-layout { display: flex; gap: 34px; flex-wrap: wrap; align-items: flex-start; }
.ds-layout-specs { margin: 0; flex: 1; min-width: 260px; display: flex; flex-direction: column; gap: 0; }
.ds-layout-row { display: flex; gap: 14px; justify-content: space-between; align-items: baseline;
  padding: 10px 0; border-bottom: 1px solid var(--md-sys-color-outline-variant); }
.ds-layout-row dt { margin: 0; font-size: var(--md-sys-typescale-body-medium-size, 14px); font-weight: 600; color: var(--md-sys-color-on-surface); }
.ds-layout-row dd { margin: 0; font-size: var(--md-sys-typescale-body-small-size, 12.5px); color: var(--md-sys-color-on-surface-variant); text-align: right; }
.ds-layout-schema {
  flex: none; width: 300px; height: 190px; background: var(--md-sys-color-surface);
  border: 1px solid var(--md-sys-color-outline); border-radius: var(--md-sys-shape-corner-small); overflow: hidden;
  display: flex; flex-direction: column;
}
.ds-schema-topbar { height: 26px; background: var(--chip); border-bottom: 1px solid var(--md-sys-color-outline-variant); }
.ds-schema-body { flex: 1; display: flex; }
.ds-schema-rail { width: 30px; background: var(--chip); border-right: 1px solid var(--md-sys-color-outline-variant); }
.ds-schema-content {
  flex: 1; padding: 12px; display: grid;
  grid-template-columns: repeat(4, 1fr); grid-auto-rows: 50px; gap: 8px;
}
.ds-schema-content span { background: var(--md-sys-color-outline-variant); border-radius: var(--md-sys-shape-corner-extra-small); }

/* ── Contenu d'une base : rayons (arrondis par rôle) ── */
.ds-radii { display: flex; gap: 22px 28px; flex-wrap: wrap; }
.ds-radius { display: flex; flex-direction: column; gap: 8px; width: 190px; }
.ds-radius-box { height: 72px; background: var(--chip); border: 1px solid var(--md-sys-color-outline); }
.ds-radius-box.is-pill { height: 44px; }
.ds-radius-val {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: var(--md-sys-typescale-label-medium-size, 12px); color: var(--md-sys-color-on-surface-variant);
}
.ds-radius-use { font-size: var(--md-sys-typescale-label-medium-size, 12px); color: var(--md-sys-color-on-surface-faint); line-height: 1.35; }

/* ── Contenu d'une base : iconographie ── */
.ds-iconspec { margin: -6px 0 18px; font-size: var(--md-sys-typescale-body-small-size, 12.5px); color: var(--md-sys-color-on-surface-variant); }
.ds-icons { display: grid; grid-template-columns: repeat(auto-fill, minmax(94px, 1fr)); gap: 10px; }
.ds-icon {
  display: flex; flex-direction: column; align-items: center; gap: 9px;
  padding: 15px 8px 10px; border: 1px solid var(--md-sys-color-outline-variant);
  border-radius: var(--md-sys-shape-corner-small); background: var(--md-sys-color-surface);
}
.ds-icon svg { color: var(--md-sys-color-on-surface); }
.ds-icon span {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: var(--md-sys-typescale-label-small-size, 11px); color: var(--md-sys-color-on-surface-faint); text-align: center; word-break: break-word;
}

/* ── Contenu d'une base : élévation (surfaces par couleur) ── */
.ds-elev { display: flex; gap: 32px; flex-wrap: wrap; align-items: flex-start; }
.ds-elev-demo { flex: none; width: 300px; border: 1px solid var(--md-sys-color-outline); border-radius: var(--md-sys-shape-corner-medium); padding: 16px; }
.ds-elev-card { border-radius: var(--md-sys-shape-corner-medium); padding: 16px; margin-top: 8px; border: 1px solid rgba(24, 24, 27, .05); }
.ds-elev-hl { border-radius: var(--md-sys-shape-corner-small); padding: 16px 14px; text-align: center; font-size: var(--md-sys-typescale-label-medium-size, 12px); color: var(--md-sys-color-on-surface-strong); }
.ds-elev-sep { height: 2px; border-radius: var(--md-sys-shape-corner-extra-small); margin-top: 12px; }
.ds-elev-tag { display: block; font-size: var(--md-sys-typescale-label-small-size, 11px); color: var(--md-sys-color-on-surface-variant); margin-bottom: 8px; }
.ds-elev-legend { flex: 1; min-width: 260px; }
.ds-elev-row { display: flex; align-items: center; gap: 12px; padding: 10px 0; border-bottom: 1px solid var(--md-sys-color-outline-variant); }
.ds-elev-chip { flex: none; width: 44px; height: 28px; border-radius: var(--md-sys-shape-corner-extra-small); border: 1px solid var(--md-sys-color-outline); }
.ds-elev-meta { flex: 1; display: flex; flex-direction: column; }
.ds-elev-meta b { font-size: var(--md-sys-typescale-body-medium-size, 14px); font-weight: 600; color: var(--md-sys-color-on-surface); }
.ds-elev-meta i { font-style: normal; font-size: var(--md-sys-typescale-label-medium-size, 12px); color: var(--md-sys-color-on-surface-variant); }
.ds-elev-hex { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: var(--md-sys-typescale-label-medium-size, 12px); color: var(--md-sys-color-on-surface-faint); }

/* ── Contenu d'une base : bordures & traits (1px) ── */
.ds-borders { }
.ds-border-demo { display: flex; gap: 28px; flex-wrap: wrap; align-items: flex-start; }
.ds-border-item { display: flex; flex-direction: column; gap: 8px; }
.ds-border-box {
  width: 190px; height: 78px; background: var(--md-sys-color-surface);
  border: 1px solid var(--md-sys-color-outline); border-radius: var(--md-sys-shape-corner-medium);
  display: flex; align-items: center; justify-content: center;
  font-size: var(--md-sys-typescale-body-small-size, 12.5px); color: var(--md-sys-color-on-surface-variant);
}
.ds-border-sep { width: 220px; height: 78px; display: flex; align-items: center; }
.ds-border-sep i { display: block; width: 100%; height: 1px; background: var(--md-sys-color-outline-variant); }
.ds-border-cap { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: var(--md-sys-typescale-label-medium-size, 12px); color: var(--md-sys-color-on-surface-faint); }
.ds-border-note { margin: 18px 0 0; font-size: var(--md-sys-typescale-body-small-size, 12.5px); color: var(--md-sys-color-on-surface-variant); max-width: 62ch; line-height: 1.5; }
.ds-border-note b { color: var(--md-sys-color-on-surface); font-weight: 650; }

/* ══ Propositions « À DÉCIDER » (migration Découvrir) : maquettes stylées au DS ══ */
/* 1) Bloc vedette / carrousel */
.feat { position: relative; aspect-ratio: 2.4 / 1; border-radius: var(--sp-shape-corner-large-fluid); overflow: hidden;
  display: flex; flex-direction: column; justify-content: flex-end; align-items: flex-start; }
.feat-bg { position: absolute; inset: 0; }
.feat-shade { position: absolute; inset: 0; background: linear-gradient(to top, rgba(0, 0, 0, .9) 4%, rgba(0, 0, 0, .25) 46%, transparent 78%); }
/* Rangée du haut (retour du porteur 26/09/2026) : un badge calé en haut à gauche (« Le plus vu »),
   un autre en haut à droite (nombre de réactions), à 24 px des bords comme le bas du bloc. */
.feat-top { position: relative; z-index: 1; align-self: stretch; display: flex; align-items: center; justify-content: space-between;
  gap: 8px; padding: 24px 24px 0; margin-bottom: auto; }
.feat-inner { position: relative; z-index: 1; align-self: stretch; padding: 24px; display: flex; flex-direction: column; gap: 8px; }
.feat-tag { align-self: flex-start; }
.feat-tags { display: flex; gap: 6px; flex-wrap: wrap; }
.feat-h { font: var(--md-sys-typescale-headline-medium); font-weight: 700; line-height: 1.12; margin: 0; color: #fff;}
.feat-h--lg { font: var(--md-sys-typescale-headline-large); }   /* bloc vedette de Découvrir : headline-large (30, gras) */
.feat-p { font: var(--md-sys-typescale-body-medium); margin: 0; color: rgba(255, 255, 255, .82); max-width: 46ch; }
.feat-foot { display: flex; align-items: center; gap: 16px; margin-top: 6px; flex-wrap: wrap; }
/* Variante « carte d'invitation » (Promo card, 29/09/2026, maquette du porteur : « Devenir
   créateur » à droite de Mon profil) : le bloc vedette en format carte, mêmes pièces (image,
   voile, titre, texte, bouton rose), texte EN HAUT sous un voile qui part du haut, bouton en
   bas à droite. */
.feat--promo { aspect-ratio: auto; min-height: 320px; justify-content: space-between; }
.feat--promo .feat-bg { background-size: cover; background-repeat: no-repeat; }
.feat--promo .feat-shade { background: linear-gradient(to bottom, rgba(0, 0, 0, .86) 0%, rgba(0, 0, 0, .55) 40%, rgba(0, 0, 0, .12) 70%, rgba(0, 0, 0, .3) 100%); }
.feat-act { position: relative; z-index: 1; align-self: stretch; display: flex; justify-content: flex-end; padding: 0 24px 24px; }
/* Pastilles du carrousel (retour du porteur 26/09/2026) : dans le pied du bloc, en bas à
   droite, calées sur le BAS du bouton (pas centrées sur lui) ; elles passent dessous,
   toujours à droite, si la place manque. Traits plats : boutons SANS la bordure en relief du navigateur ; blancs à 50 %
   sur l'image (lisibles en clair comme en sombre), l'actif en primary ; zone de clic
   agrandie au-delà des 5 px visibles. */
.feat-dots { display: flex; align-items: center; gap: 7px; margin-left: auto; align-self: flex-end; }
.feat-dot { position: relative; flex: none; width: 22px; height: 5px; padding: 0; border: 0; cursor: pointer;
  border-radius: var(--md-sys-shape-corner-full); background: rgba(255, 255, 255, .5); transition: background-color .15s ease; }
.feat-dot::after { content: ""; position: absolute; inset: -12px -3px; }
.feat-dot:hover { background: rgba(255, 255, 255, .8); }
.feat-dot.on { background: var(--md-sys-color-primary); }
.feat-dot:focus-visible { outline: 2px solid #fff; outline-offset: 3px; }
/* 2) Classement « Top React » */
.rlist { padding: 14px; border-radius: var(--md-sys-shape-corner-medium); background: var(--md-sys-color-surface); border: 1px solid var(--md-sys-color-outline-variant); }
.rlist-title { font: var(--md-sys-typescale-title-medium); font-weight: 700; color: var(--md-sys-color-on-surface); margin-bottom: 10px; }
.rlist-list { display: flex; flex-direction: column; gap: 4px; }
.rlist-item { display: flex; align-items: center; gap: 10px; padding: 6px; border-radius: var(--md-sys-shape-corner-small); }
.rlist-item:hover { background: var(--sp-hover-bg); }
.rlist-rank { font: var(--md-sys-typescale-title-small); font-weight: 700; flex: none; width: 22px; text-align: center; color: var(--md-sys-color-on-surface-faint); }
.rlist-meta { display: flex; flex-direction: column; min-width: 0; }
.rlist-name { font: var(--md-sys-typescale-label-large); font-weight: 600; display: inline-flex; align-items: center; gap: 4px; color: var(--md-sys-color-on-surface); }
.rlist-sub { font: var(--md-sys-typescale-body-small); color: var(--md-sys-color-on-surface-variant); }
/* 3) Carte créateur */
.ccards { display: flex; gap: 14px; flex-wrap: wrap; }
.ccard { display: flex; flex-direction: column; align-items: center; gap: 8px; text-align: center; width: 150px; padding: 20px 16px; border-radius: var(--md-sys-shape-corner-medium); background: var(--md-sys-color-surface); border: 1px solid var(--md-sys-color-outline); transition: border-color .15s ease, transform .15s ease; cursor: pointer; }
.ccard:hover { border-color: var(--md-sys-color-primary); transform: translateY(-2px); }
.ccard .ava { width: 56px; height: 56px; border-radius: var(--md-sys-shape-corner-large); font-size: 18px; }
.ccard-name { font: var(--md-sys-typescale-title-small); display: inline-flex; align-items: center; gap: 4px; color: var(--md-sys-color-on-surface); }
.ccard-sub { font: var(--md-sys-typescale-body-small); color: var(--md-sys-color-on-surface-variant); }
/* Pastille « vérifié » (check) */
.ic-verified { color: var(--md-sys-color-primary); flex: none; }

/* ══ Propositions « À DÉCIDER » : composants manquants (audit des pages app) ══ */
/* Wrappers de démo */
.ds-stack { display: flex; flex-direction: column; gap: 10px; }
.ds-row { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; }
/* Démo des compteurs (section Badge & tag) : un titre de section et des onglets sans filet. */
.ds-count-demo { margin: 0; font: var(--md-sys-typescale-title-large); font-weight: 700; }
/* Démo des titres (composant Title) : les quatre l'un sous l'autre, 12 px entre eux. */
.ds-titles-demo { display: flex; flex-direction: column; gap: 12px; padding: 20px 24px; border: 1px solid var(--md-sys-color-outline-variant); border-radius: var(--md-sys-shape-corner-large); background: var(--md-sys-color-surface); }
.ds-tabs-inline { display: inline-flex; border-bottom: 0; }

/* Carte de statistique */
.statc-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 14px; }
.statc { padding: 16px; border-radius: var(--md-sys-shape-corner-medium); background: var(--md-sys-color-surface); border: 1px solid var(--md-sys-color-outline); }
.statc-ic { display: inline-flex; color: var(--md-sys-color-primary); margin-bottom: 8px; }
.statc-val { font: var(--md-sys-typescale-headline-medium); font-weight: 700; line-height: 1; color: var(--md-sys-color-on-surface); font-variant-numeric: tabular-nums;}
.statc-lbl { font: var(--md-sys-typescale-body-small); color: var(--md-sys-color-on-surface-variant); margin-top: 4px; }
.statc-sub { font: var(--md-sys-typescale-label-small); color: var(--md-sys-color-on-surface-faint); margin-top: 3px; }
/* GRAND CHIFFRE (30/09/2026, à valider) : le chiffre vedette d'un bloc, un seul par bloc (Revenus du tableau de
   bord du Studio). display-small 34 / 700 (28 sur téléphone), on-surface, chiffres tabulaires. */
.bignum { font: var(--md-sys-typescale-display-small); color: var(--md-sys-color-on-surface); font-variant-numeric: tabular-nums; }

/* Message / alerte inline */
.alert { font: var(--md-sys-typescale-body-medium); display: flex; align-items: center; gap: 9px; padding: 11px 14px; border-radius: var(--md-sys-shape-corner-medium); }
.alert svg { flex: none; }
/* Bouton Fermer d'un message (.ibtn de 44 en dernier) : calé à droite, sans faire grandir le
   message, qui garde 44 de haut (marges négatives = le retrait du .alert). */
.alert > .ibtn { margin: -11px -8px -11px auto; }
.alert--ok { background: var(--md-sys-color-success-container); color: var(--md-sys-color-on-success-container); }
/* Erreur : la paire error-container / on-error-container, comme .ex-err et .errsum (audit du
   13/10/2026 : le rose sur rose à 14 % ne faisait que 2,9:1 ; 6,3:1 en clair, 5,4:1 en sombre). */
.alert--err { background: var(--md-sys-color-error-container); color: var(--md-sys-color-on-error-container); }
.alert--info { background: var(--md-sys-color-surface-container-high); color: var(--md-sys-color-on-surface-strong); }

/* Rangée de liste */

/* Bannière / couverture + avatars XL/XXL */
.banner { position: relative; aspect-ratio: 4 / 1; }
.banner-img { position: absolute; inset: 0; border-radius: var(--md-sys-shape-corner-large); }
.banner-ava { position: absolute; left: 24px; bottom: -24px; border: 3px solid var(--md-sys-color-surface); }
.banner-ava:has(> img) { background: var(--md-sys-color-surface); }
.banner-ava img { border-radius: calc(var(--md-sys-shape-corner-extra-large) - 3px); }
/* Sans image (refonte du Studio, À valider) : .banner.banner--empty, le .banner-img prend le fond
   surface-container-high et centre son icône Lucide « image ». */
.banner--empty .banner-img { display: grid; place-items: center; background: var(--md-sys-color-surface-container-high); color: var(--md-sys-color-on-surface-variant); }
.banner--empty .banner-img svg { flex: none; }
.ava--xl { width: 84px; height: 84px; border-radius: var(--md-sys-shape-corner-large); font-size: 26px; }
.ava--xxl { width: 112px; height: 112px; border-radius: var(--md-sys-shape-corner-extra-large); font-size: 34px; }

/* Cartes tarifaires */

/* Barre de progression */
.prog { height: 8px; border-radius: var(--md-sys-shape-corner-full); background: var(--md-sys-color-surface-container-high); overflow: hidden; }
.prog-bar { display: block; height: 100%; border-radius: var(--md-sys-shape-corner-full); background: var(--md-sys-color-primary); }
.prog-lbl { font: var(--md-sys-typescale-body-small); color: var(--md-sys-color-on-surface-variant); }

/* ── LANCEMENT DE CHAÎNE (« Ta chaîne est en préparation ») ─────────────
   Pattern partagé (shared/channel-launch.js), mis beaucoup plus en avant le
   25/09/2026 : bloc du menu du Studio (sous Paramètres), bandeau du tableau
   de bord, rappel en tête des pages du Studio, ligne du menu du compte.
   Fond primary-container, contour primary à 40 %, rayon 16, icône dans un
   rond primary. Une fois lancée : fond et contour success. */
.launch { display: flex; align-items: center; gap: 14px; box-sizing: border-box; width: 100%;
  border: 1px solid color-mix(in srgb, var(--md-sys-color-primary) 40%, transparent);
  border-radius: var(--md-sys-shape-corner-large);
  background: var(--md-sys-color-primary-container); color: var(--md-sys-color-on-primary-container); }
.launch[hidden] { display: none; }
.launch-ic { flex: none; display: inline-flex; align-items: center; justify-content: center; width: 44px; height: 44px;
  border-radius: var(--md-sys-shape-corner-medium);   /* carré arrondi, pas de rond à cette taille (porteur, 25/09) */ background: var(--md-sys-color-primary); color: var(--md-sys-color-on-primary); }
.launch-txt { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 4px; }
.launch-txt b { font: var(--md-sys-typescale-title-medium); color: var(--md-sys-color-on-surface); }
.launch-txt > span { font: var(--md-sys-typescale-body-small); line-height: 1.5; color: var(--md-sys-color-on-surface-variant); }
.launch-txt a { color: var(--md-sys-color-primary); }
.launch-actions { display: flex; flex-wrap: wrap; gap: 10px; flex: none; }
/* Bandeau du tableau de bord : large, marge 20, titre title-large. */
.launch--banner { padding: 20px; gap: 16px; }
.launch--banner .launch-ic { width: 52px; height: 52px; border-radius: var(--md-sys-shape-corner-large); }
.launch--banner .launch-txt b { font: var(--md-sys-typescale-title-large); font-weight: 700; }
/* Repli (refonte du Studio, À valider) : le bandeau est sa propre requête de conteneur. Le texte
   garde 240 px au moins, sinon les boutons passent dessous ; sous 560 px de bandeau, les actions
   prennent leur propre ligne en pleine largeur et l'icône, le texte et la croix éventuelle
   (.ibtn « Fermer », dernier enfant) restent sur la 1re : plus de titre à un mot par ligne. */
.launch--banner { container: launch / inline-size; flex-wrap: wrap; }
.launch--banner .launch-txt { flex: 1 1 240px; }
@container launch (max-width: 559px) {
  .launch--banner .launch-txt { flex-basis: 0; }
  .launch--banner .launch-actions { order: 3; flex: 1 1 100%; }
}
/* Bloc du menu du Studio : icône et titre côte à côte, texte dessous, bouton sur
   toute la largeur (compact, pour rester visible même sur un écran bas). */
.launch--rail { display: grid; grid-template-columns: auto minmax(0, 1fr); align-items: center; gap: 10px; padding: 12px; }
.launch--rail .launch-ic { width: 36px; height: 36px; border-radius: var(--md-sys-shape-corner-small); }
.launch--rail .launch-txt { display: contents; }
.launch--rail .launch-txt > span { grid-column: 1 / -1; }
.launch--rail .launch-actions { grid-column: 1 / -1; }
.launch--rail .launch-actions .cbtn { flex: 1 1 auto; }
/* Rappel discret en tête des autres pages du Studio : une ligne, lien à droite. */
.launch--notice { padding: 10px 14px; gap: 12px; border-radius: var(--md-sys-shape-corner-medium); margin-bottom: 20px; }
.launch--notice .launch-ic { width: 32px; height: 32px; border-radius: var(--md-sys-shape-corner-small); }
.launch--notice .launch-txt { flex-direction: row; flex-wrap: wrap; align-items: baseline; gap: 4px 8px; }
.launch--notice .launch-txt b { font: var(--md-sys-typescale-title-small); }
.launch-go.lnk { flex: none; background: none; border: 0; padding: 0; }
.launch.is-live { border-color: var(--md-sys-color-on-success-container); background: var(--md-sys-color-success-container); }
.launch.is-live .launch-ic { background: var(--md-sys-color-on-success-container); color: var(--md-sys-color-success-container); }
/* Lien d'adresse dans l'encart vert : le rose y tombait à 3,7:1 (audit du 13/10/2026). Texte
   du conteneur succès, souligné pour rester repérable comme lien (6,3:1 clair, 7,4:1 sombre). */
.launch.is-live .launch-txt a { color: var(--md-sys-color-on-success-container); text-decoration: underline; text-underline-offset: 3px; }
/* Menu du Studio : la liste défile (neuf entrées, séparateur centré, Paramètres) ;
   le bloc de lancement reste FIXE juste dessous, au-dessus du bouton de repli :
   toujours visible, même quand la liste doit défiler. */
.sbar--studio .sbar-scroll { display: flex; flex-direction: column; gap: 16px; }
.sbar--studio .sbar-sep { align-self: center; }
.sbar > .sbar-launch { flex: none; width: auto; margin: 8px 20px 0; }
.sbar-launch[hidden] { display: none; }
/* Rail replié : le bloc se réduit à son icône (carré de 44 centré). */
.sbar.is-collapsed > .sbar-launch { width: 44px; margin: 8px auto 0; padding: 4px; }
.sbar.is-collapsed .launch--rail .launch-txt, .sbar.is-collapsed .launch--rail .launch-actions { display: none; }
@media (max-width: 1000px) {
  .ds-app .sbar > .sbar-launch { width: 44px; margin: 8px auto 0; padding: 4px; }
  .ds-app .sbar .launch--rail .launch-txt, .ds-app .sbar .launch--rail .launch-actions { display: none; }
}
/* Ligne du menu du compte : l'étiquette « En préparation » part à droite, sans se couper. */
.launch-menuline .bdg { margin-left: auto; flex: none; white-space: nowrap; }

/* Logo du Studio : « SydePlay » suivi de « Studio » (retour du porteur 25/09/2026). */
.tbar-logo-studio { flex: none; margin-left: 8px; font: 600 20px/1 "Noto Sans", ui-sans-serif, sans-serif; letter-spacing: -0.01em; color: var(--md-sys-color-on-surface); }

/* ── GRAPHIQUES : courbe (.chart--line) et barres (.chart--bars) ─────────
   Validés par le porteur le 25/09/2026 pour le tableau de bord du Studio ;
   rendus par shared/charts.js (lineChart, barChart). Quatre graduations
   rondes à gauche (label-small, on-surface-variant), quatre dates en bas,
   filets horizontaux 1 px outline-variant. Courbe : ligne primary 2,5 px et
   zone dégradée (primary 28 % → transparent). Barres : primary, coins hauts
   arrondis 3, écart 3. Hauteur de la zone : 140 par défaut (--chart-h). */
.chart { display: grid; grid-template-columns: auto 1fr; grid-template-rows: var(--chart-h, 140px) auto; column-gap: 10px; row-gap: 8px; margin: 0; min-width: 0; }
.chart-y { display: flex; flex-direction: column; justify-content: space-between; text-align: right;
  font: var(--md-sys-typescale-label-small); color: var(--md-sys-color-on-surface-variant); }
.chart-y span { display: flex; align-items: center; justify-content: flex-end; height: 0; white-space: nowrap; }
.chart-plot { position: relative; min-width: 0; color: var(--md-sys-color-primary); }
.chart-grid { position: absolute; inset: 0; display: flex; flex-direction: column; justify-content: space-between; pointer-events: none; }
.chart-grid i { display: block; height: 1px; background: var(--md-sys-color-outline-variant); }
.chart-svg { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; }
.chart-bars { position: absolute; inset: 0; display: flex; align-items: flex-end; gap: 3px; padding: 0 2px; }
.chart-bars i { flex: 1 1 0; min-width: 2px; background: currentColor; border-radius: 3px 3px 0 0; }
.chart-x { grid-column: 2; display: flex; justify-content: space-between; gap: 8px;
  font: var(--md-sys-typescale-label-small); color: var(--md-sys-color-on-surface-variant); white-space: nowrap; }

/* Pastille numérotée */
.numpill { font: var(--md-sys-typescale-label-medium); font-weight: 700; display: inline-flex; align-items: center; justify-content: center; width: 24px; height: 24px; border-radius: var(--md-sys-shape-corner-small); background: var(--md-sys-color-surface-container-high); color: var(--md-sys-color-on-surface-strong); font-variant-numeric: tabular-nums; }
.numpill--on { background: var(--md-sys-color-primary); color: #fff; }

/* Bloc code */
.codeblock { display: inline-flex; align-items: center; gap: 8px; min-width: 260px; max-width: 340px; padding: 6px 6px 6px 14px; border-radius: var(--md-sys-shape-corner-medium); background: var(--md-sys-color-surface-container-high); }
.codeblock code { flex: 1; font-family: var(--sp-font-mono); font-size: var(--md-sys-typescale-body-medium-size, 14px); font-weight: 600; letter-spacing: .04em; color: var(--md-sys-color-on-surface); }

/* Accordéon / FAQ */
.accord-list { display: flex; flex-direction: column; }
.accord { border-bottom: 1px solid var(--md-sys-color-outline-variant); }
.accord-sum { font: var(--md-sys-typescale-title-small); display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 14px 2px; cursor: pointer; color: var(--md-sys-color-on-surface); list-style: none; }
.accord-sum::-webkit-details-marker { display: none; }
.accord-caret { transition: transform .2s ease; color: var(--md-sys-color-on-surface-variant); }
.accord[open] .accord-caret { transform: rotate(180deg); }
.accord-body { font: var(--md-sys-typescale-body-medium); line-height: 1.55; padding: 0 2px 14px; color: var(--md-sys-color-on-surface-variant);}
/* Variante « carte » : chaque question est une surface arrondie, séparée des
   autres, avec un bouton rond + qui pivote en × à l'ouverture. Utilisée par
   les FAQ des pages publiques (centre d'aide). */
.accord--carte { border-bottom: 0; background: var(--md-sys-color-surface-container-high); border-radius: var(--md-sys-shape-corner-medium); padding: 0 18px; }
.accord--carte + .accord--carte { margin-top: 10px; }
.accord--carte .accord-sum { padding: 16px 0; gap: 16px; }
.accord--carte .accord-body { padding: 0 0 16px; }
.accord-plus { display: grid; place-items: center; flex: none; width: 28px; height: 28px; border-radius: 50%;
  background: var(--md-sys-color-surface); color: var(--md-sys-color-on-surface); transition: transform .2s ease, background-color .15s ease, color .15s ease; }
.accord-plus svg { width: 16px; height: 16px; }
.accord--carte[open] .accord-plus { transform: rotate(45deg); background: var(--md-sys-color-primary); color: var(--md-sys-color-on-primary); }
.accord--carte:hover .accord-plus { background: var(--md-sys-color-primary); color: var(--md-sys-color-on-primary); }

/* Liste d'avis */

/* Tableau */
.dstable-wrap { overflow-x: auto; }
.dstable { font: var(--md-sys-typescale-body-medium); width: 100%; border-collapse: collapse; }
.dstable th, .dstable td { text-align: left; padding: 10px 12px; border-bottom: 1px solid var(--md-sys-color-outline-variant); white-space: nowrap; }
.dstable th { font: var(--md-sys-typescale-label-medium); font-weight: 600; color: var(--md-sys-color-on-surface-variant); }
.dstable td { color: var(--md-sys-color-on-surface); font-variant-numeric: tabular-nums; }
.dstable tbody tr:hover td { background: var(--sp-hover-bg); }
.dstable tbody tr:hover td:first-child { border-radius: var(--md-sys-shape-corner-small) 0 0 var(--md-sys-shape-corner-small); }
.dstable tbody tr:hover td:last-child { border-radius: 0 var(--md-sys-shape-corner-small) var(--md-sys-shape-corner-small) 0; }

/* Jauge / graphique */

/* ── Responsive ── */
@media (max-width: 640px) {
  .ds-hero h1 { font-size: 32px; }
  .ds-sec { padding: 20px 18px; }
}

/* ════════════════════════════════════════════════════════════════════
   ÉTATS DE GRILLE (2026-09-14, squelette retiré le 15/09) : « aucun contenu »
   ou « aucun résultat » = icône dans un rond gris + titre + phrase + bouton
   facultatif (25/09/2026 ; une petite illustration viendra plus tard).
   ════════════════════════════════════════════════════════════════════ */

.empty-state { display: flex; flex-direction: column; align-items: center; padding: 40px 20px 48px; text-align: center; }
/* Icône dans un rond gris (56, icône 24), comme l'état vide des notifications. */
.empty-ic { display: inline-flex; align-items: center; justify-content: center; width: 56px; height: 56px; margin-bottom: 16px;
  border-radius: var(--md-sys-shape-corner-full); background: var(--md-sys-color-surface-container-high); color: var(--md-sys-color-on-surface-variant); }
.empty-ic svg { width: 24px; height: 24px; }
.empty-title { font: var(--md-sys-typescale-headline-small); font-weight: 700; margin: 0; letter-spacing: -0.01em; color: var(--md-sys-color-on-surface); }
.empty-sub { font: var(--md-sys-typescale-body-medium); line-height: 1.5; margin: 8px 0 0; max-width: 380px; color: var(--md-sys-color-on-surface-variant);}
.empty-cta { margin-top: 18px; }

/* ── Zone CONSTRUCTIONS : inventaire d'un fonctionnement + nouvelle brique ── */
.cst-list { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 12px; max-width: 900px; }
.cst-row { padding: 16px; border-radius: var(--md-sys-shape-corner-medium); background: var(--md-sys-color-surface); border: 1px solid var(--md-sys-color-outline); display: flex; flex-direction: column; gap: 6px; }
.cst-row-head { display: flex; align-items: baseline; justify-content: space-between; gap: 8px; }
.cst-row-head b { font-size: var(--md-sys-typescale-body-medium-size, 14px); color: var(--md-sys-color-on-surface); }
.cst-size { font-size: var(--md-sys-typescale-label-medium-size, 12px); font-weight: 600; color: var(--md-sys-color-primary); }
.cst-what { font-size: var(--md-sys-typescale-body-small-size, 12.5px); line-height: 1.5; color: var(--md-sys-color-on-surface-variant); }
.cst-use { font-size: var(--md-sys-typescale-body-small-size, 12.5px); line-height: 1.45; color: var(--md-sys-color-on-surface-faint); }
.cst-row .lnk { margin-top: auto; }

/* Panel : démonstration dans la doc (composant défini section OVERLAYS). */
.ex-panel { width: 560px; }
.ex-panel-body .ex-row { margin-left: 0; }
.ex-panel-body .ex-search { width: 100%; }

/* Panneaux de la barre du haut montrés à plat dans la doc (ils sont sinon masqués). */
.ds-nav-static { max-width: 100%; }
.ds-nav-static .tbar-dd-panel { position: static; display: block; visibility: visible; opacity: 1; transform: none; right: auto; width: 300px; max-width: 100%; }
.ds-nav-static .tbar-notif { width: 360px; }
/* Dans l'app le menu du compte occupe toute la hauteur à droite : ici on le borne pour la doc. */
.ds-nav-static .tbar-account { width: 277px; height: auto; max-height: 560px; }
.ds-nav-static + .ds-group-sub { margin-top: 26px; }

/* Bandeaux du bas d'écran (cookies, inscription) : peau commune du DS. */
.ds-banner { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 14px;
  padding: 16px; border-radius: var(--md-sys-shape-corner-medium); background: var(--md-sys-color-surface); border: 1px solid var(--md-sys-color-outline-variant);
  box-shadow: var(--md-sys-elevation-level3); }
.ds-banner--demo { max-width: 560px; }
.ds-banner-txt { display: flex; align-items: flex-start; gap: 10px; flex: 1; min-width: 240px; font: var(--md-sys-typescale-body-medium); color: var(--md-sys-color-on-surface-variant); }
.ds-banner-txt b { color: var(--md-sys-color-on-surface); }
.ds-banner-txt svg { flex: none; color: var(--md-sys-color-primary); margin-top: 2px; }
.ds-banner-act { display: flex; align-items: center; gap: 8px; }
/* Bulle d'inscription (visiteur non connecté) : le titre seul sur sa ligne, la phrase dessous ;
   pas de croix, elle reste tant qu'on ne s'inscrit pas (retour du porteur du 29/09/2026). */
.ds-signup .ds-banner-txt > span { display: block; }
.ds-signup .ds-banner-txt b { display: block; margin-bottom: 2px; }
.ds-signup-sub { display: block; }


/* ════════════════════════════════════════════════════════════════════
   PATTERNS RAPATRIÉS (23/09/2026) — ils vivaient dans leurs propres
   fichiers, hors du design system. Règles déplacées telles quelles.
   ════════════════════════════════════════════════════════════════════ */

/* ── Locked content (ex shared/tier-lock.css) ── */
/* ── La pastille, posée sur la jaquette ── */
.ds-app .tlock-pill {
  position: absolute; left: 8px; bottom: 8px; z-index: 3;
  display: inline-flex; align-items: center; gap: 5px;
  padding: 5px 9px; border-radius: var(--md-sys-shape-corner-full);
  font-size: var(--md-sys-typescale-label-medium-size, 12px); font-weight: 700; line-height: 1;
  backdrop-filter: blur(6px);
  background: rgba(12, 12, 14, .78); color: #fff;
  border: 1px solid rgba(255, 255, 255, .14);
}
.ds-app .tlock-pill--reserve { background: color-mix(in srgb, var(--md-sys-color-primary) 88%, #000); border-color: transparent; }
.ds-app .tlock-pill svg { flex: none; }
/* Sur une carte, la pastille partage la rangée de la durée (.rcard-bottom) : une ligne,
   coupée par « … » (title complet), au-dessus de l'ombre basse. */
.ds-app .tlock-shade .rcard-bottom { z-index: 3; }
.ds-app .rcard-bottom .tlock-pill { position: static; min-width: 0; white-space: nowrap; }
.ds-app .rcard-bottom .tlock-pill > span { min-width: 0; overflow: hidden; text-overflow: ellipsis; }

/* La jaquette d'un contenu verrouillé reste NETTE et lisible : on montre ce
   qu'on vend. Seule une ombre basse assure la lisibilité de la pastille. */
.ds-app .tlock-shade::after {
  content: ""; position: absolute; inset: auto 0 0 0; height: 46%;
  background: linear-gradient(to top, rgba(0, 0, 0, .55), transparent);
  pointer-events: none; z-index: 2;
}

/* ── Le bloc argumenté (modale, carte de fil) ── */
.ds-app .tlock {
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
  padding: 14px; border-radius: var(--md-sys-shape-corner-medium);
  border: 1px solid var(--md-sys-color-outline); background: transparent;
}
.ds-app .tlock--reserve {
  border-color: color-mix(in srgb, var(--md-sys-color-primary) 34%, transparent);
  background: color-mix(in srgb, var(--md-sys-color-primary) 8%, transparent);
}
.ds-app .tlock-ic {
  flex: none; width: 38px; height: 38px; border-radius: var(--md-sys-shape-corner-small);
  display: grid; place-items: center;
  background: color-mix(in srgb, var(--md-sys-color-on-surface) 8%, transparent); color: var(--md-sys-color-on-surface-strong);
}
.ds-app .tlock--reserve .tlock-ic {
  background: color-mix(in srgb, var(--md-sys-color-primary) 16%, transparent); color: var(--md-sys-color-primary);
}
.ds-app .tlock-txt { flex: 1; min-width: 180px; display: flex; flex-direction: column; gap: 3px; }
.ds-app .tlock-t { font-size: var(--md-sys-typescale-title-medium-size, 15px); color: var(--md-sys-color-on-surface); }
.ds-app .tlock-s { font-size: var(--md-sys-typescale-body-small-size, 12.5px); color: var(--md-sys-color-on-surface-strong); line-height: 1.5; }
.ds-app .tlock-cta { flex: none; }

@media (max-width: 560px) {
  .ds-app .tlock-cta { width: 100%; justify-content: center; }
}

/* L'invitation d'un onglet réservé (FAQ…) est l'état vide du DS avec son bouton (tier-lock.js). */

/* ── View mode picker (ex shared/view-mode.css) ── */
.vmode { display: flex; gap: 12px; }
.vmode--cards { flex-wrap: wrap; }
.vmode--compact { gap: 8px; }

.vmode-opt, .thm {
  position: relative; display: flex; cursor: pointer; font-family: inherit; text-align: left;
  background: var(--md-sys-color-surface-container-high); border: 1.5px solid var(--md-sys-color-outline); border-radius: var(--md-sys-shape-corner-medium); color: var(--md-sys-color-on-surface);
  transition: border-color .15s ease, background .15s ease;
}
.vmode-opt:hover:not([disabled]), .thm:hover { border-color: var(--md-sys-color-on-surface-strong); }
.vmode-opt.on, .thm[aria-checked="true"] { border-color: var(--md-sys-color-primary); background: rgba(255, 54, 118, .06); }
.vmode-opt:focus-visible, .thm:focus-visible { outline: 2px solid var(--md-sys-color-primary); outline-offset: 2px; }

/* ── Variante CARTES (onboarding / réglages) ── */
.vmode--cards .vmode-opt { flex: 1; min-width: 158px; flex-direction: column; gap: 10px; padding: 16px 14px 46px; }
.vmode--cards .vmode-ic {
  width: 46px; height: 46px; border-radius: var(--md-sys-shape-corner-medium); display: flex; align-items: center; justify-content: center;
  background: var(--md-sys-color-surface); color: var(--md-sys-color-primary);
}
.vmode--cards .vmode-txt b { font: var(--md-sys-typescale-title-small); font-weight: 700; display: block; color: var(--md-sys-color-on-surface); }
/* La phrase est en on-surface-strong : on-surface-variant tombait à 4,05:1 sur le fond de l'option
   (surface-container-high) et à 4,38:1 sur l'option cochée, en clair (seuil AA : 4,5). Avec ce jeton :
   8,9:1 et 9,6:1 en clair, 9,3:1 et 10:1 en sombre (21/10/2026). */
.vmode--cards .vmode-txt i { font: var(--md-sys-typescale-body-small); line-height: 1.4; display: block; font-style: normal; color: var(--md-sys-color-on-surface-strong); margin-top: 3px;}
/* faux bouton radio en bas à gauche */
.vmode--cards .vmode-radio {
  position: absolute; left: 14px; bottom: 14px; width: 18px; height: 18px; border-radius: 50%;
  border: 2px solid var(--md-sys-color-outline); display: grid; place-items: center;
}
.vmode--cards .vmode-opt.on .vmode-radio, .thm[aria-checked="true"] .thm-radio { border-color: var(--md-sys-color-primary); }
.vmode--cards .vmode-opt.on .vmode-radio::after, .thm[aria-checked="true"] .thm-radio::after { content: ""; width: 8px; height: 8px; border-radius: 50%; background: var(--md-sys-color-primary); }

/* ── Variante COMPACTE (pop-up d'un react) : 3 icônes carrées ── */
.vmode--compact .vmode-opt { width: 44px; height: 44px; align-items: center; justify-content: center; }
.vmode--compact .vmode-ic { color: var(--md-sys-color-on-surface-variant); display: flex; }
.vmode--compact .vmode-opt.on .vmode-ic { color: var(--md-sys-color-primary); }

/* ── Mode « Bientôt » (split désactivé) ── */
.vmode-opt.soon { cursor: not-allowed; opacity: .55; }
.vmode-opt.soon:hover { border-color: var(--md-sys-color-outline); }
.vmode-soon { font: var(--md-sys-typescale-label-small); font-weight: 800; position: absolute; top: 10px; right: 10px; letter-spacing: .04em; text-transform: uppercase; color: var(--md-sys-color-on-surface-variant); background: var(--md-sys-color-surface); border: 1px solid var(--md-sys-color-outline); padding: 2px 7px; border-radius: var(--md-sys-shape-corner-full);
}
.vmode--compact .vmode-soon { top: -5px; right: -5px; padding: 1px 5px; font-size: var(--md-sys-typescale-label-small-size, 11px); }

@media (max-width: 560px) { .vmode--cards { flex-direction: column; } }

/* ── Variante LIGNES (.vmode--cards.vmode--rows, 21/10/2026, À valider) : la fenêtre « Comment veux-tu
   regarder ? » du lancement (dialog.js, variant "rows" de renderViewModeSelector). Trois cartes de 158 ne
   tiennent pas dans les 352 px d'une fenêtre de 400 : elles passent l'une sous l'autre, en lignes (icône 44
   à gauche, nom et phrase, rond de choix à droite). Même peau et même état choisi que les cartes. ── */
.vmode--rows { flex-direction: column; gap: 8px; }
.vmode--rows .vmode-opt { flex: none; flex-direction: row; align-items: center; gap: 12px; min-width: 0; padding: 12px 48px 12px 12px; }
.vmode--rows .vmode-ic { flex: none; width: 44px; height: 44px; }
.vmode--rows .vmode-txt { min-width: 0; }
.vmode--rows .vmode-radio { left: auto; right: 16px; bottom: auto; top: calc(50% - 9px); }

/* ── Fenêtre COMPACTE du lancement (.dlg--vmode + .vmode--tiles, choix du porteur 21/10/2026, À valider) :
   « Comment veux-tu regarder ? » petite, les trois modes en TUILES côte à côte, un fond en verre translucide
   NEUTRE et bien transparent (la surface à 56 %, flou 14 : le site se devine derrière) à peine teinté de rose dans un coin. Le rose est un accent, jamais un
   fond : la tuile cochée (teinte 14 %, contour rose, icône rose) et le bouton lecture rond. En bas (.vmode-go) :
   la phrase du mode coché, puis le bouton lecture rond, centrés ; la croix, Échap et le voile annulent. EXCEPTION À LA RÈGLE DU VOILE (décision du porteur, 21/10/2026) : cette fenêtre n'assombrit que
   légèrement le site (.dlg-ov--vmode, noir 38 %) au lieu du noir 70 % commun, pour que la page reste visible
   derrière le verre. Contrastes : texte on-surface sur le verre ≥ 11:1 en clair et en sombre ; blanc sur le
   bouton lecture 3,5:1 (icône, comme les boutons roses : choix connu du porteur). ── */
.dlg-ov.dlg-ov--vmode { background: rgba(0, 0, 0, .38); }
.dlg.dlg--vmode { max-width: 420px; padding: 18px 20px 20px;
  background:
    radial-gradient(120% 90% at 0% 0%, color-mix(in srgb, var(--md-sys-color-primary) 11%, transparent), transparent 60%),
    color-mix(in srgb, var(--md-sys-color-surface) 56%, transparent);
  -webkit-backdrop-filter: blur(14px) saturate(160%); backdrop-filter: blur(14px) saturate(160%);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--md-sys-color-on-surface) 12%, transparent), 0 24px 48px -16px rgba(0, 0, 0, .5); }
.dlg--vmode .ex-modal-head h4 { font: var(--md-sys-typescale-title-large); font-weight: 700; }
.dlg--vmode .ex-modal-head { margin-bottom: 4px; }
.dlg--vmode p { color: var(--md-sys-color-on-surface-strong); }
.dlg--vmode .dlg-field { margin-top: 12px; }
.dlg--vmode .ex-modal-foot { margin-top: 20px; }
.dlg--vmode .ex-modal-foot[hidden] { display: none; }   /* la fenêtre du choix n'a pas de pied : la lecture est sur la ligne du bas */
.vmode--tiles { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px; }
.vmode--tiles .vmode-opt { flex-direction: column; align-items: center; justify-content: flex-start; gap: 6px; min-width: 0; min-height: 88px;
  padding: 14px 8px 12px; text-align: center; border-radius: var(--md-sys-shape-corner-large);
  background: color-mix(in srgb, var(--md-sys-color-surface) 34%, transparent); border: 1px solid color-mix(in srgb, var(--md-sys-color-on-surface) 12%, transparent); }
.vmode--tiles .vmode-ic { display: grid; place-items: center; width: 32px; height: 32px; background: none; color: var(--md-sys-color-on-surface-strong); }
.vmode--tiles .vmode-txt { min-width: 0; }
.vmode--tiles .vmode-txt b { display: block; font: var(--md-sys-typescale-label-large); font-weight: 600; color: inherit; overflow-wrap: anywhere; }
.vmode--tiles .vmode-txt i { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
.vmode--tiles .vmode-opt:hover:not([disabled]) { background: color-mix(in srgb, var(--md-sys-color-on-surface) 10%, transparent); border-color: color-mix(in srgb, var(--md-sys-color-on-surface) 18%, transparent); }
.vmode--tiles .vmode-opt.on, .vmode--tiles .vmode-opt.on:hover { background: color-mix(in srgb, var(--md-sys-color-primary) 14%, transparent); border-color: var(--md-sys-color-primary);
  box-shadow: inset 0 0 0 1px var(--md-sys-color-primary); color: var(--md-sys-color-on-surface); }
.vmode--tiles .vmode-opt.on .vmode-ic { color: var(--sp-brand-ink, var(--md-sys-color-primary)); }
.vmode--tiles .vmode-opt:focus-visible { outline: 2px solid var(--md-sys-color-on-surface); outline-offset: 2px; }
.vmode--tiles .vmode-desc, .vmode-go .vmode-desc { margin: 0; min-height: 1.5em; font: var(--md-sys-typescale-body-small); color: var(--md-sys-color-on-surface-strong); }
.vmode--tiles .vmode-desc { grid-column: 1 / -1; margin-top: 4px; text-align: center; }
/* Le bas : la phrase du mode coché, puis la lecture, centrées. */
.vmode-go { display: flex; flex-direction: column; align-items: center; gap: 12px; margin-top: 12px; }
.vmode-go .vmode-desc { min-width: 0; text-align: center; }
.vmode-play { position: relative; flex: none; display: grid; place-items: center; width: 52px; height: 52px; padding: 0; border: 0; cursor: pointer;
  border-radius: var(--md-sys-shape-corner-full); background: var(--md-sys-color-primary); color: var(--md-sys-color-on-primary);
  box-shadow: 0 8px 18px -6px color-mix(in srgb, var(--md-sys-color-primary) 60%, transparent); transition: transform .18s cubic-bezier(.16, 1, .3, 1), box-shadow .18s ease; }
.vmode-play svg { width: 22px; height: 22px; margin-left: 3px; fill: currentColor; }
.vmode-play:active { transform: scale(.94); }
.vmode-play:focus-visible { outline: 2px solid var(--md-sys-color-on-surface); outline-offset: 3px; }
@media (hover: hover) and (pointer: fine) { .vmode-play:hover { transform: scale(1.06); box-shadow: 0 10px 22px -6px color-mix(in srgb, var(--md-sys-color-primary) 70%, transparent); } }
@media (prefers-reduced-motion: reduce) { .vmode-play, .vmode-play:hover, .vmode-play:active { transition: none; transform: none; } }
@media (max-width: 400px) { .vmode--tiles .vmode-txt b { font: var(--md-sys-typescale-label-medium); font-weight: 600; } }
@media (prefers-reduced-transparency: reduce) { .dlg.dlg--vmode { -webkit-backdrop-filter: none; backdrop-filter: none; background: var(--md-sys-color-surface); } }

/* ── Theme picker (Paramètres > Affichage) ──
   Créé le 28/09/2026 à la demande du porteur (sa référence « Appearance ») : trois cartes
   Système / Clair / Sombre, chacune avec un mini aperçu de l'appli (rail, barre du haut,
   bloc de contenu blanc ou sombre). Même peau que les cartes du mode d'affichage (.vmode-opt,
   règles communes plus haut) : fond surface-container-high, contour 1,5, rayon 12, anneau
   rose et fond rosé sur le choix, bouton radio. L'aperçu ne suit PAS le thème de la page :
   ses couleurs sont celles de chaque thème (mêmes valeurs que les jetons clair et sombre),
   « Système » montre les deux, coupés en biais. */
.thm-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 12px; }
.thm { flex-direction: column; gap: 12px; min-width: 0; padding: 10px 10px 12px; }
.thm-prev { position: relative; display: block; aspect-ratio: 16 / 10; overflow: hidden;
  border-radius: var(--md-sys-shape-corner-small); box-shadow: 0 0 0 1px var(--md-sys-color-outline-variant); }
.thm-scr { position: absolute; inset: 0; display: grid; grid-template-columns: 20% 1fr; grid-template-rows: 18% 1fr; background: var(--thm-bg); }
.thm-scr--light { --thm-bg: #F9FAFD; --thm-surf: #FFFFFF; --thm-fill: #E7EEF8; }
.thm-scr--dark { --thm-bg: #121214; --thm-surf: #1b1c1e; --thm-fill: #2a2c30; }
.thm-scr--cut { clip-path: polygon(62% 0, 100% 0, 100% 100%, 38% 100%); }
.thm-rail { grid-row: 1 / 3; display: flex; flex-direction: column; gap: 9%; padding: 55% 22% 0; }
.thm-rail i { display: block; height: 5px; border-radius: 3px; background: var(--thm-fill); }
.thm-rail i:first-child { background: #FF3676; }
.thm-bar { display: flex; align-items: center; justify-content: flex-end; gap: 4%; padding: 0 5%; }
.thm-bar i { display: block; width: 34%; height: 7px; margin-right: auto; border-radius: 4px; background: var(--thm-fill); }
.thm-bar b { display: block; width: 9px; height: 9px; border-radius: 3px; background: #FF3676; }
.thm-main { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); align-content: start; gap: 7%; margin: 0 5% 0 0; padding: 8%;
  border-radius: 6px 6px 0 0; background: var(--thm-surf); }
.thm-main i { display: block; aspect-ratio: 16 / 10; border-radius: 3px; background: var(--thm-fill); }
.thm-main i:first-child { grid-column: 1 / -1; aspect-ratio: 16 / 4; }
.thm-foot { display: flex; align-items: center; gap: 8px; font: var(--md-sys-typescale-title-small); font-weight: 700; color: var(--md-sys-color-on-surface); }
.thm-radio { flex: none; display: grid; place-items: center; width: 18px; height: 18px; box-sizing: border-box; border-radius: 50%;
  border: 2px solid var(--md-sys-color-outline); }

/* ── Image cropper (ex shared/image-cropper.css) ── */
.crp-back { z-index: 90; }   /* voile et fenêtre : règle commune des dialogues (OVERLAYS) */
body.crp-open { overflow: hidden; }   /* la page ne défile pas derrière l'overlay */

.crp-help { margin: 0 0 16px; }

/* Le CADRE = la destination réelle (16:9 par défaut).
   Tout ce qui déborde est masqué : ce qu'on voit est ce qu'on garde. */
.crp-stage { display: flex; justify-content: center; }
.crp-frame { position: relative; width: 100%; overflow: hidden; border-radius: var(--md-sys-shape-corner-medium);
  background: var(--md-sys-color-surface-container-high); cursor: grab; touch-action: none; user-select: none; }
.crp-frame.is-dragging { cursor: grabbing; }
.crp-img { position: absolute; max-width: none; opacity: 0; transition: opacity .15s ease; }
.crp-back.is-ready .crp-img { opacity: 1; }

/* Grille des tiers : repère de composition, purement visuel. */
.crp-grid { position: absolute; inset: 0; pointer-events: none; }
.crp-grid span { position: absolute; background: rgba(255, 255, 255, .22); }
.crp-grid span:nth-child(1) { left: 33.33%; top: 0; bottom: 0; width: 1px; }
.crp-grid span:nth-child(2) { left: 66.66%; top: 0; bottom: 0; width: 1px; }
.crp-grid span:nth-child(3) { top: 33.33%; left: 0; right: 0; height: 1px; }
.crp-grid span:nth-child(4) { top: 66.66%; left: 0; right: 0; height: 1px; }

/* Zoom : curseur encadré de deux boutons icône du DS. */
.crp-zoom { display: flex; align-items: center; gap: 8px; margin-top: 16px; }
.crp-range { flex: 1; min-width: 0; accent-color: var(--md-sys-color-primary); }

.crp-reset { margin-right: auto; }   /* action neutre à gauche, Annuler / Valider à droite (M3) ; placement uniquement */

@media (max-width: 560px) {
  .crp-actions .cbtn { flex: 1 1 100%; justify-content: center; }   /* placement uniquement */
}

/* ── Extension launch (ex pages/feed/feed-ds.css) ── */
/* Panneau extension : une CARTE d'accueil (demande du porteur, d'après la carte
   « Create with just your voice ») : visuel en haut, texte en bas, bouton en bas
   à droite. Aux couleurs du THÈME (clair / sombre), comme les autres panneaux. */
/* Le visuel est pleine largeur : il touche les bords du panneau et prend son arrondi (overflow hidden).
   Sélecteur renforcé : la règle commune .tbar-dd-panel { padding: 6px } l'emportait et laissait un cadre blanc (retour du porteur 29/09/2026). */
.tbar-dd-panel.tbar-ext-panel { width: 400px; max-width: 92vw; padding: 0; overflow: hidden; background: var(--md-sys-color-surface); border-color: var(--md-sys-color-outline); color: var(--md-sys-color-on-surface); border-radius: var(--md-sys-shape-corner-medium); }   /* aligné sur le rayon du DS (était 16) */
.tbar-ext-panel .tbar-dd-head { display: none; }
/* Panneau à deux onglets : « Extension » (regarder) et « SydePlay Atelier » (l'appli qui crée la seed).
   Le sélecteur en pastille est posé sur l'illustration ; l'illustration change de scène (la fenêtre du
   navigateur part à gauche, celle de l'appli arrive de droite), le fond passe du rose à l'ambre, le texte
   se fond. Les deux textes partagent la même case de grille : la hauteur ne saute pas. */
.tbar-ext-panel { --ext-ressort: cubic-bezier(.34, 1.56, .64, 1); --ext-sortie: cubic-bezier(.22, 1, .36, 1); }
.tbar-ext-visual { position: relative; height: 190px; overflow: hidden; isolation: isolate;
  background: radial-gradient(120% 90% at 20% 0%, #FF6A9A 0%, #FF3676 40%, color-mix(in srgb, #FF3676 45%, var(--md-sys-color-surface)) 80%, var(--md-sys-color-surface) 100%); }
.tbar-ext-fond { position: absolute; inset: 0; z-index: -1; opacity: 0;
  background: radial-gradient(120% 90% at 80% 0%, #FFC27A 0%, #FF8A5B 34%, #FF3676 62%, color-mix(in srgb, #FF3676 40%, var(--md-sys-color-surface)) 84%, var(--md-sys-color-surface) 100%); }
.tbar-ext-panel[data-onglet="atelier"] .tbar-ext-fond { opacity: 1; }
.tbar-ext-visual::before { content: ""; position: absolute; inset: 0; z-index: 0; background: repeating-linear-gradient(115deg, rgba(255, 255, 255, 0) 0 22px, rgba(255, 255, 255, .05) 22px 24px); }

/* Les deux scènes : la sortante file vers son côté, inclinée, en rapetissant. */
.tbar-ext-scene { position: absolute; inset: 0; z-index: 1; }
.tbar-ext-panel[data-onglet="atelier"] .tbar-ext-scene--ext { opacity: 0; transform: translateX(-72%) rotate(-7deg) scale(.88); }
.tbar-ext-panel:not([data-onglet="atelier"]) .tbar-ext-scene--atelier { opacity: 0; transform: translateX(72%) rotate(7deg) scale(.88); }

/* Scène « Extension » : l'illustration d'origine, inchangée (une fenêtre stylisée, avec la pièce de puzzle
   en haut à droite, là où vit l'extension). */
.tbar-ext-win { position: absolute; left: 44px; right: 44px; top: 44px; bottom: -10px; border-radius: var(--md-sys-shape-corner-medium) var(--md-sys-shape-corner-medium) 0 0; background: var(--md-sys-color-surface); box-shadow: 0 20px 50px -20px rgba(0, 0, 0, .45); }
.tbar-ext-win::before { content: ""; position: absolute; left: 14px; top: 12px; width: 10px; height: 10px; border-radius: 50%; background: #FF5F57; box-shadow: 18px 0 0 #FEBC2E, 36px 0 0 #28C840; }
.tbar-ext-win::after { content: ""; position: absolute; left: 0; right: 0; top: 34px; height: 1px; background: var(--md-sys-color-outline); }
.tbar-ext-puzzle { position: absolute; right: 14px; top: 6px; display: grid; place-items: center; width: 24px; height: 24px; border-radius: var(--md-sys-shape-corner-extra-small); background: var(--md-sys-color-on-surface); color: var(--md-sys-color-surface); }
.tbar-ext-puzzle svg { width: 14px; height: 14px; }

/* Scène « SydePlay Atelier » : la fenêtre sombre de l'appli, son timer qui défile et une seed prête. */
.tbar-ext-appwin { position: absolute; left: 44px; right: 44px; top: 44px; bottom: -10px; display: flex; flex-direction: column; align-items: center; gap: 12px; padding: 30px 16px 0;
  border-radius: 12px 12px 0 0; background: #0e0f11; border: 1px solid rgba(255, 255, 255, .1); box-shadow: 0 20px 50px -20px rgba(0, 0, 0, .55); }
.tbar-ext-appbar { position: absolute; top: 11px; right: 12px; display: flex; gap: 9px; }
.tbar-ext-appbar i { width: 9px; height: 2px; border-radius: 1px; background: rgba(255, 255, 255, .45); }
.tbar-ext-appbar i:nth-child(2) { height: 8px; width: 8px; background: none; border: 1.5px solid rgba(255, 255, 255, .45); margin-top: -3px; }
.tbar-ext-appbar i:nth-child(3) { position: relative; background: none; }
.tbar-ext-appbar i:nth-child(3)::before, .tbar-ext-appbar i:nth-child(3)::after { content: ""; position: absolute; left: 0; top: 0; width: 10px; height: 1.5px; background: rgba(255, 255, 255, .45); transform: rotate(45deg); }
.tbar-ext-appbar i:nth-child(3)::after { transform: rotate(-45deg); }
.tbar-ext-timer { padding: 6px 12px; border-radius: 8px; background: #000; color: #f4f4f4; font: 700 22px/1 "Cascadia Mono", Consolas, ui-monospace, monospace; font-variant-numeric: tabular-nums; letter-spacing: .02em; box-shadow: 0 0 0 1px rgba(255, 255, 255, .08); }
.tbar-ext-timer b { color: #FF3676; font-weight: 700; }
.tbar-ext-seed { display: inline-flex; align-items: center; gap: 6px; max-width: 100%; padding: 5px 10px 5px 7px; border-radius: 999px; background: rgba(95, 211, 154, .12); border: 1px solid rgba(95, 211, 154, .35); color: #5fd39a; font: 600 11px/1 "Cascadia Mono", Consolas, ui-monospace, monospace; }
.tbar-ext-seed span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: #c9f2dd; }
.tbar-ext-seed svg { width: 12px; height: 12px; flex: none; }
.tbar-ext-panel:not([data-onglet="atelier"]) .tbar-ext-seed { opacity: 0; transform: translateY(10px) scale(.9); }

/* Le sélecteur : au-dessus de l'illustration (qui reste celle d'origine), la pastille rose glisse sur
   l'onglet choisi. Largeur naturelle centrée : les deux colonnes restent égales, la pastille (une moitié) tombe pile. */
.tbar-ext-switch { position: relative; z-index: 2; width: max-content; margin: 12px auto; display: grid; grid-template-columns: 1fr 1fr; padding: 3px; border-radius: 999px;
  background: color-mix(in srgb, var(--md-sys-color-on-surface) 7%, transparent); border: 1px solid var(--md-sys-color-outline-variant); }
.tbar-ext-thumb { position: absolute; top: 3px; bottom: 3px; left: 3px; width: calc(50% - 3px); border-radius: 999px; background: #FF3676; box-shadow: 0 3px 12px -2px rgba(255, 54, 118, .45); }
.tbar-ext-panel[data-onglet="atelier"] .tbar-ext-thumb { transform: translateX(100%); }
.tbar-ext-switch [role="tab"] { position: relative; z-index: 1; display: inline-flex; align-items: center; justify-content: center; gap: 6px; min-height: 34px; padding: 0 14px; border: 0; border-radius: 999px; background: none; cursor: pointer;
  color: var(--md-sys-color-on-surface-variant); font: var(--md-sys-typescale-label-large); font-weight: 600; white-space: nowrap; }
.tbar-ext-switch [role="tab"] svg { width: 15px; height: 15px; flex: none; }
.tbar-ext-switch [role="tab"][aria-selected="true"] { color: #fff; }
.tbar-ext-switch [role="tab"]:not([aria-selected="true"]):hover { color: var(--md-sys-color-on-surface); }
.tbar-ext-switch [role="tab"]:focus-visible { outline: 2px solid var(--md-sys-color-primary); outline-offset: 2px; }

/* Les deux textes : le sortant quitte le flux (la hauteur suit le texte affiché, animée en JS) et se
   fond pendant que l'entrant arrive, un peu après. */
.tbar-ext-panes { position: relative; }
.tbar-ext-panes.is-anim { transition: height .45s var(--ext-sortie); }
.tbar-ext-pane:not(.is-on) { position: absolute; inset: 0 0 auto 0; visibility: hidden; opacity: 0; transform: translateY(6px); filter: blur(3px); pointer-events: none; }
.tbar-ext-pour { list-style: none; margin: 0 0 16px; padding: 0; display: grid; gap: 10px; }
.tbar-ext-pour li { display: grid; grid-template-columns: 32px minmax(0, 1fr); gap: 10px; align-items: start; }
.tbar-ext-pour li > svg { box-sizing: content-box; width: 16px; height: 16px; padding: 8px; border-radius: 10px; color: #FF3676; background: color-mix(in srgb, #FF3676 12%, transparent); }
.tbar-ext-pour b { display: block; font: var(--md-sys-typescale-label-large); font-weight: 700; color: var(--md-sys-color-on-surface); }
.tbar-ext-pour span { display: block; font: var(--md-sys-typescale-body-small); line-height: 1.45; color: var(--md-sys-color-on-surface-variant); }
.tbar-ext-meta { display: flex; align-items: center; gap: 6px; margin: 0 0 14px; font: var(--md-sys-typescale-body-small); color: var(--md-sys-color-on-surface-variant); }
.tbar-ext-meta svg { width: 14px; height: 14px; flex: none; }
.tbar-ext-erreur { margin: 10px 0 0; text-align: right; font: var(--md-sys-typescale-body-small); color: var(--md-sys-color-error, #FF7A59); }
.tbar-ext-dl { white-space: nowrap; }
/* « Bientôt disponible » : pas encore cliquable, mais lisible (l'opacité des boutons désactivés du DS l'effaçait). */
.tbar-ext-panel .tbar-ext-dl:disabled { opacity: 1; cursor: default; color: var(--md-sys-color-on-surface-variant); border-color: var(--md-sys-color-outline); background: transparent; }

@media (prefers-reduced-motion: no-preference) {
  .tbar-ext-panel:not(.sans-transition) :is(.tbar-ext-fond) { transition: opacity .5s ease; }
  .tbar-ext-panel:not(.sans-transition) .tbar-ext-scene { transition: transform .6s var(--ext-sortie), opacity .45s ease; }
  .tbar-ext-panel:not(.sans-transition) .tbar-ext-thumb { transition: transform .45s var(--ext-ressort); }
  .tbar-ext-panel:not(.sans-transition) .tbar-ext-switch [role="tab"] { transition: color .25s ease; }
  .tbar-ext-panel:not(.sans-transition) .tbar-ext-seed { transition: transform .45s var(--ext-ressort) .32s, opacity .3s ease .32s; }
  .tbar-ext-panel:not(.sans-transition):not([data-onglet="atelier"]) .tbar-ext-seed { transition-delay: 0s; }
  .tbar-ext-panel:not(.sans-transition) .tbar-ext-pane { transition: opacity .32s ease .1s, transform .42s var(--ext-sortie) .1s, filter .32s ease .1s, visibility 0s linear 0s; }
  .tbar-ext-panel:not(.sans-transition) .tbar-ext-pane:not(.is-on) { transition: opacity .18s ease, transform .2s ease, filter .18s ease, visibility 0s linear .2s; }
}
.tbar-ext-body { padding: 18px 20px 20px; }
.tbar-ext-title { font: var(--md-sys-typescale-headline-small); font-weight: 700; margin: 0 0 6px; letter-spacing: -0.01em; color: var(--md-sys-color-on-surface); }
.tbar-ext-st { font: var(--md-sys-typescale-body-medium); line-height: 1.5; margin: 0 0 14px; color: var(--md-sys-color-on-surface-variant);}
.tbar-ext-st b { color: var(--md-sys-color-on-surface); }
/* Un seul bouton, à droite, qui change avec l'état : Télécharger / Installer, Mettre à jour,
   Recharger (retour du porteur 25/09/2026 : plus de guide d'installation). */
.tbar-ext-actions { display: flex; align-items: center; justify-content: flex-end; gap: 12px; }
/* Placement seulement : forme, hauteur et typo = bouton du DS (.cbtn, rayon 12), jamais rond
   (retour du porteur 26/09/2026 : « on n'utilise pas de bouton rond »). */
.tbar-ext-dl { margin-left: auto; }

/* Étiquette de zone et jeton, dans la documentation de la typographie. */
.ds-type-zone { display: inline-block; margin-left: 8px; padding: 2px 8px; border-radius: var(--md-sys-shape-corner-full); font: var(--md-sys-typescale-label-small); vertical-align: middle; }
.ds-type-zone--mkt { background: var(--md-sys-color-primary-container); color: var(--md-sys-color-on-primary-container); }
.ds-type-zone--prod { background: #EAF7EE; color: #1F7A42; }
.ds-type-zone--both { background: var(--md-sys-color-surface-container-high); color: var(--md-sys-color-on-surface-variant); }
.ds-type-token { display: block; margin-top: 4px; font-family: Menlo, monospace; font-size: var(--md-sys-typescale-label-small-size, 11px); color: var(--md-sys-color-on-surface-faint); }

/* Les six niveaux d'ombre, dans la documentation de l'élévation. */
/* Les ombres se montrent sur le fond de page (comme dans le produit) : sans cette
   scène, le niveau 0 et, en sombre, tous les niveaux se fondaient dans la carte. */
.ds-shadows { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 18px; max-width: 900px;
  padding: 24px; border-radius: var(--md-sys-shape-corner-medium); background: var(--md-sys-color-surface-container-low); }
.ds-shadow { display: flex; flex-direction: column; gap: 4px; }
.ds-shadow-box { height: 64px; border-radius: var(--md-sys-shape-corner-medium); background: var(--md-sys-color-surface); margin-bottom: 8px; border: 1px solid var(--md-sys-color-outline-variant); }
.ds-shadow b { font: var(--md-sys-typescale-title-small); color: var(--md-sys-color-on-surface); }
.ds-shadow i { font-style: normal; font: var(--md-sys-typescale-body-small); color: var(--md-sys-color-on-surface-variant); }
.ds-radius code.ds-type-token { margin-top: 2px; }

/* ── ÉTATS · la couche Material 3 ────────────────────────────────────
   Un seul mécanisme pour tout ce qui se clique : une couche de la couleur
   du contenu, posée par-dessus, dont l'opacité change selon l'état.
   Usage : ajouter .state-layer au composant. */
.state-layer { position: relative; isolation: isolate; }
.state-layer::after {
  content: ""; position: absolute; inset: 0; border-radius: inherit;
  background: currentColor; opacity: 0; pointer-events: none;
  transition: opacity .15s ease;
}
.state-layer:hover::after { opacity: var(--md-sys-state-hover-opacity); }
.state-layer:focus-visible::after { opacity: var(--md-sys-state-focus-opacity); }
.state-layer:active::after { opacity: var(--md-sys-state-pressed-opacity); }
.state-layer[disabled], .state-layer[aria-disabled="true"] { opacity: var(--md-sys-state-disabled-opacity); pointer-events: none; }

/* Démonstration des états dans la documentation. */
.ds-states { display: grid; grid-template-columns: repeat(auto-fit, minmax(170px, 1fr)); gap: 16px; max-width: 900px; }
/* Cartes de la démo, scopées à .ds-states : sans ça, elles regonflaient la pastille d'état
   des sections (même nom de classe) à 51 de haut. */
.ds-states .ds-state { padding: 16px; border-radius: var(--md-sys-shape-corner-medium); background: var(--md-sys-color-surface); border: 1px solid var(--md-sys-color-outline-variant);
  font: inherit; text-transform: none; letter-spacing: normal; color: inherit; }
.ds-state-box { height: 52px; border-radius: var(--md-sys-shape-corner-medium); background: var(--md-sys-color-primary); position: relative; margin-bottom: 10px; }
.ds-state-box::after { content: ""; position: absolute; inset: 0; border-radius: inherit; background: #fff; }
.ds-states .ds-state b { display: block; font: var(--md-sys-typescale-title-small); color: var(--md-sys-color-on-surface); }
.ds-states .ds-state i { font-style: normal; font: var(--md-sys-typescale-body-small); color: var(--md-sys-color-on-surface-variant); }

/* ════════════════════════════════════════════════════════════════════
   OVERLAYS · DIALOG (Material 3) : la source UNIQUE de toutes les fenêtres
   du produit. Forme extra-large (rayon 28, retenue par le porteur le
   25/09/2026 : « les contours bien arrondis des fenêtres »), marges 24,
   hauteur qui suit le contenu, élévation niveau 3, largeur 280 à 560,
   titre headline-small (on-surface) collé au texte (8), texte d'appui
   body-medium (on-surface-variant), actions à 32 du texte, alignées à droite
   avec un écart de 8 ; voile noir à 70 %, sans flou (choix du porteur, au lieu du scrim
   M3 à 32 %).
   Écart assumé (jeton de composant surchargé, ce que M3 autorise) : le fond
   est la SURFACE (blanc / #1b1c1e) et non surface-container-high. Dans la
   palette SydePlay, la surface haute a la teinte des champs et des filets :
   ils disparaîtraient dans la fenêtre. Les fenêtres restent blanches, comme
   les cartes.
   Règle SydePlay en plus de M3 : la croix de fermeture est toujours à 12 px
   du haut et de la droite ; Échap et un clic sur le voile ferment aussi.
   Deux mises en page :
   (a) dialogue simple : tout le contenu dans les marges de 24 ;
   (b) en-tête fixe : titre + croix, séparateur, puis contenu qui défile
       (M3 prévoit le séparateur quand le contenu défile).
   Chaque fenêtre ne garde dans son propre fichier que sa largeur et sa mise
   en page interne. Seul écart de gabarit : la pop-up de réaction, dialogue
   média de 800 px, même rayon 28, même voile (reaction-modal-ds.css).
   ════════════════════════════════════════════════════════════════════ */

/* Voile */
.sp-auth-ov, .pwa-ov, .sat-overlay, .ds-app .ds-build-modal, .crp-back, .fw-modal-ov, .shr-ov, .stp-ov, .avm-ov, .srw-ov, .vcard-ov, .dlg-ov, .upd-ov {
  position: fixed; inset: 0; display: flex; align-items: center; justify-content: center; padding: 24px; }
/* Teinte du voile, la même pour TOUTES les fenêtres centrées, pop-up de réaction comprise
   (.modal-overlay, reaction-modal-ds.css) : noir à 70 %, SANS flou (décision du porteur
   26/09/2026, « comme YouTube » : le flou coûtait de la puissance aux appareils modestes ;
   le voile est plus foncé qu'avant, 60 %, pour compenser). Écart assumé avec M3 (scrim
   noir 32 %). */
.sp-auth-ov, .pwa-ov, .sat-overlay, .ds-app .ds-build-modal, .crp-back, .fw-modal-ov, .shr-ov, .stp-ov, .avm-ov, .srw-ov, .vcard-ov, .dlg-ov, .modal-overlay, .upd-ov {
  background: rgba(0, 0, 0, .7); }
.sp-auth-ov, .pwa-ov, .shr-ov, .stp-ov, .avm-ov, .srw-ov, .vcard-ov { z-index: 1000; }
/* La confirmation passe DEVANT toute autre fenêtre (elle est souvent ouverte depuis l'une d'elles). */
.dlg-ov { z-index: 1001; }
.pwa-ov { opacity: 0; transition: opacity .18s ease; }
.pwa-ov.is-on { opacity: 1; }

/* Conteneur */
.ex-modal, .ex-panel, .sp-auth, .pwa-modal, .sat-card, .ds-build-card, .crp, .fw-modal, .shr {
  position: relative; box-sizing: border-box; width: 100%; min-width: 280px; max-width: 560px;
  max-height: calc(100vh - 48px); overflow-y: auto; padding: 24px;
  background: var(--md-sys-color-surface); color: var(--md-sys-color-on-surface);
  border: 0; border-radius: var(--md-sys-shape-corner-extra-large); box-shadow: var(--md-sys-elevation-level3); }

/* Titre, texte d'appui, actions : le titre colle au texte (8), les actions s'en
   détachent (32) : on lit d'abord la question, puis on choisit. */
.ex-modal-head h4, .ex-panel-head b, .sp-auth-h, .pwa-head h2, .sat-title, .ds-build-head b, .crp-t, .fw-modal-head b, .shr-t {
  margin: 0; font: var(--md-sys-typescale-headline-small); letter-spacing: -.01em; color: var(--md-sys-color-on-surface); }
.ex-modal p, .sp-auth-sub, .pwa-intro, .sat-sub, .crp-help {
  font: var(--md-sys-typescale-body-medium); color: var(--md-sys-color-on-surface-variant); }
.ex-modal p { margin: 0; }
.ex-modal-foot, .crp-actions, .sat-actions { display: flex; flex-wrap: wrap; justify-content: flex-end; gap: 8px; margin-top: 32px; }

/* Croix : 12 px du haut et de la droite */
.sp-auth-x, .sat-close, .pwa-x { position: absolute; top: 12px; right: 12px; z-index: 2; }
/* (a) titre et croix sur une même ligne : la ligne remonte dans la marge. */
.ex-modal-head, .crp-head, .shr-head { display: flex; align-items: center; justify-content: space-between; gap: 16px; margin: -12px -12px 8px 0; }

/* (b) en-tête fixe + contenu qui défile */
.ex-panel, .ds-build-card, .fw-modal { display: flex; flex-direction: column; padding: 0; overflow: hidden; }
.ex-panel-head, .ds-build-head, .fw-modal-head { flex: none; display: flex; align-items: center; justify-content: space-between; gap: 16px;
  padding: 12px 12px 12px 24px; border-bottom: 1px solid var(--md-sys-color-outline-variant); }
.ex-panel-body, .ds-build-list { flex: 1; min-height: 0; overflow-y: auto; padding: 16px 24px 24px; }

/* Largeurs */
.ex-modal-wrap .ex-modal { width: 320px; }
/* ── Confirmation / information / saisie (shared/dialog.js) : LA boîte de dialogue du DS
   (.ex-modal) ouverte par le code, à la place des fenêtres grises du navigateur
   (décision du porteur du 29/09/2026). 400 px au plus, texte en paragraphes, champ optionnel. */
/* ── Pattern « Subscriptions list » (maquette Abonnements du 29/09/2026) : mise en page seulement ── */
.subs-list { display: flex; flex-direction: column; gap: 16px; }
.subs-list-head { display: flex; align-items: baseline; gap: 12px; }
.subs-list-count { font: var(--md-sys-typescale-body-medium); color: var(--md-sys-color-on-surface-variant); }
.subs-tbl td { white-space: normal; vertical-align: middle; padding: 12px; }
.subs-list .dstable-wrap { overflow: visible; }   /* le menu du bouton « Abonné » dépasse du tableau (il était rogné, retour du porteur 29/09) */
/* Le tableau déborde de 12 px de chaque côté : le contenu reste aligné sur le titre, et le
   survol (gris, rayon 8) laisse de l'air autour de l'avatar (retour du porteur 29/09/2026). */
.subs-list .subs-tbl { width: calc(100% + 24px); margin: 0 -12px; }
.subs-tbl tbody tr { cursor: pointer; }
.subs-chan-cell { display: flex; align-items: center; gap: 14px; min-width: 0; }
.subs-chan-cell .ava { flex: none; }
.subs-chan-txt { min-width: 0; }
.subs-chan-name { display: flex; align-items: center; gap: 6px; font: var(--md-sys-typescale-title-small); font-weight: 600; color: var(--md-sys-color-on-surface); }
.subs-chan-handle { font: var(--md-sys-typescale-body-small); font-weight: 400; color: var(--md-sys-color-on-surface-variant); }
.subs-chan-bio { margin-top: 2px; font: var(--md-sys-typescale-body-small); color: var(--md-sys-color-on-surface-variant); max-width: 520px;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.subs-col-abo { width: 150px; } .subs-col-tier { width: 220px; }
.subs-abo { position: relative; display: inline-block; }
.subs-abo .menu { position: absolute; top: calc(100% + 8px); left: 0; z-index: 5; }
.subs-abo--demo { display: flex; flex-direction: column; align-items: flex-start; gap: 8px; }
.subs-abo--demo .menu { position: static; }
.subs-tier-btn { max-width: 100%; }
.subs-tier-btn span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.subs-tier-end { margin-top: 6px; font: var(--md-sys-typescale-body-small); color: var(--md-sys-color-on-surface-variant); }
.subs-list--phone { width: 390px; max-width: 100%; padding: 16px; border: 1px solid var(--md-sys-color-outline-variant); border-radius: var(--md-sys-shape-corner-large); }
.subs-list--phone .subs-chan-bio { max-width: none; }
.subs-m-row { display: flex; flex-direction: column; gap: 12px; padding: 14px 0; border-bottom: 1px solid var(--md-sys-color-outline-variant); }
.subs-m-row:last-child { border-bottom: 0; }
.subs-m-acts { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.subs-chan-cell a.ava, .subs-chan-link { color: inherit; text-decoration: none; }
.subs-chan-link:hover { text-decoration: underline; }
.menu a[role="menuitem"] { color: inherit; text-decoration: none; }
/* Téléphone : le tableau devient une carte par chaîne (identité en haut, bouton à gauche, palier à droite). */
@media (max-width: 720px) {
  .subs-tbl, .subs-tbl tbody { display: block; }
  .subs-tbl thead { display: none; }
  .subs-tbl tr { display: grid; grid-template-columns: auto minmax(0, 1fr); gap: 12px 16px; align-items: center; padding: 14px 0; border-bottom: 1px solid var(--md-sys-color-outline-variant); }
  .subs-tbl td, .subs-tbl td:first-child { display: block; padding: 0; border: 0; }
  .subs-tbl td:first-child { grid-column: 1 / -1; }
  .subs-col-abo, .subs-col-tier { width: auto; min-width: 0; }
  .subs-col-tier { text-align: right; }
  .subs-chan-bio { max-width: none; }
  .subs-list .subs-tbl { width: 100%; margin: 0; }
  .subs-tbl tbody tr:hover td { background: none; }
}

.dlg { max-width: 400px; }
.dlg-body { display: flex; flex-direction: column; gap: 8px; }
.dlg-field { display: block; margin-top: 16px; }
.dlg-field .sr-only { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); }
.sp-auth { max-width: 420px; }
.pwa-modal { max-width: 448px; }
.shr { max-width: 560px; }

/* ── Fenêtre de mise à jour (Update dialog, 29/09/2026) ──
   Demande du porteur, inspirée de la fenêtre « Mises à jour des Conditions » de Claude :
   deux colonnes, le texte à gauche (titre, date, encadré « Qu'est-ce qui change ? » aux
   lignes séparées par un filet, liens, bouton pleine largeur), une illustration calme à
   droite (icônes Lucide sur la surface haute). Deux usages, un seul composant :
   (a) « Nouveautés » : croix, Échap et voile ferment, bouton « Compris » ;
   (b) « Mise à jour de nos conditions » : ni croix ni Échap, seul « Accepter » ferme.
   Même voile, même rayon 28 que toutes les fenêtres ; plus large (880) car deux colonnes,
   marges 32 (24 sur téléphone). Sur téléphone, l'illustration disparaît. */
.upd-ov { z-index: 1000; }
.upd { position: relative; box-sizing: border-box; display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 340px);
  width: 100%; max-width: 880px; max-height: calc(100vh - 48px); overflow: hidden;
  /* Une seule rangée, bornée à la hauteur de la fenêtre : sans elle, la rangée prend toute la hauteur du texte, la colonne
     de gauche ne défile jamais et « Accepter » reste hors de l'écran dès que le texte dépasse (retour terrain 15/10/2026). */
  grid-template-rows: minmax(0, 1fr);
  background: var(--md-sys-color-surface); color: var(--md-sys-color-on-surface);
  border-radius: var(--md-sys-shape-corner-extra-large); box-shadow: var(--md-sys-elevation-level3); }
.upd:focus { outline: none; }
.upd-main { display: flex; flex-direction: column; gap: 16px; min-width: 0; padding: 32px; overflow-y: auto; }
/* La colonne défile : ses blocs gardent leur hauteur au lieu de se tasser (sinon « Accepter » s'écrase). */
.upd-main > * { flex-shrink: 0; }
.upd-x { position: absolute; top: 12px; right: 12px; z-index: 1; }
.upd-head { display: flex; flex-direction: column; gap: 8px; padding-right: 32px; }
.upd-title { margin: 0; font: var(--md-sys-typescale-headline-small); color: var(--md-sys-color-on-surface); }
.upd-lead { margin: 0; font: var(--md-sys-typescale-body-medium); color: var(--md-sys-color-on-surface-variant); }
.upd-box { padding: 4px 16px; border-radius: var(--md-sys-shape-corner-large); background: var(--md-sys-color-surface-container-low);
  border: 1px solid var(--md-sys-color-outline-variant); }
.upd-box-h { padding: 12px 0 4px; font: var(--md-sys-typescale-title-small); color: var(--md-sys-color-on-surface); }
.upd-list { list-style: none; margin: 0; padding: 0; }
.upd-list li { display: grid; grid-template-columns: 20px minmax(0, 1fr); gap: 12px; padding: 12px 0; border-top: 1px solid var(--md-sys-color-outline-variant); }
.upd-list li:first-child { border-top: 0; }
.upd-list .upd-ic { display: flex; padding-top: 1px; color: var(--md-sys-color-on-surface-variant); }
.upd-list b { display: block; font: var(--md-sys-typescale-title-small); color: var(--md-sys-color-on-surface); }
.upd-list .upd-txt { display: block; margin-top: 2px; font: var(--md-sys-typescale-body-medium); color: var(--md-sys-color-on-surface-variant); }
.upd-links { display: flex; flex-wrap: wrap; gap: 4px 16px; margin: 0; font: var(--md-sys-typescale-body-medium); }
.upd .upd-links a { color: var(--md-sys-color-on-surface); text-decoration: underline; text-underline-offset: 3px; }
.upd .upd-links a:hover { color: var(--md-sys-color-primary); }
.upd-go { width: 100%; justify-content: center; }
.upd-foot { margin: -4px 0 0; text-align: center; font: var(--md-sys-typescale-body-small); color: var(--md-sys-color-on-surface-variant); }
.upd .upd-foot a { color: inherit; text-decoration: underline; text-underline-offset: 3px; }
/* Liens : .upd devant, sinon « .ds-app a » (feed-ds.css, chargée après) retire le soulignement. */
/* Illustration : une carte (icône principale) et trois pastilles autour, sur la surface haute. */
.upd-art { position: relative; display: grid; place-items: center; min-height: 100%; overflow: hidden;
  background: var(--md-sys-color-surface-container-high); }
.upd-art-card { display: grid; place-items: center; width: 152px; height: 152px; border-radius: var(--md-sys-shape-corner-extra-large);
  background: var(--md-sys-color-surface); box-shadow: var(--md-sys-elevation-level2); color: var(--md-sys-color-primary); }
.upd-art-dot { position: absolute; display: grid; place-items: center; width: 44px; height: 44px; border-radius: var(--md-sys-shape-corner-full);
  background: var(--md-sys-color-surface); box-shadow: var(--md-sys-elevation-level1); color: var(--md-sys-color-on-surface-variant); }
/* Pastilles placées autour de la carte, depuis le centre (pas en % de la colonne) : elles restent groupées quelle que soit
   la hauteur de la fenêtre. */
.upd-art-dot--1 { top: calc(50% - 128px); left: calc(50% - 118px); }
.upd-art-dot--2 { top: calc(50% - 70px); left: calc(50% + 84px); }
.upd-art-dot--3 { top: calc(50% + 84px); left: calc(50% - 74px); }
body.upd-open { overflow: hidden; }
@media (max-width: 760px) {
  .upd { grid-template-columns: minmax(0, 1fr); grid-template-rows: none; overflow-y: auto; }
  .upd-art { display: none; }
  .upd-main { padding: 24px; overflow: visible; }
}
/* Variante formulaire (29/09/2026, « Crée ta chaîne ») : l'encadré porte des cases à cocher,
   une par ligne, séparées par le même filet ; leurs liens sont soulignés comme .upd-links. */
.upd-checks { list-style: none; margin: 0; padding: 0; }
.upd-checks li { padding: 12px 0; border-top: 1px solid var(--md-sys-color-outline-variant);
  font: var(--md-sys-typescale-body-medium); color: var(--md-sys-color-on-surface); }
.upd-checks li:first-child { border-top: 0; }
.upd .upd-checks a { color: var(--md-sys-color-on-surface); text-decoration: underline; text-underline-offset: 3px; }
.upd .upd-checks a:hover { color: var(--md-sys-color-primary); }
.upd .upd-checks a + a { margin-left: 8px; }

/* ── Bloc inversé (.sblk--inverse), 29/09/2026 ─────────────────────────────
   Page « Devenir créateur » (structure D choisie par le porteur) : le panneau « Ce à quoi
   tu t'engages » en surface inverse (noir de marque en thème clair, blanc en thème sombre),
   à côté d'un bloc normal. Même forme, mêmes marges que .sblk ; seules les couleurs
   s'inversent (titres, textes, filets, tuiles d'icône). */
.sblk.sblk--inverse { background: var(--md-sys-color-inverse-surface); color: var(--md-sys-color-inverse-on-surface); border-color: transparent; }
.sblk--inverse .sblk-head h3, .sblk--inverse .stp-row-name { color: inherit; }
.sblk--inverse .sblk-head p, .sblk--inverse .stp-row-sub, .sblk--inverse .sblk-note { color: color-mix(in srgb, currentColor 78%, transparent); }
.sblk--inverse .stp-row + .stp-row, .sblk--inverse .sblk-head { border-color: color-mix(in srgb, currentColor 16%, transparent); }
.sblk--inverse .srub-ic { background: color-mix(in srgb, currentColor 12%, transparent); color: inherit; }

/* ── Curseur (.ex-range), 29/09/2026 ───────────────────────────────────────
   Le Slider de M3 : piste de 4, partie active rose, poignée ronde de 20 dans une zone de
   44 de haut (règle des 44). La part remplie vient de --val (0 à 100 %), posée par le
   script à chaque mouvement. Libellé et valeur au-dessus (.ex-range-top). */
.ex-range { -webkit-appearance: none; appearance: none; display: block; width: 100%; height: 44px; margin: 0;
  background: transparent; cursor: pointer; --val: 50%; }
.ex-range:focus { outline: none; }
.ex-field input.ex-range { height: 44px; padding: 0; background: transparent; border: 0; border-radius: 0; }   /* pas la peau des champs */
.ex-range::-webkit-slider-runnable-track { height: 4px; border-radius: var(--md-sys-shape-corner-full);
  background: linear-gradient(to right, var(--md-sys-color-primary) var(--val), var(--md-sys-color-surface-container-highest) var(--val)); }
.ex-range::-moz-range-track { height: 4px; border-radius: var(--md-sys-shape-corner-full); background: var(--md-sys-color-surface-container-highest); }
.ex-range::-moz-range-progress { height: 4px; border-radius: var(--md-sys-shape-corner-full); background: var(--md-sys-color-primary); }
.ex-range::-webkit-slider-thumb { -webkit-appearance: none; appearance: none; width: 20px; height: 20px; margin-top: -8px;
  border: 0; border-radius: 50%; background: var(--md-sys-color-primary); box-shadow: var(--md-sys-elevation-level1); }
.ex-range::-moz-range-thumb { width: 20px; height: 20px; border: 0; border-radius: 50%; background: var(--md-sys-color-primary); box-shadow: var(--md-sys-elevation-level1); }
.ex-range:focus-visible::-webkit-slider-thumb { outline: 3px solid var(--md-sys-color-primary); outline-offset: 2px; }
.ex-range:focus-visible::-moz-range-thumb { outline: 3px solid var(--md-sys-color-primary); outline-offset: 2px; }
.ex-range-top { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; }
.ex-range-val { font: var(--md-sys-typescale-title-medium); font-weight: 600; color: var(--md-sys-color-on-surface); font-variant-numeric: tabular-nums; }

/* ── Partager (shared/reaction-ui.js, tous les boutons « Partager ») ──
   Mise en page de la référence du porteur (26/09/2026, « Share this article ») dans la
   fenêtre du DS : le titre, puis directement une rangée de réseaux (icône du cadre Figma
   « Icon Partage » au-dessus du nom), puis le lien dans un champ du DS avec l'icône
   « copier » au bout (bouton de fin du champ, .ex-affix). Icônes en 64 px : exception à
   la règle des 44 px demandée par le porteur (logos des réseaux, pas des boutons du DS),
   après le retrait de WhatsApp et E-mail. Tous les réseaux sur une ligne ; sur un écran
   étroit, trois colonnes (le nom « Messenger » ne tiendrait pas dans cinq). */
body.shr-open { overflow: hidden; }   /* la page ne défile pas derrière la fenêtre */
.shr:focus { outline: none; }   /* focus posé sur la fenêtre à l'ouverture, sans anneau */
.shr-nets { display: grid; grid-auto-flow: column; grid-auto-columns: minmax(0, 1fr); gap: 16px 8px; margin-top: 16px; }
@media (max-width: 560px) { .shr-nets { grid-auto-flow: row; grid-template-columns: repeat(3, minmax(0, 1fr)); } }
.shr-tgt { position: relative; isolation: isolate; display: flex; flex-direction: column; align-items: center; gap: 8px;
  min-width: 0; padding: 8px 0; border: 0; background: none; cursor: pointer; text-decoration: none;
  border-radius: var(--md-sys-shape-corner-medium); color: var(--md-sys-color-on-surface-variant);
  font: var(--md-sys-typescale-label-medium); }
.shr-tgt img { width: 64px; height: 64px; flex: none; }
.shr-tgt span { max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* Couche d'état du DS (8 % au survol, 10 % au focus et à l'appui) et anneau de focus. */
.shr-tgt::after { content: ""; position: absolute; inset: 0; border-radius: inherit; background: currentColor;
  opacity: 0; pointer-events: none; transition: opacity .15s ease; }
.shr-tgt:hover::after { opacity: var(--md-sys-state-hover-opacity); }
.shr-tgt:focus-visible::after, .shr-tgt:active::after { opacity: var(--md-sys-state-focus-opacity); }
.shr-tgt:focus-visible { outline: 3px solid var(--md-sys-color-primary); outline-offset: 2px; }
.shr-link { margin-top: 24px; }

/* ── Paramètres de la chaîne (shared/studio-settings.js, « Paramètres » du menu du Studio) ──
   Pattern « Settings dialog », maquettes validées par le porteur le 27/09/2026. Fenêtre
   à en-tête fixe du DS (.ex-panel) : titre et croix, onglets (.ex-tabs), contenu qui
   défile, pied fixe Annuler / Enregistrer. Interrupteurs au BOUT de la ligne, texte à
   gauche, comme la page des paramètres du compte (retour du porteur : placés en début
   de ligne, ils paraissaient énormes sur téléphone). La confirmation « Quitter sans
   enregistrer ? » est la boîte de dialogue du DS (.ex-modal), posée au-dessus.
   Placement seulement : les composants viennent du DS. */
body.stp-open { overflow: hidden; }   /* la page ne défile pas derrière la fenêtre */
.stp { max-width: 560px; max-height: calc(100dvh - 48px); }
.stp:focus { outline: none; }
.stp .ex-panel-head { border-bottom: 0; }
.stp .ex-tabs { flex: none; padding: 0 12px; }
.stp .ex-panel-body { padding-top: 20px; }
.stp-tab { display: flex; flex-direction: column; gap: 22px; }
.stp-tab[hidden] { display: none; }
.stp-intro { margin: 0; font: var(--md-sys-typescale-body-medium); color: var(--md-sys-color-on-surface-variant); }
.stp-sec { display: flex; flex-direction: column; gap: 8px; }
.stp-sec > .lnk { align-self: flex-start; }
.stp-help { margin: 0; font: var(--md-sys-typescale-body-small); color: var(--md-sys-color-on-surface-variant); }
.stp-rows { display: flex; flex-direction: column; }
.stp-row { display: flex; align-items: center; gap: 16px; padding: 12px 0; }
.stp-row + .stp-row { border-top: 1px solid var(--md-sys-color-outline-variant); }
.stp-row-txt { flex: 1; min-width: 0; }
.stp-row-name { margin: 0; font: var(--md-sys-typescale-title-small); color: var(--md-sys-color-on-surface); }   /* margin : un <p> n'apporte pas ses marges (refonte du Studio) */
.stp-row-sub { margin: 3px 0 0; font: var(--md-sys-typescale-body-small); color: var(--md-sys-color-on-surface-variant); }
.stp-row > .ex-toggle { flex: none; }
.stp-infos { display: flex; flex-direction: column; border-top: 1px solid var(--md-sys-color-outline-variant); }
.stp-info { display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; gap: 2px 16px;
  padding: 12px 0; border-bottom: 1px solid var(--md-sys-color-outline-variant); }
.stp-info b { font: var(--md-sys-typescale-label-large); color: var(--md-sys-color-on-surface); }
.stp-info > span { margin-left: auto; font: var(--md-sys-typescale-body-medium); color: var(--md-sys-color-on-surface-variant); text-align: right; }
.stp-danger .ex-lbl { color: var(--md-sys-color-error); }
.stp-foot { flex: none; display: flex; justify-content: flex-end; gap: 8px; padding: 16px 24px;
  border-top: 1px solid var(--md-sys-color-outline-variant); }
.stp-conf { max-width: 360px; }

/* ── Paramètres du compte (pages/settings/, « Paramètres » du menu du compte) ──
   Pattern « Account settings », d'après les réponses du porteur du 28/09/2026 (sa
   référence de blocs « Personal information / Change password / Preferences ») :
   1. la page : un titre, puis une grille de cartes de rubrique (.srub) sur toute la
      largeur des marges : icône Lucide noire ou blanche dans sa tuile de 44, nom,
      phrase, chevron ;
   2. une rubrique s'ouvre dans une fenêtre centrée (.srw, le panneau à en-tête fixe du
      DS, voile commun) : titre et croix, puis des blocs qui défilent. Une seule fenêtre
      à la fois : une action qui a besoin de place (Mes commentaires, Supprimer mon compte,
      Créer mon avatar) remplace le contenu de la fenêtre, avec une flèche de retour à
      gauche du titre ;
   3. un bloc (.sblk) : un titre (et une phrase), un filet, puis son contenu (champs du DS,
      lignes de réglage .stp-row de la fenêtre des paramètres de la chaîne, tableau) ;
   4. sur téléphone (proposition du porteur à valider), la fenêtre prend tout l'écran,
      comme le prévoit Material 3 pour les longues fenêtres de réglages.
   Placement seulement : les champs, boutons, lignes et tableaux viennent du DS. */
.srub-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); gap: 16px; }
.srub { position: relative; isolation: isolate; display: flex; flex-direction: column; align-items: flex-start; gap: 14px; min-width: 0;
  padding: 20px; box-sizing: border-box; text-align: left; cursor: pointer; font-family: inherit;
  background: var(--md-sys-color-surface); color: var(--md-sys-color-on-surface);
  border: 1px solid var(--md-sys-color-outline-variant); border-radius: var(--md-sys-shape-corner-large); }
.srub::after { content: ""; position: absolute; inset: 0; border-radius: inherit; background: currentColor;
  opacity: 0; pointer-events: none; transition: opacity .15s ease; }
.srub:hover::after { opacity: var(--md-sys-state-hover-opacity); }
.srub:focus-visible::after, .srub:active::after { opacity: var(--md-sys-state-focus-opacity); }
.srub:focus-visible { outline: 3px solid var(--md-sys-color-primary); outline-offset: 2px; }
.srub-ic { display: grid; place-items: center; width: 44px; height: 44px; flex: none;
  border-radius: var(--md-sys-shape-corner-medium); background: var(--md-sys-color-surface-container-high); color: var(--md-sys-color-on-surface); }
/* Tuile d'icône en bouton (refonte du Studio, À valider : icône d'un palier qu'on change) :
   button.srub-ic.srub-ic--btn, sans habillage de bouton, couche d'état, anneau de focus ; une image
   (icône importée) la remplit. */
.srub-ic--btn { position: relative; isolation: isolate; overflow: hidden; padding: 0; border: 0; font: inherit; cursor: pointer; }
.srub-ic--btn::after { content: ""; position: absolute; inset: 0; border-radius: inherit; background: currentColor; opacity: 0; pointer-events: none; transition: opacity .15s ease; }
.srub-ic--btn:hover::after { opacity: var(--md-sys-state-hover-opacity); }
.srub-ic--btn:active::after { opacity: var(--md-sys-state-pressed-opacity); }
.srub-ic--btn:focus-visible { outline: 3px solid var(--md-sys-color-primary); outline-offset: 2px; }
.srub-ic--btn > img { display: block; width: 100%; height: 100%; object-fit: cover; }
.srub-ic--btn:disabled { opacity: var(--md-sys-state-disabled-opacity); cursor: not-allowed; }
.srub-ic--btn:disabled::after { opacity: 0; }
.srub-go { position: absolute; top: 30px; right: 16px; display: flex; color: var(--md-sys-color-on-surface-variant); }
.srub-name { display: block; font: var(--md-sys-typescale-title-medium); font-weight: 600; }
.srub-sub { display: block; margin-top: 4px; font: var(--md-sys-typescale-body-small); color: var(--md-sys-color-on-surface-variant); }
/* Téléphone : une rubrique par ligne, l'icône à gauche du texte, le chevron au bout. */
@media (max-width: 560px) {
  .srub-grid { gap: 8px; }
  .srub { flex-direction: row; align-items: center; gap: 16px; padding: 12px 16px; }
  .srub-go { position: static; margin-left: auto; }
}

body.srw-open { overflow: hidden; }   /* la page ne défile pas derrière la fenêtre */
.srw { max-width: 720px; max-height: calc(100dvh - 48px); }
.srw:focus { outline: none; }
.srw .ex-panel-head { min-height: 68px; box-sizing: border-box; }
.srw-head--sub { padding-left: 12px; }
.srw-title { display: flex; align-items: center; gap: 8px; min-width: 0; }
.srw-title b { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.srw .ex-panel-body { display: flex; flex-direction: column; gap: 16px; padding: 24px; }
/* Dans une fenêtre de rubrique, les blocs n'ont PAS de trait entre le titre et le contenu (retour du porteur 29/09/2026 : « de trop, ça alourdit »). */
.srw .sblk-head { border-bottom: 0; padding-bottom: 2px; }
.srw-intro { margin: 0; font: var(--md-sys-typescale-body-medium); color: var(--md-sys-color-on-surface-variant); }
@media (max-width: 600px) {
  .srw-ov { padding: 0; }
  .srw { max-width: none; height: 100dvh; max-height: none; border-radius: 0; box-shadow: none; }
  .srw .ex-panel-body { padding: 16px; }
}

.sblk { min-width: 0; background: var(--md-sys-color-surface);
  border: 1px solid var(--md-sys-color-outline-variant); border-radius: var(--md-sys-shape-corner-large); }
.sblk-head { display: flex; align-items: center; justify-content: space-between; gap: 12px 16px; flex-wrap: wrap;
  padding: 14px 20px; border-bottom: 1px solid var(--md-sys-color-outline-variant); }
.sblk-head h3 { margin: 0; font: var(--md-sys-typescale-title-medium); font-weight: 600; color: var(--md-sys-color-on-surface); }
.sblk-head p { margin: 2px 0 0; font: var(--md-sys-typescale-body-small); color: var(--md-sys-color-on-surface-variant); }
.sblk--danger .sblk-head h3 { color: var(--md-sys-color-error); }
.sblk-body { display: flex; flex-direction: column; gap: 16px; padding: 16px 20px 20px; }
.sblk-body--rows { gap: 0; padding-top: 0; padding-bottom: 0; }   /* lignes .stp-row : elles portent leurs marges */
.sblk-body--flush { padding: 0; }                                  /* tableau : il va d'un bord à l'autre */
.sblk-body--flush .dstable th:first-child, .sblk-body--flush .dstable td:first-child { padding-left: 20px; }
.sblk-body--flush .dstable th:last-child, .sblk-body--flush .dstable td:last-child { padding-right: 20px; }
.sblk-body--flush .dstable tr:last-child td { border-bottom: 0; }
.sblk-two { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 16px; }
.sblk-acts { display: flex; flex-wrap: wrap; justify-content: flex-end; align-items: center; gap: 8px; }
.sblk-acts--start { justify-content: flex-start; }
.sblk-body--rows > .sblk-acts { padding: 12px 0 16px; }
.sblk-body--rows > .sblk-acts:first-child { padding-top: 16px; }
.sblk-note { margin: 0; font: var(--md-sys-typescale-body-small); color: var(--md-sys-color-on-surface-variant); }
.sblk-empty { margin: 0; padding: 16px 0; font: var(--md-sys-typescale-body-medium); color: var(--md-sys-color-on-surface-variant); }
.sblk .stp-row > .ava, .sblk .stp-row > .plat, .sblk .stp-row > .srub-ic { flex: none; }
.sblk .stp-row-name .bdg { margin-left: 6px; vertical-align: 1px; }
.sblk-sep { padding: 16px 0 4px; border-top: 1px solid var(--md-sys-color-outline-variant);
  font: var(--md-sys-typescale-label-medium); font-weight: 600; color: var(--md-sys-color-on-surface-variant); }
/* Ligne-lien (documents, aide) : toute la ligne mène à la page, chevron au bout. */
.sblk a.stp-row { color: inherit; text-decoration: none; }
.sblk a.stp-row > svg { flex: none; margin-left: auto; color: var(--md-sys-color-on-surface-variant); }
.sblk a.stp-row { margin: 0 -8px; padding-left: 8px; padding-right: 8px; border-radius: var(--md-sys-shape-corner-small); }   /* même survol gris que les menus, pas de soulignement */
.sblk a.stp-row:hover { background: var(--sp-hover-bg); }
/* Boutons qui rétrécissent et passent à la ligne entre eux : « Se désabonner » ne sort plus du bord à 320 px
   (audit break-ui, 2026-10). */
.sblk .stp-row-acts { flex: 0 1 auto; min-width: 0; max-width: 100%; display: flex; flex-wrap: wrap; justify-content: flex-end; gap: 8px; margin-left: auto; }
/* Un interrupteur ou un bouton icône seul garde sa taille au bout de la ligne (lignes .setc sans retour, plus bas). */
.sblk .stp-row-acts:has(> :is(.ex-toggle, .ibtn):only-child) { flex: none; }
/* Liste de lignes .lrow dans un bloc : le texte s'aligne sur le titre (20 px), le survol déborde de 10 px. */
.sblk-body--rows > .lrow-list { padding: 8px 0; }
.sblk .lrow { margin: 0 -10px; }
/* Place réduite : le texte garde 200 px au moins, les boutons passent dessous, à droite. */
.sblk .stp-row { flex-wrap: wrap; row-gap: 12px; }
.sblk .stp-row-txt { flex: 1 1 200px; }
@media (max-width: 560px) {
  .sblk-two { grid-template-columns: minmax(0, 1fr); }
  .sblk-head, .sblk-body { padding-left: 16px; padding-right: 16px; }
}
/* Sous 400 px, les boutons d'une ligne passent toujours sous le nom. */
@media (max-width: 400px) { .sblk .stp-row-acts { flex-basis: 100%; } }

/* Notifications : une ligne par événement, deux interrupteurs (Sur le site, Par e-mail)
   sous deux en-têtes de colonne. */
.snotif-row { display: grid; grid-template-columns: minmax(0, 1fr) 88px 88px; align-items: center; gap: 0 8px; padding: 12px 0; }
.snotif-row + .snotif-row { border-top: 1px solid var(--md-sys-color-outline-variant); }
.snotif-row--h { padding: 12px 0 4px; }
.snotif-h { text-align: center; font: var(--md-sys-typescale-label-medium); font-weight: 600; color: var(--md-sys-color-on-surface-variant); }
.snotif-h:first-child { text-align: left; }
.snotif-cell { display: flex; justify-content: center; }
@media (max-width: 560px) { .snotif-row { grid-template-columns: minmax(0, 1fr) 64px 64px; } }
.stp-row-name.is-danger { color: var(--md-sys-color-error); }

/* ── Éditeur d'avatar (« Crée ton avatar » : inscription et Paramètres > Profil) ──
   Aperçu en avatar 112, puis trois rangées du Visual picker : forme, couleur, fond. */
.avm-body { display: flex; flex-direction: column; gap: 16px; }
.avm-preview { display: flex; margin: 8px auto 4px; }
.avm-group { display: flex; flex-direction: column; gap: 8px; }

/* ── Fiche d'un spectateur (shared/viewer-card.js) ──
   Un spectateur n'a pas de page : un clic sur son nom ou sa photo ouvre cette petite
   fenêtre (décision du porteur du 28/09/2026, référence « carte de chaîne » de YouTube).
   Avatar 84, nom, @pseudo, « Membre depuis », puis « À propos » sous un filet. */
.vcard { max-width: 400px; }
.vcard:focus { outline: none; }
.vcard-x { position: absolute; top: 12px; right: 12px; }
.vcard-top { display: flex; align-items: center; gap: 16px; padding-right: 32px; }
.vcard-id { min-width: 0; }
.vcard-name { margin: 0; font: var(--md-sys-typescale-title-large); font-weight: 700; color: var(--md-sys-color-on-surface); overflow-wrap: anywhere; }
.vcard-handle { margin: 2px 0 0; font: var(--md-sys-typescale-body-medium); color: var(--md-sys-color-on-surface-variant); overflow-wrap: anywhere; }   /* @pseudo sans point de coupure : il passe à la ligne */
.vcard-meta { margin: 4px 0 0; font: var(--md-sys-typescale-body-small); color: var(--md-sys-color-on-surface-variant); }
.vcard-about { margin: 20px 0 0; padding-top: 16px; border-top: 1px solid var(--md-sys-color-outline-variant);
  font: var(--md-sys-typescale-body-medium); color: var(--md-sys-color-on-surface); overflow-wrap: anywhere; white-space: pre-line; }

/* ── Barre de liste (shared/list-header.js) : Rechercher, Filtre, Trier par ──
   Pattern « List header ». Modèle du porteur du 27/09/2026 (Nike, une barre « Search +
   Filter », puis une barre « Funnels » : tous les éléments de la même famille), revu
   d'après ses maquettes : le titre de la liste (écrit par la page) au-dessus ; dessous,
   calés à GAUCHE et toujours dans cet ordre : Rechercher (.ex-search), Filtre et Trier
   par (sélecteurs à menu .ex-selbtn, même peau que la recherche), puis « Tout effacer »
   (.lnk--ink + circle-x) seulement s'il y a un filtre. Seule cette barre reste collée en
   haut au défilement (la page la pose dans son .ds-sticky-head), le titre s'en va.
   Filtre ouvre un menu du DS à choix multiples (groupes titrés, une case à cocher par
   choix, deux colonnes) ; Trier par, un menu du DS à choix exclusif coché. Le nombre de filtres choisis
   s'affiche sur Filtre, dans la pastille de compteur de la cloche des notifications
   (.tbar-dot, même composant). Sous 480 px (SA largeur, requête de conteneur), la
   recherche prend le reste de la ligne, Filtre et Trier deviennent des sélecteurs carrés
   à icône seule et les menus prennent toute la largeur.
   Placement seulement : les composants viennent du DS. */
/* position: relative : repère des menus quand ils prennent toute la largeur. */
.lhead { position: relative; container: lhead / inline-size; }
.lhead-tools { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
/* Recherche souple (refonte du Studio, À valider ; 240 px fixes avant) : 280 px de base, elle
   s'élargit jusqu'à 400 px pour que l'indication longue tienne (« Rechercher un titre, une œuvre,
   un épisode ») ; Filtre et Trier passent à la ligne seulement si 280 px ne tiennent plus. */
.lhead-search { flex: 1 1 280px; width: auto; min-width: 0; max-width: 400px; }
.lhead-dd { position: relative; }
.lhead-narrow { display: none; }
.lhead-caret { transition: transform .15s ease; }
.lhead-dd [aria-expanded="true"] .lhead-caret { transform: rotate(180deg); }
/* Pastille : à cheval sur le coin haut droit de l'entonnoir (maquette du porteur) ; sur le
   sélecteur carré, à la même place que sur la cloche. */
.lhead-wide .tbar-dot { top: 3px; right: 6px; }
.lhead-narrow .tbar-dot { top: 5px; right: 5px; }
.lhead-pop { position: absolute; top: calc(100% + 8px); left: 0; z-index: 40; box-sizing: border-box; width: 240px; }
.lhead-pop[hidden] { display: none; }
/* Menu Filtre : 320 px au moins pour ses deux colonnes (Trier par : 240) ; il s'élargit
   jusqu'à 560 px quand ses libellés sont longs (types de publication, titres d'œuvres),
   au-delà ils sont coupés (…). */
.lhead-pop--filter { width: max-content; min-width: 320px; max-width: min(560px, calc(100vw - 32px)); max-height: min(70vh, 560px); overflow-y: auto; }
.lhead-clear { height: 44px; margin-left: 8px; padding: 0; border: 0; background: none; }
.lhead-clear[hidden] { display: none; }
@container lhead (max-width: 479px) {
  /* Base de 160 px : « Tout effacer » passe à la ligne au lieu d'écraser la recherche. */
  .lhead-search { flex: 1 1 160px; width: auto; min-width: 0; max-width: none; }   /* tout le reste de la ligne */
  .lhead-clear { margin-left: 0; }
  .lhead-dd { position: static; }
  .lhead-wide { display: none; }
  .lhead-narrow { display: inline-flex; }
  .lhead-pop { left: 0; right: 0; width: auto; min-width: 0; max-width: none; }
}
/* Démo de l'atelier : un cadre, le titre au-dessus de la barre (16 px), de la place
   dessous pour le panneau et le menu ouverts, et une version étroite pour le téléphone. */
.lh-demo { padding: 20px 24px; border: 1px solid var(--md-sys-color-outline-variant); border-radius: var(--md-sys-shape-corner-large); background: var(--md-sys-color-surface); }
.lh-demo--open-filter { padding-bottom: 500px; }
.lh-demo--open-sort { padding-bottom: 240px; }
.lh-demo--narrow { max-width: 390px; box-sizing: border-box; padding: 16px; }
.lh-demo-t { margin-bottom: 16px; }
/* Démo du composant Menu : les trois menus côte à côte, alignés en haut. */
.ds-menus { align-items: flex-start; gap: 24px; }
.lh-demo-eyebrow { font: var(--md-sys-typescale-label-small); font-weight: 700; letter-spacing: .08em; text-transform: uppercase; color: var(--md-sys-color-primary); }
.lh-demo-h { margin: 3px 0 0; font: var(--md-sys-typescale-headline-small); font-weight: 700; letter-spacing: -0.01em; color: var(--md-sys-color-on-surface); }

/* ── Connexion (shared/auth-modal.js) ── */
.sp-auth-logo { text-align: center; color: var(--md-sys-color-primary); margin-bottom: 8px; }
.sp-auth-h { margin: 0 0 4px; font: var(--md-sys-typescale-headline-small); text-align: center; color: var(--md-sys-color-on-surface); }
.sp-auth-sub { margin: 0 0 16px; font: var(--md-sys-typescale-body-medium); text-align: center; color: var(--md-sys-color-on-surface-variant); }
.sp-auth label { display: block; margin: 16px 0 8px; }   /* champ : règle commune TEXT FIELD (Champs de formulaire) */
.sp-auth-err { min-height: 16px; margin: 8px 0 0; font: var(--md-sys-typescale-body-small); color: var(--md-sys-color-error); }
.sp-auth-btn { width: 100%; margin-top: 16px; }
.sp-auth-resend { margin: 16px 0 0; }   /* « Pas reçu ? Renvoyer le code » sous le bouton, étape du code de connexion */
.sp-auth-or { display: flex; align-items: center; gap: 12px; margin: 16px 0; font: var(--md-sys-typescale-label-medium); color: var(--md-sys-color-on-surface-faint); }
.sp-auth-or::before, .sp-auth-or::after { content: ""; flex: 1; height: 1px; background: var(--md-sys-color-outline-variant); }
.sp-auth-reg { width: 100%; }

/* ── Installation (shared/pwa.js) ── */
.pwa-modal { transform: translateY(10px) scale(.98); transition: transform .18s ease; }
.pwa-ov.is-on .pwa-modal { transform: none; }
.pwa-head { display: flex; align-items: center; gap: 12px; padding-right: 40px; }   /* la croix est dans le coin */
.pwa-appicon { flex: none; width: 44px; height: 44px; border-radius: var(--md-sys-shape-corner-medium); }
.pwa-head h2 { flex: 1; }
.pwa-intro { margin: 16px 0; font: var(--md-sys-typescale-body-medium); color: var(--md-sys-color-on-surface-variant); }
.pwa-install { width: 100%; margin-bottom: 24px; }
.pwa-tabs { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 16px; }
.pwa-plat { margin: 0 0 12px; font: var(--md-sys-typescale-label-large); color: var(--md-sys-color-on-surface-variant); }
.pwa-steps { display: flex; flex-direction: column; gap: 12px; }
.pwa-step { display: flex; align-items: flex-start; gap: 12px; }
.pwa-step-ic { flex: none; display: inline-flex; align-items: center; justify-content: center; width: 32px; height: 32px;
  border-radius: var(--md-sys-shape-corner-small);
  background: var(--md-sys-color-primary-container); color: var(--md-sys-color-on-primary-container); }
.pwa-step-tx { flex: 1; padding-top: 6px; font: var(--md-sys-typescale-body-medium); color: var(--md-sys-color-on-surface); }
.pwa-step-tx b { font-weight: 600; }
.pwa-done { display: flex; align-items: center; gap: 12px; margin-top: 4px; padding: 16px; border-radius: var(--md-sys-shape-corner-medium);
  background: var(--md-sys-color-surface-container-highest); font: var(--md-sys-typescale-body-medium); color: var(--md-sys-color-on-surface); }
.pwa-done svg { flex: none; color: var(--md-sys-color-success); }

/* ── MENUS ─────────────────────────────────────────────────────────────
   Les vrais menus (une liste d'actions), formes SydePlay : panneau fond surface,
   contour, rayon 12, marge 6, élévation 3 (le même que les menus de la barre du
   haut) ; lignes de 44 (règle des 44 px), rayon 8, écart 10, libellé 14 / 500,
   icônes 20 ; couche d'état au survol. Concerne le menu « Publier », les menus
   de lien, la langue, le menu mobile, et tout menu de page (classe .menu :
   tri et filtres du fil). */
.menu, .tbar-dd-panel { padding: 6px; background: var(--md-sys-color-surface); color: var(--md-sys-color-on-surface);
  border: 1px solid var(--md-sys-color-outline); border-radius: var(--md-sys-shape-corner-medium); box-shadow: var(--md-sys-elevation-level3); }
.tbar-publish [role="menuitem"], .tbar-linkmenu [role="menuitem"], .tbar-lang [role="menuitemradio"], .tbar-mobile [role="menuitem"]:not(.cbtn, .tbar-m-signin),
.menu :is([role="menuitem"], [role="menuitemradio"], [role="menuitemcheckbox"]) {
  position: relative; isolation: isolate; display: flex; align-items: center; gap: 10px; width: 100%; box-sizing: border-box;
  height: 44px; padding: 0 12px; border: 0; border-radius: var(--md-sys-shape-corner-small); white-space: nowrap;
  background: transparent; color: var(--md-sys-color-on-surface); font: var(--md-sys-typescale-label-large);
  text-align: left; text-decoration: none; cursor: pointer;
}
.tbar-publish [role="menuitem"] svg, .tbar-linkmenu [role="menuitem"] svg, .tbar-mobile [role="menuitem"]:not(.cbtn, .tbar-m-signin) svg,
.menu :is([role="menuitem"], [role="menuitemradio"], [role="menuitemcheckbox"]) svg { flex: none; width: 20px; height: 20px; color: var(--md-sys-color-on-surface-variant); }
.tbar-publish [role="menuitem"]::after, .tbar-linkmenu [role="menuitem"]::after, .tbar-lang [role="menuitemradio"]::after, .tbar-mobile [role="menuitem"]:not(.cbtn, .tbar-m-signin)::after,
.menu :is([role="menuitem"], [role="menuitemradio"], [role="menuitemcheckbox"])::after {
  content: ""; position: absolute; inset: 0; border-radius: inherit; background: currentColor; opacity: 0; pointer-events: none; transition: opacity .15s ease; }
.tbar-publish [role="menuitem"]:hover::after, .tbar-linkmenu [role="menuitem"]:hover::after, .tbar-lang [role="menuitemradio"]:hover::after, .tbar-mobile [role="menuitem"]:not(.cbtn, .tbar-m-signin):hover::after,
.menu :is([role="menuitem"], [role="menuitemradio"], [role="menuitemcheckbox"]):hover::after { opacity: var(--md-sys-state-hover-opacity); }
.menu :is([role="menuitem"], [role="menuitemradio"], [role="menuitemcheckbox"]):focus-visible { outline: 3px solid var(--md-sys-color-primary); outline-offset: -3px; }
/* Ligne désactivée : opacité 38 % (état M3), ni survol ni clic (ex. « Personnalisées », bientôt disponible). */
.menu :is([role="menuitem"], [role="menuitemradio"], [role="menuitemcheckbox"])[aria-disabled="true"] { opacity: var(--md-sys-state-disabled-opacity); cursor: default; pointer-events: none; }
/* Choix exclusif (menuitemradio) : coche primary en fin de ligne, visible sur l'option retenue. */
.menu [role="menuitemradio"] .menu-check { width: 18px; height: 18px; margin-left: auto; color: var(--md-sys-color-primary); opacity: 0; }
.menu [role="menuitemradio"][aria-checked="true"] .menu-check { opacity: 1; }
/* Choix multiples (menuitemcheckbox) : la case à cocher du DS (.ex-box) en tête de ligne,
   cochée quand aria-checked vaut true ; le menu reste ouvert pendant qu'on coche. Les
   choix se rangent en groupes : un titre (.menu-label, label-medium 600,
   on-surface-variant) au-dessus de ses lignes, un filet (.menu-sep) entre deux groupes.
   Né pour le menu Filtre de la barre de liste (27/09/2026). */
.menu [role="menuitemcheckbox"] .ex-box svg { width: 14px; height: 14px; color: inherit; }
.menu [role="menuitemcheckbox"]:hover .ex-box { border-color: var(--md-sys-color-on-surface-variant); }
.menu [role="menuitemcheckbox"][aria-checked="true"] .ex-box { background: var(--md-sys-color-primary); border-color: var(--md-sys-color-primary); }
.menu [role="menuitemcheckbox"][aria-checked="true"] .ex-box svg { opacity: 1; }
.menu-label { padding: 10px 12px 6px; font: var(--md-sys-typescale-label-medium); font-weight: 600; color: var(--md-sys-color-on-surface-variant); }
/* Deux colonnes (.menu-cols) : les lignes d'un groupe se rangent deux par deux, pour un
   menu moins long (menu Filtre, retour du porteur du 27/09/2026). Écart de 4 entre les
   colonnes ; un libellé trop long se coupe par « … ». */
.menu-cols { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); column-gap: 4px; }
.menu-cols > [role^="menuitem"] > span:last-child { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
/* Téléphone ou barre de liste étroite (refonte du Studio, À valider) : une seule colonne, et un
   libellé long passe à la ligne au lieu d'être coupé (« Réactions synchronisées »). */
@media (max-width: 560px) {
  .menu-cols { grid-template-columns: minmax(0, 1fr); }
  .menu-cols > [role^="menuitem"] { height: auto; min-height: 44px; padding-top: 10px; padding-bottom: 10px; white-space: normal; }
  .menu-cols > [role^="menuitem"] > span:last-child { overflow: visible; text-overflow: clip; overflow-wrap: anywhere; }
}
@container lhead (max-width: 479px) {
  .lhead-pop .menu-cols { grid-template-columns: minmax(0, 1fr); }
  .lhead-pop .menu-cols > [role^="menuitem"] { height: auto; min-height: 44px; padding-top: 10px; padding-bottom: 10px; white-space: normal; }
  .lhead-pop .menu-cols > [role^="menuitem"] > span:last-child { overflow: visible; text-overflow: clip; overflow-wrap: anywhere; }
}
.menu-sep, .menu .tbar-menu-sep { height: 1px; margin: 4px 6px; background: var(--md-sys-color-outline-variant); }

/* ═══════════════════════════════════════════════════════
 *  Publier en étapes (01/10/2026) : pièces nées dans Studio › Publier,
 *  rangées ici sur demande du porteur. À VALIDER (section Composants).
 *  Barre d'étapes (.wiz-progress/.wiz-step), tuiles de plateforme et
 *  fenêtre « Autre » (.wiz-plat*), lignes de pause / point (.wiz-row*),
 *  champ de temps (.tf/.tstep), frise sur une ligne (.wiz-tl, préfixée
 *  :is(.ds, .ds-app) pour passer devant les anciennes règles .tl2-* de Publier).
 * ═══════════════════════════════════════════════════════ */
/* ── Étapes : barres fines ; roses jusqu'à l'étape en cours, gris clair ensuite.
   Les étapes faites restent cliquables (zone de clic plus haute que la barre). ── */
.wiz-progress { display: flex; align-items: center; gap: 6px; }
.wiz-step { position: relative; display: block; width: 40px; height: 20px; padding: 0; border: 0; background: none; }
.wiz-step::before { content: ""; position: absolute; left: 0; right: 0; top: 8px; height: 4px; border-radius: 2px;
  background: var(--md-sys-color-surface-container-highest); transition: background .2s ease; }
.wiz-step.is-done::before, .wiz-step.is-current::before { background: var(--md-sys-color-primary); }
button.wiz-step { cursor: pointer; }
button.wiz-step:hover::before { filter: brightness(1.1); }
button.wiz-step:focus-visible { outline: 3px solid var(--md-sys-color-primary); outline-offset: 2px; border-radius: 4px; }

/* Nom de l'étape gardé pour les lecteurs d'écran */
.wiz-step .sr-only { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }

.wiz-plat-list { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 8px; }
.wiz-plat { position: relative; cursor: pointer; }
.wiz-plat input { position: absolute; opacity: 0; width: 0; height: 0; }
/* Révision du 06/10/2026 (refonte du Studio) : rayons et ombres sur les jetons du DS (12, 8, élévations 1 et 2). */
.wiz-plat > span { display: flex; align-items: center; gap: 10px; height: 44px; box-sizing: border-box; padding: 0 12px 0 6px; border-radius: var(--md-sys-shape-corner-medium);
  border: 1px solid var(--md-sys-color-outline-variant); background: var(--md-sys-color-surface); font: var(--md-sys-typescale-label-large); font-weight: 600;
  color: var(--md-sys-color-on-surface); transition: border-color .15s ease, box-shadow .15s ease; }
.wiz-plat img, .wiz-plat-ic { flex: none; width: 32px; height: 32px; border-radius: var(--md-sys-shape-corner-small); }
.wiz-plat-ic { display: flex; align-items: center; justify-content: center; background: var(--md-sys-color-surface-container-high); color: var(--md-sys-color-on-surface-variant); }
.wiz-plat:hover > span { border-color: var(--md-sys-color-on-surface-variant); }
.wiz-plat input:checked + span { border: 1.5px solid var(--md-sys-color-primary); padding-left: 5.5px; background: color-mix(in srgb, var(--md-sys-color-primary) 6%, var(--md-sys-color-surface)); box-shadow: var(--md-sys-elevation-level1); }
.wiz-plat input:checked + span::after { content: ""; margin-left: auto; width: 16px; height: 16px; border-radius: var(--md-sys-shape-corner-full); box-sizing: border-box; border: 5px solid var(--md-sys-color-primary); }
.wiz-plat input:focus-visible + span { outline: 3px solid var(--md-sys-color-primary); outline-offset: 2px; }
/* « Autre » : petite fenêtre accrochée à la tuile (même peau que le réglage de l'heure) */
.wiz-plat-more { position: relative; }
.wiz-plat-more > .wiz-plat > span { overflow: hidden; white-space: nowrap; }
.wiz-plat-pop { position: absolute; top: calc(100% + 8px); left: 0; z-index: 30; width: 300px; max-width: calc(100vw - 48px); padding: 10px;
  border-radius: var(--md-sys-shape-corner-medium); background: var(--md-sys-color-surface); border: 1px solid var(--md-sys-color-outline-variant); box-shadow: var(--md-sys-elevation-level2); }
.wiz-plat-pop[hidden] { display: none; }
.wiz-plat-res { display: flex; flex-direction: column; gap: 2px; max-height: 280px; overflow-y: auto; margin-top: 8px; }
.wiz-plat-opt { display: flex; align-items: center; gap: 10px; width: 100%; min-height: 44px; padding: 4px 8px; border: 0; border-radius: var(--md-sys-shape-corner-small); background: none;
  text-align: left; font: var(--md-sys-typescale-body-medium); color: var(--md-sys-color-on-surface); cursor: pointer; }
.wiz-plat-opt:hover, .wiz-plat-opt:focus-visible { background: var(--sp-hover-bg); outline: none; }
.wiz-plat-opt img { flex: none; width: 28px; height: 28px; border-radius: var(--md-sys-shape-corner-small); }
.wiz-plat-opt.is-free { font-weight: 600; }

/* Pauses et points : une ligne chacun.
   Révision du 06/10/2026 (refonte du Studio, contrat « .tf, .tf-pop, .tstep, .wiz-row, .wiz-add, .wiz-tl ») :
   note = champ du DS de 44, retirer = bouton icône de 44, pastilles sur les jetons --sp-tl-*-container,
   « Ajouter » de 44, rayons 12 / 8 du DS, survol = couche d'état commune (--sp-hover-bg). */
.wiz-rows { margin-top: 24px; }
.wiz-rows-head { display: flex; align-items: baseline; gap: 8px; margin-bottom: 8px; }
.wiz-rows-head b { font: var(--md-sys-typescale-title-small); font-weight: 700; }
.wiz-rows-head span { font: var(--md-sys-typescale-body-small); color: var(--md-sys-color-on-surface-variant); }
.wiz-row { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; padding: 6px 6px 6px 8px; margin-bottom: 6px; border: 1px solid var(--md-sys-color-outline-variant); border-radius: var(--md-sys-shape-corner-medium); background: var(--md-sys-color-surface); }
.wiz-row-ic { flex: none; display: flex; align-items: center; justify-content: center; width: 32px; height: 32px; border-radius: var(--md-sys-shape-corner-small); }
.wiz-row-ic.is-pause { background: var(--sp-tl-pause-container); color: var(--sp-on-tl-pause-container); }
.wiz-row-ic.is-point { background: var(--sp-tl-point-container); color: var(--sp-on-tl-point-container); }
.wiz-row-f { display: inline-flex; align-items: center; gap: 6px; font: var(--md-sys-typescale-body-small); color: var(--md-sys-color-on-surface-variant); }
.wiz-row-note { flex: 1 1 100%; order: 5; min-width: 60px; height: 44px; box-sizing: border-box; padding: 0 12px; font: var(--md-sys-typescale-body-medium); color: var(--md-sys-color-on-surface);
  background: var(--md-sys-color-surface-container-high); border: 1px solid transparent; border-radius: var(--md-sys-shape-corner-medium); }
.wiz-row-note::placeholder { color: color-mix(in srgb, var(--md-sys-color-on-surface-variant) 60%, var(--md-sys-color-on-surface-strong)); opacity: 1; }
.wiz-row-note:focus { outline: none; border-color: var(--md-sys-color-primary); }
.wiz-row-note[aria-invalid="true"] { border-color: var(--md-sys-color-error); }
.wiz-row-btn { flex: none; display: flex; align-items: center; justify-content: center; width: 44px; height: 44px; padding: 0; border: 0; border-radius: var(--md-sys-shape-corner-medium); background: none; color: var(--md-sys-color-on-surface-variant); cursor: pointer; }
.wiz-row-btn:hover { background: var(--sp-hover-bg); color: var(--md-sys-color-on-surface); }
.wiz-row-btn:focus-visible, .wiz-add:focus-visible { outline: 3px solid var(--md-sys-color-primary); outline-offset: 1px; }
.wiz-add { display: flex; align-items: center; justify-content: center; gap: 6px; width: 100%; height: 44px; border: 1px dashed var(--md-sys-color-outline-variant); border-radius: var(--md-sys-shape-corner-medium);
  background: none; font: var(--md-sys-typescale-label-large); font-weight: 600; color: var(--md-sys-color-on-surface-variant); cursor: pointer; }
.wiz-add:hover { color: var(--md-sys-color-on-surface); border-color: var(--md-sys-color-on-surface-variant); }
/* La note passe sous les heures, en pleine largeur, à toutes les largeurs (audit break-ui du 15/10/2026 :
   à 1440 elle n'avait que 90 px, « Je dois en ») ; elle l'était déjà sous 600 px. order: 5 : après « retirer ». */

/* Champ de temps compact : on tape « 58:00 », ou le réglage s'ouvre au clic (flèches par unité).
   Révision du 06/10/2026 : 44 de haut, rayon 12, largeur 112, chiffres en title-medium tabulaires ;
   petite fenêtre au rayon 12 et à l'élévation 2 ; réglages en jetons, rayon 8. */
.tf { position: relative; display: inline-flex; align-items: stretch; height: 44px; box-sizing: border-box; border: 1px solid var(--md-sys-color-outline-variant); border-radius: var(--md-sys-shape-corner-medium); background: var(--md-sys-color-surface); }
.tf:focus-within, .tf.is-open { border-color: var(--md-sys-color-primary); }
.tf-in { width: 112px; box-sizing: border-box; padding: 0 12px; border: 0; border-radius: var(--md-sys-shape-corner-medium); background: none; text-align: center; cursor: pointer;
  font: var(--md-sys-typescale-title-medium); font-variant-numeric: tabular-nums; color: var(--md-sys-color-on-surface); }
.tf-in:focus { outline: none; }
.tf-in:disabled { cursor: not-allowed; }
.tf:has(.tf-in:disabled) { opacity: var(--md-sys-state-disabled-opacity); }
.tf-in[aria-invalid="true"] { color: var(--md-sys-color-on-error-container); }
.tf:has(.tf-in[aria-invalid="true"]) { border-color: var(--md-sys-color-error); }
.tf-pop { position: absolute; top: calc(100% + 8px); left: 0; z-index: 30; padding: 10px; border-radius: var(--md-sys-shape-corner-medium); background: var(--md-sys-color-surface);
  border: 1px solid var(--md-sys-color-outline-variant); box-shadow: var(--md-sys-elevation-level2); }
.tf-pop::before { content: ""; position: absolute; top: -6px; left: 20px; width: 10px; height: 10px; background: inherit;
  border-left: 1px solid var(--md-sys-color-outline-variant); border-top: 1px solid var(--md-sys-color-outline-variant); transform: rotate(45deg); }
.tf-pop[hidden] { display: none; }
.tstep { display: inline-flex; align-items: flex-start; gap: 0; }
.tstep-col { display: flex; flex-direction: column; align-items: center; width: 44px; }
.tstep-col.is-ms { width: 52px; }
.tstep-btn { display: flex; align-items: center; justify-content: center; width: 100%; height: 28px; padding: 0; border: 0; border-radius: var(--md-sys-shape-corner-small); cursor: pointer;
  background: none; color: var(--md-sys-color-on-surface-variant); }
.tstep-btn:hover { background: var(--sp-hover-bg); color: var(--md-sys-color-on-surface); }
.tstep-btn svg { width: 14px; height: 14px; }
.tstep-btn:focus-visible, .tstep-in:focus-visible { outline: 3px solid var(--md-sys-color-primary); outline-offset: 1px; }
.tstep-in { width: 40px; height: 30px; margin: 0 2px; padding: 0; box-sizing: border-box; text-align: center; font: var(--md-sys-typescale-title-large); font-variant-numeric: tabular-nums;
  color: var(--md-sys-color-on-surface); background: none; border: 1px solid var(--md-sys-color-outline-variant); border-radius: var(--md-sys-shape-corner-small); -moz-appearance: textfield; }
.tstep-col.is-ms .tstep-in { width: 48px; }
.tstep-in::-webkit-outer-spin-button, .tstep-in::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
.tstep-sep { align-self: center; font-weight: 700; color: var(--md-sys-color-on-surface-variant); }

/* Frise sur UNE ligne : vert avant le film, violet après, orange les pauses, traits roses les
   points d'ancrage, le reste (bleu pastel) = « Tu regardes ». Heures et minutes seulement.
   Révision du 06/10/2026 : la frise ne lit plus que les jetons --sp-tl-* (clair et sombre définis en
   tête du fichier) ; plus aucune couleur ni aucun rayon écrits en dur. */
:is(.ds, .ds-app) .wiz-tl-box { margin-top: 24px; padding: 16px; border: 1px solid var(--md-sys-color-outline-variant); border-radius: var(--md-sys-shape-corner-medium); background: var(--md-sys-color-surface); }
:is(.ds, .ds-app) .wiz-tl .tl2-bar { height: 32px; border-radius: var(--md-sys-shape-corner-small); overflow: hidden; background: var(--sp-tl-watch); }
:is(.ds, .ds-app) .wiz-tl .tl2-blk { border-radius: 0; }
:is(.ds, .ds-app) .wiz-tl .tl2-blk.is-before { background: var(--sp-tl-before); }
:is(.ds, .ds-app) .wiz-tl .tl2-blk.is-after { background: var(--sp-tl-after); }
:is(.ds, .ds-app) .wiz-tl .tl2-blk.is-pause { background: var(--sp-tl-pause); }
:is(.ds, .ds-app) .wiz-tl .tl2-pt { position: absolute; top: 4px; bottom: 4px; width: 3px; height: auto; border: 0; border-radius: var(--md-sys-shape-corner-full); background: var(--sp-tl-point);
  transform: translateX(-1.5px); z-index: 4; }
:is(.ds, .ds-app) .wiz-tl .tl2-timerow { height: 18px; margin: 6px 0 0; }
:is(.ds, .ds-app) .wiz-tl .tl-dot.is-before { background: var(--sp-tl-before); }
:is(.ds, .ds-app) .wiz-tl .tl-dot.is-after { background: var(--sp-tl-after); }
:is(.ds, .ds-app) .wiz-tl .tl-dot.is-pause { background: var(--sp-tl-pause); }
:is(.ds, .ds-app) .wiz-tl .tl-dot.is-watch { background: var(--sp-tl-watch); border: 1px solid var(--md-sys-color-outline-variant); box-sizing: border-box; }
:is(.ds, .ds-app) .wiz-tl .tl-dot.is-pt { width: 3px; height: 12px; border-radius: var(--md-sys-shape-corner-full); background: var(--sp-tl-point); }
:is(.ds, .ds-app) .wiz-tl .tl2-bar { position: relative; }
:is(.ds, .ds-app) .wiz-tl .tl2-blk { position: absolute; top: 0; bottom: 0; }
:is(.ds, .ds-app) .wiz-tl .tl2-timerow { position: relative; }
:is(.ds, .ds-app) .wiz-tl .tl2-time { position: absolute; transform: translateX(-50%); font: var(--md-sys-typescale-label-small); color: var(--md-sys-color-on-surface-variant); white-space: nowrap; font-variant-numeric: tabular-nums; }
:is(.ds, .ds-app) .wiz-tl .tl-legend { display: flex; flex-wrap: wrap; gap: 16px; margin-top: 12px; font: var(--md-sys-typescale-label-small); color: var(--md-sys-color-on-surface-variant); }
:is(.ds, .ds-app) .wiz-tl .tl-legend span { display: inline-flex; align-items: center; gap: 6px; }
:is(.ds, .ds-app) .wiz-tl .tl-dot { width: 11px; height: 11px; border-radius: var(--md-sys-shape-corner-extra-small); }

/* ════════════════════════════════════════════════════════════════════
   REFONTE DU STUDIO (06/10/2026) · FONDATION DU DESIGN SYSTEM
   Contrat : refonte-studio/design/consolidated.json (dsComponents), étape 1A,
   et la mise en page des Paramètres (spec-site-settings.md, §5.2 A), partagée
   par /settings et Studio › Paramètres.
   Tout ce qui suit est À VALIDER par le porteur avant usage (règle DS 2) ;
   la documentation vivante est dans atelier.js (statut « À décider »).
   Ordre : celui du contrat (buildOrder 1A). Uniquement des jetons --md-sys-* et
   --sp-* ; les jetons ajoutés sont en tête du fichier, les utilitaires .sr-only
   et .sp-spin sous les classes de typo, le bloc prefers-reduced-motion à la fin.
   Les composants existants sont ÉTENDUS (aucune variante parallèle).
   ════════════════════════════════════════════════════════════════════ */

/* ── 1. CHAMPS · aide, erreur, compteur, champ requis ───────────────────
   Sous le contrôle d'un .ex-field (écart 6) : une ligne .ex-meta (l'aide à gauche, le
   compteur à droite), puis l'erreur. Fusion de .ex-hint, .ex-error, .ex-help--err des specs.
   L'aide n'est jamais DANS le <label> (elle entrerait dans le nom du champ) : le champ la
   lit par aria-describedby (aide + erreur affichée + compteur). Couleur jamais seule :
   l'erreur a son icône, la réussite la sienne. */
.ex-meta { display: flex; align-items: flex-start; gap: 8px; min-width: 0; }
.ex-help { flex: 1 1 auto; min-width: 0; margin: 0; font: var(--md-sys-typescale-body-small); color: var(--md-sys-color-on-surface-variant); }
.ex-help[hidden], .ex-err[hidden], .ex-count[hidden] { display: none; }
.ex-help--ok, .ex-help--wait, .ex-help--busy { display: flex; align-items: center; gap: 6px; }
.ex-help svg { flex: none; width: 14px; height: 14px; }
.ex-help--ok { color: var(--md-sys-color-on-success-container); }   /* « Ce nom est libre. » : icône check */
.ex-help--wait svg, .ex-help--busy svg { animation: sp-spin .8s linear infinite; }   /* « Vérification… » : loader-circle */
.ex-err { display: flex; align-items: flex-start; gap: 6px; margin: 0; font: var(--md-sys-typescale-body-small); font-weight: 600; color: var(--md-sys-color-on-error-container); }
.ex-err svg { flex: none; width: 16px; height: 16px; margin-top: 1px; }   /* circle-alert */
.ex-count { flex: none; margin-left: auto; font: var(--md-sys-typescale-label-small); color: var(--md-sys-color-on-surface-variant); font-variant-numeric: tabular-nums; white-space: nowrap; }
.ex-count.is-limit { color: var(--md-sys-color-on-error-container); font-weight: 700; }
.ex-req { margin-left: 2px; color: var(--md-sys-color-on-surface-variant); }   /* astérisque aria-hidden dans .ex-lbl ; le champ porte required + aria-required */
/* Champ à préfixe ou à bouton de fin (.ex-affix) en erreur : le même contour error que
   .ex-field [aria-invalid] ; au focus, le contour primary reprend la main, comme les autres champs. */
.ex-affix:has([aria-invalid="true"]):not(:focus-within) { box-shadow: inset 0 0 0 1px var(--md-sys-color-error); }

/* ── 1b. RÉSUMÉ DES ERREURS (.errsum) ───────────────────────────────────
   En tête de formulaire après un envoi refusé (2 erreurs ou plus : il prend le focus).
   Fusion de .errsum, .alert--list et .alert--summary ; .alert--err (paire error-container
   depuis l'audit du 13/10/2026) ne sert plus aux erreurs de formulaire. Liens soulignés « Libellé : message » vers chaque champ. */
.errsum { display: flex; flex-direction: column; gap: 8px; box-sizing: border-box; margin: 0 0 24px; padding: 16px;
  border-radius: var(--md-sys-shape-corner-medium); background: var(--md-sys-color-error-container); color: var(--md-sys-color-on-error-container); }
.errsum[hidden] { display: none; }
.errsum:focus { outline: 3px solid var(--md-sys-color-primary); outline-offset: 2px; }
.errsum-title, .errsum > p:first-child { display: flex; align-items: center; gap: 8px; margin: 0; font: var(--md-sys-typescale-title-small); font-weight: 700; color: inherit; }
.errsum-title svg, .errsum > p:first-child svg { flex: none; width: 20px; height: 20px; }
.errsum ul { display: flex; flex-direction: column; gap: 4px; margin: 0; padding: 0 0 0 28px; font: var(--md-sys-typescale-body-medium); }
.errsum li a { color: inherit; text-decoration: underline; text-underline-offset: 3px; }   /* li a : passe devant « .ds-app a » (feed-ds.css) */
.errsum li a:focus-visible { outline: 3px solid var(--md-sys-color-primary); outline-offset: 2px; border-radius: var(--md-sys-shape-corner-extra-small); }
.errsum-acts { display: flex; flex-wrap: wrap; gap: 8px; }   /* variante serveur : « Réessayer » */

/* ── 1c. CHAMP DATE ET HEURE (.ex-dt) ───────────────────────────────────
   fieldset.ex-dt-set > legend.ex-lbl + .ex-dt (deux .ex-field : Date, Heure) + aide + erreur.
   Sélecteurs natifs (tactiles) à la peau des champs ; le calendrier natif suit le thème. */
.ex-dt-set { min-width: 0; margin: 0; padding: 0; border: 0; }
.ex-dt-set > legend { padding: 0; margin: 0; }
.ex-dt-set > :not(legend) { margin-top: 6px; }
.ex-dt { display: grid; grid-template-columns: minmax(0, 1fr) minmax(112px, 140px); gap: 8px; }
.ex-dt input { color-scheme: light; }
[data-theme="dark"] .ex-dt input, .ds-sec--dark .ex-dt input { color-scheme: dark; }
@media (max-width: 360px) { .ex-dt { grid-template-columns: minmax(0, 1fr); } }

/* ── 1d. BOUTON RADIO DESSINÉ (.ex-check--radio + .ex-dot) ──────────────
   Même famille que la case à cocher dessinée : rond de 20, contour 1,5 outline, point de 10
   primary qui apparaît (échelle 0 → 1). L'input natif reste (flèches, lecteurs d'écran),
   toujours dans un fieldset / legend. .ex-dot sert aussi de radio visuel dans .choice--row. */
.ex-check--radio { align-items: flex-start; }
.ex-check--radio input { position: absolute; left: 0; top: 1px; width: 20px; height: 20px; margin: 0; opacity: 0; cursor: pointer; }
.ex-dot { position: relative; display: inline-flex; align-items: center; justify-content: center; flex: none; box-sizing: border-box; width: 20px; height: 20px; margin-top: 1px;
  border-radius: var(--md-sys-shape-corner-full); border: 1.5px solid var(--md-sys-color-outline); background: var(--md-sys-color-surface); transition: border-color .15s ease; }
.ex-dot::after { content: ""; width: 10px; height: 10px; border-radius: var(--md-sys-shape-corner-full); background: var(--md-sys-color-primary); transform: scale(0); transition: transform .15s ease; }
.ex-check--radio:hover .ex-dot, .choice:hover .ex-dot { border-color: var(--md-sys-color-on-surface-variant); }
.ex-check--radio input:checked + .ex-dot, .choice input:checked + .choice-card .ex-dot { border-color: var(--md-sys-color-primary); }
.ex-check--radio input:checked + .ex-dot::after, .choice input:checked + .choice-card .ex-dot::after { transform: scale(1); }
.ex-check--radio input:focus-visible + .ex-dot { outline: 3px solid var(--md-sys-color-primary); outline-offset: 2px; }
.ex-check--radio:has(input:disabled) { cursor: not-allowed; }
.ex-check--radio input:disabled + .ex-dot { opacity: var(--md-sys-state-disabled-opacity); }

/* ── 1e. CASE À COCHER · état mixte (extension de .ex-box) ──────────────
   « Tout sélectionner » quand une partie seulement des lignes est cochée : la boîte porte
   une 2e icône Lucide minus (.ex-box-mixed) ; input.indeterminate est posé par le script. */
.ex-box:has(> .ex-box-mixed) { display: inline-grid; place-items: center; }
.ex-box:has(> .ex-box-mixed) > svg { grid-area: 1 / 1; }
.ex-check--box input:checked:not(:indeterminate) + .ex-box .ex-box-mixed { opacity: 0; }
.ex-check--box input:indeterminate + .ex-box { background: var(--md-sys-color-primary); border-color: var(--md-sys-color-primary); }
.ex-check--box input:indeterminate + .ex-box svg { opacity: 0; }
.ex-check--box input:indeterminate + .ex-box .ex-box-mixed { opacity: 1; }

/* ── 2. LIGNE DE MENU DESTRUCTIVE (générique) ───────────────────────────
   Supprimer, Bannir, Supprimer le brouillon, dans n'importe quel .menu : la même couleur
   que .tbar-account .danger (primary), pour ne pas créer une 2e couleur de danger.
   Toujours précédée d'un .menu-sep, toujours confirmée par un dialogue. */
.menu [role="menuitem"].danger, .menu [role="menuitem"].danger svg { color: var(--md-sys-color-primary); }

/* ── 3. BOUTON DESTRUCTIF (.cbtn--danger, À valider) ────────────────────
   Validation des confirmations définitives (dialog.js : option danger). Gabarit .cbtn (44,
   rayon 12, couche d'état) ; peau en contour on-error-container (AA) plutôt qu'un fond error
   plein (texte on-error à 3,2:1). Se distingue du bouton rose plein. */
.cbtn--danger { background: var(--md-sys-color-surface); color: var(--md-sys-color-on-error-container); border: 1px solid var(--md-sys-color-on-error-container); }

/* ── 4. SNACKBAR (.snack) ───────────────────────────────────────────────
   LE retour éphémère du site (shared/snackbar.js) ; toast() de reaction-ui.js n'en est plus
   qu'un adaptateur. Au-dessus des fenêtres et de leur voile (1000, confirmation 1001) : un
   message émis depuis une fenêtre ouverte reste lisible. Centré en bas, aux couleurs du thème (inverse-surface), un seul à la fois,
   ne prend jamais le focus. Aucun rôle sur la boîte .snack : snackbar.js écrit le message dans
   deux régions live .sr-only posées une fois (role=status polie pour un succès, role=alert
   assertive pour une erreur). Erreur (.snack--error) : icône triangle-alert en tête.
   Action = .cbtn--redpink, fermer = .ibtn « Fermer ». */
/* Largeur de son contenu (bornée par max-width) : avec left: 50 %, une largeur automatique s'arrêtait à la moitié de
   l'écran, et sur un téléphone le texte se retrouvait sur une colonne de quelques pixels sous le bouton d'action. */
.snack { position: fixed; left: 50%; bottom: 24px; z-index: 1100; box-sizing: border-box; display: flex; align-items: center; gap: 12px;
  width: max-content; min-width: 288px; max-width: min(560px, calc(100vw - 32px)); min-height: 48px; padding: 6px 6px 6px 16px;
  border-radius: var(--md-sys-shape-corner-medium); background: var(--md-sys-color-inverse-surface); color: var(--md-sys-color-inverse-on-surface);
  font: var(--md-sys-typescale-body-medium); box-shadow: var(--md-sys-elevation-level3); transform: translateX(-50%); animation: sp-snack-in .15s ease-out; }
.snack[hidden] { display: none; }
.snack > svg { flex: none; width: 18px; height: 18px; }
.snack-txt { flex: 1 1 auto; min-width: 0; padding: 7px 0; }
.snack-act { flex: none; }
.snack-close { flex: none; color: inherit; }
.snack-close svg { width: 18px; height: 18px; }
.snack:not(:has(.snack-act, .snack-close)) { padding-right: 16px; }
@keyframes sp-snack-in { from { opacity: 0; transform: translate(-50%, 8px); } to { opacity: 1; transform: translate(-50%, 0); } }
@keyframes sp-fade-in { from { opacity: 0; } to { opacity: 1; } }
@keyframes sp-rise-in { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }
/* Au-dessus d'une barre d'enregistrement visible (ordinateur). */
body:has(.savebar:not([hidden])) .snack { bottom: calc(16px + 60px + 16px); }
@media (max-width: 760px) {
  .snack { bottom: calc(84px + 16px + env(safe-area-inset-bottom)); }   /* au-dessus de la barre du bas */
  /* Téléphone : toute la largeur moins les gouttières ; le texte sur sa ligne, l'action et la croix dessous, à droite.
     Sans action, la croix reste au bout du texte. */
  .snack { flex-wrap: wrap; row-gap: 2px; width: calc(100vw - 32px); }
  .snack-txt { flex: 1 1 calc(100% - 30px); }
  .snack:not(:has(.snack-act)) .snack-txt { flex-basis: calc(100% - 30px - 56px); }
  .snack-act { margin-left: auto; }
  body:has(.bulkbar--dock:not([hidden]), .savebar:not([hidden])) .snack { bottom: calc(84px + 16px + 60px + env(safe-area-inset-bottom)); }
}

/* ── 5. EN-TÊTE DE PAGE STUDIO (.phead) ─────────────────────────────────
   UN modèle pour toutes les pages du Studio (remplace .sc, .set, .ssig, .sst, .cm-head,
   .sset-head). [lien retour] + titre et phrase, actions (au plus 1 bouton plein et 2
   secondaires), puis onglets facultatifs. Aucune marge extérieure ni largeur max : seule
   la marge du bas (24) sépare l'en-tête du contenu. Sous 560 px de LARGEUR D'EN-TÊTE
   (requête de conteneur), les actions passent sous le texte, calées à gauche. */
.phead { container: phead / inline-size; display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: end; gap: 16px 24px; margin: 0 0 24px; }
.phead > .phead-back { grid-column: 1 / -1; justify-self: start; min-height: 24px; margin-bottom: -8px; }   /* 8 jusqu'au titre */
.phead-txt { grid-column: 1; min-width: 0; display: flex; flex-direction: column; gap: 4px; }
.phead-txt:last-child, .phead:not(:has(> .phead-acts:not([hidden]))) .phead-txt { grid-column: 1 / -1; }
.phead-sub { margin: 0; max-width: 72ch; font: var(--md-sys-typescale-body-medium); color: var(--md-sys-color-on-surface-variant); }
.phead-acts { grid-column: 2; display: flex; flex-wrap: wrap; align-items: center; justify-content: flex-end; gap: 8px; }
.phead-acts[hidden] { display: none; }
.phead-tabs { grid-column: 1 / -1; min-width: 0; }
/* Vues d'une même rubrique (.ex-seg en liens), sous le titre, avant les onglets (14/10/2026). */
.phead-views { grid-column: 1 / -1; min-width: 0; }
@container phead (max-width: 559px) {
  .phead-txt, .phead-acts { grid-column: 1 / -1; }
  .phead-acts { justify-content: flex-start; }
}

/* ── 6. BARRE DE MODIFICATIONS NON ENREGISTRÉES (.savebar) ──────────────
   Modèle d'enregistrement unique d'une page de réglages (Paramètres, Monétisation › Paliers ;
   contrôleur shared/unsaved.js). Ce N'EST PAS la barre d'étapes du compositeur (.actbar).
   Collée en bas de la zone de contenu : bottom = 16 px au-dessus du bas de l'écran, moins la
   marge basse de .ds-app-content (--home-pad-b, 60 px ; 104 px sur téléphone tant que la
   coquille ne pose pas la variable). Barre (60 de haut), pas un contrôle : ses boutons font 44.
   États : [hidden] tant que rien ne change ; .is-dirty (pencil primary) ; .is-saving
   (aria-busy, boutons désactivés, loader-circle qui tourne, .savebar-prog s'il y a des
   fichiers) ; .is-error (triangle-alert error, texte on-surface) ; .is-saved (circle-check
   on-success-container, boutons masqués, la barre se cache après 2,5 s).
   Ne prend jamais le focus ; le message passe par role=status. */
.savebar { position: sticky; bottom: calc(16px - var(--home-pad-b, 60px)); z-index: 40; container: savebar / inline-size;
  box-sizing: border-box; display: flex; flex-wrap: wrap; align-items: center; gap: 8px 12px; min-height: 60px; padding: 8px 8px 8px 16px;
  border: 1px solid var(--md-sys-color-outline-variant); border-radius: var(--md-sys-shape-corner-large);
  background: var(--md-sys-color-surface-container); color: var(--md-sys-color-on-surface); box-shadow: var(--md-sys-elevation-level3);
  animation: sp-rise-in .2s ease-out; }
.savebar[hidden] { display: none; }
.savebar-row { flex: 1 1 100%; display: flex; flex-wrap: wrap; align-items: center; gap: 8px 12px; min-width: 0; }   /* facultatif : sous .savebar-errs */
.savebar-ic { flex: none; display: inline-flex; color: var(--md-sys-color-on-surface-variant); }
.savebar-ic svg { width: 20px; height: 20px; }
.savebar-msg { flex: 1 1 auto; min-width: 0; margin: 0; font: var(--md-sys-typescale-title-small); color: var(--md-sys-color-on-surface); }
.savebar-prog { flex: none; display: flex; align-items: center; gap: 8px; font: var(--md-sys-typescale-label-medium); color: var(--md-sys-color-on-surface-variant); font-variant-numeric: tabular-nums; }
.savebar-prog[hidden] { display: none; }
.savebar-prog .prog { width: 120px; }
.savebar-acts { flex: none; display: flex; align-items: center; gap: 8px; margin-left: auto; }
.savebar.is-dirty .savebar-ic { color: var(--md-sys-color-primary); }
.savebar.is-saving :is(.savebar-ic, .cbtn) svg { animation: sp-spin .8s linear infinite; }
.savebar-acts[hidden] { display: none; }
.savebar.is-error .savebar-ic { color: var(--md-sys-color-error); }
.savebar.is-saved .savebar-ic, .savebar.is-saved .savebar-msg { color: var(--md-sys-color-on-success-container); }
.savebar.is-saved .savebar-acts { display: none; }
/* Résumé d'erreurs DANS la barre (Paramètres du compte) : centré au-dessus du message, il
   prend le focus après un échec ; chaque lien met le focus sur son champ. */
.savebar-errs { flex: 1 1 100%; display: flex; flex-direction: column; gap: 4px; padding: 4px 0 8px; border-bottom: 1px solid var(--md-sys-color-outline-variant); }
.savebar-errs[hidden] { display: none; }
.savebar-errs:focus { outline: 3px solid var(--md-sys-color-primary); outline-offset: 2px; border-radius: var(--md-sys-shape-corner-small); }
.savebar-errs-t { display: flex; align-items: center; gap: 6px; margin: 0; font: var(--md-sys-typescale-title-small); color: var(--md-sys-color-on-error-container); }
.savebar-errs-t svg { flex: none; width: 16px; height: 16px; }
.savebar-errs ul { margin: 0; padding: 0 0 0 22px; font: var(--md-sys-typescale-body-medium); }
.savebar-errs li a { color: var(--md-sys-color-on-surface); text-decoration: underline; text-underline-offset: 3px; }
@container savebar (max-width: 479px) {
  .savebar-msg { flex-basis: calc(100% - 32px); }
  .savebar-acts { flex: 1 1 100%; margin-left: 0; }
  .savebar-acts .cbtn { flex: 1 1 0; }
}
@media (max-width: 760px) {
  .savebar { bottom: calc(84px + 12px + env(safe-area-inset-bottom) - var(--home-pad-b, 104px)); }   /* au-dessus de la barre du bas */
}
/* Un champ qui prend le focus ne passe pas sous la barre (WCAG 2.4.11). */
.ds-app-content:has(.savebar:not([hidden])) { scroll-padding-bottom: 96px; }
@media (max-width: 760px) { .ds-app-content:has(.savebar:not([hidden])) { scroll-padding-bottom: 180px; } }

/* ── 7. LISTE DE DÉMARRAGE / GUIDE D'ÉTAPES (.checklist) ────────────────
   Une seule liste guidée : « Prépare ta chaîne » (tableau de bord, 5 étapes) et « Pour
   recevoir de l'argent » (Monétisation, 3 étapes). Dans un .sblk : l'en-tête porte le h2
   (tabindex=-1), la phrase et .checklist-count ; .prog role=progressbar facultatif dessous.
   ol.checklist > li.checklist-item[data-state] : grille [24 | texte | actions].
   data-state : todo (circle, bouton contour) ; next (fond primary 4 %, liseré 3 px primary,
   bouton rose, aria-current=step) ; done (circle-check success + « Fait ») ; skipped et
   not_needed (circle-dashed faint) ; pending (clock warning + « Reprendre »).
   Variante --numbered : la marque est une .numpill (.numpill--on pour l'étape en cours).
   Sous 560 px de largeur de liste, les actions passent sous le texte, calées à gauche. */
.sblk-head h2 { margin: 0; font: var(--md-sys-typescale-title-medium); font-weight: 600; color: var(--md-sys-color-on-surface); }   /* le même titre que h3 quand le bloc est une section de page */
.sblk-head h2:focus:not(:focus-visible) { outline: none; }
.checklist-count { flex: none; font: var(--md-sys-typescale-label-large); font-weight: 600; color: var(--md-sys-color-on-surface-variant); font-variant-numeric: tabular-nums; white-space: nowrap; }
.checklist { container: checklist / inline-size; list-style: none; margin: 0; padding: 0; }
.checklist-item { --cl-pad: 0px; position: relative; box-sizing: border-box; display: grid; grid-template-columns: 24px minmax(0, 1fr) auto; grid-template-areas: "mark txt act";
  align-items: center; gap: 12px 16px; min-height: 64px; padding: 12px var(--cl-pad); }
/* Filet entre deux étapes, toujours à la largeur du texte (même sous l'étape en cours qui déborde). */
.checklist-item + .checklist-item::before { content: ""; position: absolute; top: 0; left: var(--cl-pad); right: var(--cl-pad); height: 1px; background: var(--md-sys-color-outline-variant); }
.checklist-mark { grid-area: mark; display: flex; align-items: center; justify-content: center; width: 24px; height: 24px; color: var(--md-sys-color-on-surface-variant); }
.checklist-mark svg { width: 24px; height: 24px; }
.checklist-txt { grid-area: txt; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.checklist-name { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 8px; margin: 0; font: var(--md-sys-typescale-title-small); font-weight: 600; color: var(--md-sys-color-on-surface); }
.checklist-sub { margin: 0; font: var(--md-sys-typescale-body-small); color: var(--md-sys-color-on-surface-variant); }
.checklist-act { grid-area: act; display: flex; flex-wrap: wrap; align-items: center; justify-content: flex-end; gap: 8px; }
.checklist-done { display: inline-flex; align-items: center; gap: 4px; font: var(--md-sys-typescale-label-medium); font-weight: 600; color: var(--sp-brand-ink, var(--md-sys-color-primary)); }   /* rose SydePlay (07/10 : moins de couleurs) */
.checklist-item[data-state="next"] { background: color-mix(in srgb, var(--md-sys-color-primary) 4%, transparent); box-shadow: inset 3px 0 0 var(--md-sys-color-primary); }
.checklist-item[data-state="next"] .checklist-mark { color: var(--md-sys-color-primary); }
.checklist-item[data-state="done"] .checklist-mark { color: var(--sp-brand-ink, var(--md-sys-color-primary)); }
.checklist-item[data-state="done"] .checklist-name { color: var(--md-sys-color-on-surface-variant); }
.checklist-item:is([data-state="skipped"], [data-state="not_needed"]) .checklist-mark { color: var(--md-sys-color-on-surface-faint); }
.checklist-item[data-state="pending"] .checklist-mark { color: var(--md-sys-color-warning); }
.checklist--numbered .checklist-mark .numpill { flex: none; }
/* Dans un bloc : l'étape en cours touche les bords du bloc (comme .row-flag), le texte reste aligné. */
.sblk-body .checklist-item[data-state="next"] { --cl-pad: 20px; margin: 0 -20px; }
@media (max-width: 560px) { .sblk-body .checklist-item[data-state="next"] { --cl-pad: 16px; margin: 0 -16px; } }
@container checklist (max-width: 559px) {
  .checklist-item { grid-template-columns: 24px minmax(0, 1fr); grid-template-areas: "mark txt" ". act"; }
  .checklist-act { justify-content: flex-start; }
}

/* ── 8. CARTE KPI AVEC ÉVOLUTION (.statc--kpi, .statc-delta, .statc-link) ──
   Extension de .statc : le chiffre de la période et son évolution par rapport à la période
   d'avant. Bouton aria-pressed (choix de la courbe du tableau de bord, dans un role=group
   étiqueté) ou carte non interactive (div, Statistiques). La note réutilise .statc-sub.
   .statc-grid--kpi : 4 colonnes, 2 sous 560 px de grille (sans requête : la grille se plie
   seule). Statistiques garde .statc-grid (colonnes de 150) pour ses 6 cartes. */
.statc-grid--kpi { display: grid; grid-template-columns: repeat(auto-fill, minmax(clamp(calc(25% - 7px), (560px - 100%) * 999, calc(50% - 5px)), 1fr)); gap: 8px; }
.statc--kpi { position: relative; isolation: isolate; box-sizing: border-box; display: flex; flex-direction: column; gap: 4px; min-width: 0; color: var(--md-sys-color-on-surface); }
.statc--kpi .statc-ic { margin-bottom: 4px; }
.statc--kpi .statc-lbl, .statc--kpi .statc-sub { margin-top: 0; }
.statc--kpi .statc-val { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.statc--kpi:is(button, a) { width: 100%; font: inherit; text-align: left; text-decoration: none; cursor: pointer; }
.statc--kpi:is(button, a)::after { content: ""; position: absolute; inset: 0; border-radius: inherit; background: currentColor; opacity: 0; pointer-events: none; transition: opacity .15s ease; }
.statc--kpi:is(button, a):hover::after { opacity: var(--md-sys-state-hover-opacity); }
.statc--kpi:is(button, a):focus-visible::after { opacity: var(--md-sys-state-focus-opacity); }
.statc--kpi:is(button, a):active::after { opacity: var(--md-sys-state-pressed-opacity); }
.statc--kpi:is(button, a):focus-visible { outline: 3px solid var(--md-sys-color-primary); outline-offset: 2px; }
.statc--kpi[aria-pressed="true"] { border-color: var(--md-sys-color-primary); box-shadow: inset 0 0 0 1px var(--md-sys-color-primary);
  background: color-mix(in srgb, var(--md-sys-color-primary) 6%, var(--md-sys-color-surface)); }
.statc-val.is-na { font: var(--md-sys-typescale-title-medium); color: var(--md-sys-color-on-surface-variant); }   /* « Indisponible » */
.statc[aria-busy="true"] .statc-val svg { width: 18px; height: 18px; animation: sp-spin .8s linear infinite; }
/* Évolution : une pastille (signe, icône ET mot, plus la phrase entière en .sr-only). */
.statc-delta { align-self: flex-start; display: inline-flex; align-items: center; gap: 4px; height: 22px; box-sizing: border-box; padding: 0 8px;
  border-radius: var(--md-sys-shape-corner-small); font: var(--md-sys-typescale-label-medium); font-weight: 600; font-variant-numeric: tabular-nums; white-space: nowrap; }
.statc-delta svg { flex: none; width: 14px; height: 14px; }
.statc-delta--up { background: var(--md-sys-color-success-container); color: var(--md-sys-color-on-success-container); }          /* trending-up */
.statc-delta--down { background: var(--md-sys-color-error-container); color: var(--md-sys-color-on-error-container); }            /* trending-down */
.statc-delta--flat { background: var(--md-sys-color-surface-container-high); color: var(--md-sys-color-on-surface-variant); }     /* minus, « Stable » */
.statc-delta--new { background: var(--md-sys-color-primary-container); color: var(--md-sys-color-on-primary-container); }         /* sparkles, « Nouveau » */
.statc-link { margin-top: auto; padding-top: 8px; font: var(--md-sys-typescale-label-medium); }

/* ── 9. TABLEAU DE DONNÉES ÉTENDU (une seule famille d'extensions de .dstable) ──
   Gestion (Contenus : --manage), tri (Statistiques : --sort), cartes sur téléphone (--cards :
   Contenus, Statistiques, abonnés et bannis). Seuil UNIQUE des cartes : 640 px de largeur de
   tableau (requête de conteneur « dst » ; le .dstable-wrap devient conteneur dès que son
   tableau porte l'une de ces variantes, les autres tableaux du site ne changent pas).
   --manage : colonnes case et menu, débord de 12 px (motif repris de .subs-tbl), mode COMPACT
   de 640 à 1079 px (.c-access, .c-date, .c-num masqués ; .c-stats, .m-access, .s-date affichés).
   États de ligne : .is-clickable, .is-selected, .is-busy, .is-flash, .is-leaving ;
   wrap[aria-busy=true] = rechargement. Vraie <table>, <caption class="sr-only"> qui dit le tri. */
.dstable-wrap:has(> :is(.dstable--manage, .dstable--cards, .dstable--sort)) { container: dst / inline-size; }
.dstable-wrap:has(> .dstable--manage) { overflow: visible; }   /* les menus de ligne dépassent */
.dstable-wrap[aria-busy="true"] tbody { opacity: .6; }
.dstable--manage { width: calc(100% + 24px); margin: 0 -12px; }
:is(.dstable--manage, .dstable--sort) th { height: 44px; padding-top: 0; padding-bottom: 0; }
:is(.dstable--manage, .dstable--cards) td { white-space: normal; vertical-align: middle; padding-top: 12px; padding-bottom: 12px; }
/* En-tête triable : th[aria-sort] > button.dstable-sort (arrow-down, arrow-up, ou arrow-up-down à 50 %). */
.dstable-sort { position: relative; isolation: isolate; display: inline-flex; align-items: center; gap: 4px; height: 32px; padding: 0 4px; margin: 0 -4px; border: 0;
  border-radius: var(--md-sys-shape-corner-small); background: transparent; color: inherit; font: var(--md-sys-typescale-label-medium); font-weight: 600; white-space: nowrap; cursor: pointer; }
.dstable-sort svg { flex: none; width: 16px; height: 16px; }
.dstable-sort::after { content: ""; position: absolute; inset: 0; border-radius: inherit; background: currentColor; opacity: 0; pointer-events: none; transition: opacity .15s ease; }
.dstable-sort:hover::after { opacity: var(--md-sys-state-hover-opacity); }
.dstable-sort:active::after { opacity: var(--md-sys-state-pressed-opacity); }
.dstable-sort:focus-visible { outline: 3px solid var(--md-sys-color-primary); outline-offset: 0; }
th[aria-sort="none"] .dstable-sort svg { opacity: .5; }
th:is([aria-sort="ascending"], [aria-sort="descending"]) { color: var(--md-sys-color-on-surface); }
.dstable .dstable-num { text-align: right; font-variant-numeric: tabular-nums; min-width: 64px; }
.dstable th.dstable-num .dstable-sort { flex-direction: row-reverse; }
/* Case de sélection : 44 × 44 (boîte .ex-box de 20 au centre). */
.dstable :is(th, td).dstable-check { width: 44px; padding: 0; }
.dstable-check .ex-check--box { width: 44px; height: 44px; align-items: center; justify-content: center; vertical-align: middle; }
.dstable-check .ex-check--box input { left: 0; top: 0; width: 100%; height: 100%; }
.dstable-check .ex-check--box .ex-box { margin-top: 0; }
/* Cellule média : vignette 16:9 + titre (lien, 2 lignes) + méta. */
.dstable-media { display: flex; align-items: center; gap: 12px; min-width: 0; }
.dstable-media-txt { min-width: 0; display: flex; flex-direction: column; }
.dstable-thumb { position: relative; flex: none; display: grid; place-items: center; width: 96px; aspect-ratio: 16 / 9; overflow: hidden;
  border-radius: var(--md-sys-shape-corner-small); background: linear-gradient(135deg, var(--md-sys-color-surface-container-high), var(--md-sys-color-surface-container-highest));
  font: var(--md-sys-typescale-title-medium); font-weight: 700; color: var(--md-sys-color-on-surface-faint); }
.dstable-thumb img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; display: block; }
.dstable-thumb--sm { width: 64px; }
.dstable-thumb--lg { width: 128px; }
.dstable-title { font: var(--md-sys-typescale-title-small); font-weight: 600; color: var(--md-sys-color-on-surface); text-decoration: none; overflow-wrap: anywhere;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.dstable-title:is(:hover, :focus-visible) { text-decoration: underline; text-underline-offset: 3px; }
.dstable-title:focus-visible { outline: 3px solid var(--md-sys-color-primary); outline-offset: 2px; border-radius: var(--md-sys-shape-corner-extra-small); }
/* Séparateur « · » muet pour les lecteurs d'écran, centré dans l'écart de 16 À GAUCHE de chaque
   élément (position absolue). Quand la méta passe à la ligne, l'élément qui ouvre la nouvelle ligne
   a son « · » hors de la boîte, à gauche : overflow-x: clip le rogne, la ligne ne commence jamais
   par un séparateur (refonte du Studio). */
.dstable-meta { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 16px; margin-top: 2px; overflow-x: clip; font: var(--md-sys-typescale-body-small); color: var(--md-sys-color-on-surface-variant); }
.dstable-meta > * { position: relative; display: inline-flex; align-items: center; gap: 4px; }
.dstable-meta svg { flex: none; width: 14px; height: 14px; }
.dstable-meta > * + *::before { content: "·"; content: "·" / ""; position: absolute; top: 0; bottom: 0; right: 100%; width: 16px;
  display: flex; align-items: center; justify-content: center; color: var(--md-sys-color-on-surface-faint); }
.dstable-sub { display: block; margin-top: 2px; font: var(--md-sys-typescale-body-small); color: var(--md-sys-color-on-surface-variant); }
/* Date : ne se coupe jamais (« 28 / sept. ») ; td.dstable-date, et la colonne .c-date de --manage. */
.dstable td.dstable-date, .dstable--manage td.c-date { white-space: nowrap; }
.dstable :is(th, td).dstable-menu { width: 52px; text-align: right; }
.dstable-menu .ibtn { margin: 0; vertical-align: middle; }
.dstable-more { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 8px 12px; padding: 12px 20px; font: var(--md-sys-typescale-body-small); color: var(--md-sys-color-on-surface-variant); }
/* États de ligne. */
.dstable tr.is-clickable { cursor: pointer; }
.dstable tbody tr.is-selected td { background: var(--md-sys-color-secondary-container); }
.dstable tr.is-busy { opacity: .6; pointer-events: none; }
.dstable tr.is-flash td { animation: sp-flash 2s ease-out forwards; }
@keyframes sp-flash { from { background-color: var(--md-sys-color-primary-container); } to { background-color: transparent; } }
.dstable tr.is-leaving { opacity: 0; transform: translateX(12px); transition: opacity .2s ease, transform .2s ease; }
/* --manage : colonnes du mode compact masquées en grand. */
.dstable--manage :is(.c-stats, .m-access, .s-date) { display: none; }
@container dst (max-width: 1079px) {
  .dstable--manage :is(.c-access, .c-date, .c-num) { display: none; }
  .dstable--manage :is(.c-stats, .m-access, .s-date) { display: revert; }
  .dstable--manage .dstable-thumb--lg { width: 96px; }
}
/* --cards : une carte par ligne sous 640 px de largeur de tableau. Ligne en grille :
   cellule principale (td[data-cell="main"] ou la cellule média) en haut à gauche, menu en
   haut à droite, les autres cellules dessous en pleine largeur, précédées de leur data-label.
   La case de sélection n'apparaît que sous un ancêtre .is-selecting. */
@container dst (max-width: 639px) {
  .dstable.dstable--cards { display: block; width: 100%; margin: 0; }
  .dstable--cards thead { display: none; }
  .dstable--cards tbody { display: block; }
  .dstable--cards tr { display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: center; gap: 8px 12px; padding: 12px 0; border-bottom: 1px solid var(--md-sys-color-outline-variant); }
  .dstable.dstable--cards :is(td, td:first-child, td:last-child) { display: block; grid-column: 1 / -1; padding: 0; border: 0; white-space: normal; }
  .dstable.dstable--cards :is(td[data-cell="main"], td:has(> .dstable-media)) { grid-column: 1; grid-row: 1; }
  .dstable.dstable--cards :is(td[data-cell="menu"], td.dstable-menu) { grid-column: 2; grid-row: 1; justify-self: end; width: auto; }
  .dstable.dstable--cards tr:not(:has(> :is([data-cell="menu"], .dstable-menu))) > :is([data-cell="main"], td:has(> .dstable-media)) { grid-column: 1 / -1; }
  .dstable.dstable--cards td[data-label] { display: flex; align-items: baseline; gap: 8px; }
  .dstable--cards td[data-label]::before { content: attr(data-label); flex: none; min-width: 64px; font: var(--md-sys-typescale-label-medium); color: var(--md-sys-color-on-surface-variant); text-align: left; }
  /* En cartes, libellé puis valeur calés à gauche, même pour une colonne chiffrée ; une date reste d'un bloc. */
  .dstable.dstable--cards td.dstable-num { text-align: left; }
  .dstable.dstable--cards td.dstable-date { white-space: nowrap; }
  .dstable.dstable--cards td.dstable-check { display: none; }
  .dstable--cards tbody tr:hover td, .dstable--cards tbody tr.is-selected td { background: none; }
  .dstable--cards tbody tr.is-selected { background: var(--md-sys-color-secondary-container); }
  .dstable--cards .ibtn { flex: none; }
  /* Sélection en cours : la case revient, en tête, sur toute la hauteur de la carte. */
  :is(.is-selecting .dstable--cards, .dstable--cards.is-selecting) tr { grid-template-columns: 44px minmax(0, 1fr) auto; }
  :is(.is-selecting .dstable--cards, .dstable--cards.is-selecting) td.dstable-check { display: block; grid-column: 1; grid-row: 1 / span 3; align-self: start; }
  :is(.is-selecting .dstable--cards, .dstable--cards.is-selecting) td:not(.dstable-check) { grid-column: 2 / -1; }
  :is(.is-selecting .dstable--cards, .dstable--cards.is-selecting) :is(td[data-cell="main"], td:has(> .dstable-media)) { grid-column: 2; }
  :is(.is-selecting .dstable--cards, .dstable--cards.is-selecting) :is(td[data-cell="menu"], td.dstable-menu) { grid-column: 3; }
  /* --manage en cartes : la cellule média s'efface pour poser la vignette (112, 96 en
     sélection) à gauche du titre et de la méta. */
  .dstable--cards.dstable--manage tr { grid-template-columns: 112px minmax(0, 1fr) 44px; }
  .dstable.dstable--cards.dstable--manage td:has(> .dstable-media), .dstable--cards.dstable--manage .dstable-media { display: contents; }
  .dstable--cards.dstable--manage .dstable-thumb { grid-column: 1; grid-row: 1 / span 2; width: 112px; }
  .dstable--cards.dstable--manage .dstable-media-txt { grid-column: 2; grid-row: 1 / span 2; }
  .dstable.dstable--cards.dstable--manage td.dstable-menu { grid-column: 3; grid-row: 1; }
  .dstable--cards.dstable--manage :is(.c-stats, .m-access, .s-date) { display: revert; }
  .dstable.dstable--cards.dstable--manage :is(td.c-access, td.c-date, td.c-num) { display: none; }
  :is(.is-selecting .dstable--cards, .dstable--cards.is-selecting).dstable--manage tr { grid-template-columns: 44px 96px minmax(0, 1fr) 44px; }
  :is(.is-selecting .dstable--cards, .dstable--cards.is-selecting).dstable--manage td.dstable-check { grid-row: 1 / span 2; }
  :is(.is-selecting .dstable--cards, .dstable--cards.is-selecting).dstable--manage .dstable-thumb { grid-column: 2; width: 96px; }
  :is(.is-selecting .dstable--cards, .dstable--cards.is-selecting).dstable--manage .dstable-media-txt { grid-column: 3; }
  :is(.is-selecting .dstable--cards, .dstable--cards.is-selecting).dstable--manage td.dstable-menu { grid-column: 4; }
  /* Dans un bloc à bord perdu (.sblk-body--flush) : la carte garde 16 px de chaque côté. */
  .sblk-body--flush .dstable--cards tr { padding-left: 16px; padding-right: 16px; }
  .sblk-body--flush .dstable--cards tr:last-child { border-bottom: 0; }
}

/* ── 10. BARRE D'ACTIONS GROUPÉES (.bulkbar) ────────────────────────────
   Contenus : dès qu'au moins une ligne est cochée, elle remplace la .lhead dans
   .ds-sticky-head (la .lhead reste dans le DOM, masquée). Ordre : .ibtn x « Tout
   désélectionner », .bulkbar-count (aria-live polite, atomic), actions .cbtn--contour à
   icône 18, .bulkbar-note. role=toolbar, tabindex itinérant aux flèches.
   --dock (téléphone, mode sélection) : posée au-dessus de la barre du bas, élévation 3 ;
   les actions se regroupent dans « Actions » (chevron-up) qui ouvre un .menu.tbar-dd-panel--up. */
.bulkbar { display: flex; align-items: center; gap: 8px; box-sizing: border-box; height: 44px; padding: 0 4px 0 0; min-width: 0;
  border-radius: var(--md-sys-shape-corner-medium); background: var(--md-sys-color-secondary-container); color: var(--md-sys-color-on-secondary-container);
  animation: sp-fade-in .15s ease-out; }
.bulkbar[hidden] { display: none; }
.bulkbar > .ibtn { flex: none; color: inherit; }
.bulkbar-count { flex: none; margin-right: 4px; font: var(--md-sys-typescale-label-large); font-variant-numeric: tabular-nums; white-space: nowrap; }
.bulkbar .cbtn--contour { flex: none; color: inherit; }
.bulkbar-note { min-width: 0; font: var(--md-sys-typescale-label-small); color: inherit; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.bulkbar-acts { position: relative; flex: none; display: inline-flex; }   /* repère du menu « Actions » (--dock) */
.bulkbar--dock { position: fixed; left: 16px; right: 16px; bottom: calc(84px + 8px + env(safe-area-inset-bottom)); z-index: 46;
  justify-content: space-between; padding: 0 4px; box-shadow: var(--md-sys-elevation-level3); }
.ds-app-content:has(.bulkbar--dock:not([hidden])) { scroll-padding-bottom: calc(84px + 60px + 16px); }

/* ── 11. GROUPE CONNECTÉ · compteur et pleine largeur (extension de .ex-seg) ──
   Files de commentaires, vue Actifs / Bannis, période, filtre des codes. Hauteur 40
   inchangée ; role=group + aria-label, aria-pressed sur chaque bouton ; la pastille est
   complétée par un .sr-only (« , 3 à examiner »). --fill : parts égales sur toute la largeur. */
.ex-seg button .count { margin-left: 0; color: inherit; }
.ex-seg button .tbar-dot { position: static; flex: none; }
.ex-seg button.on .tbar-dot { background: var(--md-sys-color-primary); color: var(--md-sys-color-on-primary); }
.ex-seg--fill { display: flex; width: 100%; }
.ex-seg--fill button { flex: 1 1 0; min-width: 0; padding: 0 12px; }

/* ── 12. BOUTON BASCULE « Sélectionner » (extension de .ex-selbtn) ───────
   .ex-selbtn[aria-pressed=true] prend le contour primary, comme quand son menu est ouvert.
   .lhead-select (bouton « Sélectionner » de la barre de liste) n'existe que sous 640 px de
   largeur de barre (requête de conteneur lhead). */
.ex-selbtn[aria-pressed="true"] { border-color: var(--md-sys-color-primary); }
.lhead-select { display: none; }
@container lhead (max-width: 639px) { .lhead-select { display: inline-flex; } }

/* ── 13. SOMMAIRE LATÉRAL À ANCRES (.secnav) ────────────────────────────
   Navigation entre les sections d'une page de réglages longue (scroll-spy :
   shared/settings-layout.js). Vrais liens href="#id" ; actif = aria-current
   (« true » ou « location ») : fond secondary-container, texte on-secondary-container,
   600 (volontairement différent du rail, en fond inversé). Collé en haut de .ds-app-content.
   Pastille .secnav-meta (« Modifié » .bdg--orange, « À corriger » .bdg--red) ou point
   .secnav-dot (modifications non enregistrées, doublé d'un .sr-only). Sur téléphone : pas de
   sommaire, la liste .srub-grid puis la section (voir .setl). */
.secnav { position: sticky; top: 0; align-self: start; min-width: 0; max-height: calc(100dvh - 136px); overflow-y: auto; scrollbar-width: thin; }
.secnav-list { display: flex; flex-direction: column; gap: 4px; margin: 0; padding: 0; list-style: none; }
.secnav-item { position: relative; isolation: isolate; display: flex; align-items: center; gap: 12px; height: 44px; padding: 0 12px; box-sizing: border-box;
  border-radius: var(--md-sys-shape-corner-medium); color: var(--md-sys-color-on-surface-variant); font: var(--md-sys-typescale-label-large); text-decoration: none; }
.secnav-item svg { flex: none; width: 20px; height: 20px; }
.secnav-item::after { content: ""; position: absolute; inset: 0; border-radius: inherit; background: currentColor; opacity: 0; pointer-events: none; transition: opacity .15s ease; }
.secnav-item:hover::after { opacity: var(--md-sys-state-hover-opacity); }
.secnav-item:focus-visible::after { opacity: var(--md-sys-state-focus-opacity); }
.secnav-item:active::after { opacity: var(--md-sys-state-pressed-opacity); }
.secnav-item:focus-visible { outline: 3px solid var(--md-sys-color-primary); outline-offset: -3px; }   /* -3 : le sommaire défile, un anneau extérieur serait rogné */
.secnav-item[aria-current]:not([aria-current="false"]) { background: var(--md-sys-color-secondary-container); color: var(--md-sys-color-on-secondary-container); font-weight: 600; }
.secnav-label { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.secnav-meta { flex: none; display: inline-flex; }
.secnav-dot { flex: none; display: inline-block; width: 8px; height: 8px; border-radius: var(--md-sys-shape-corner-full); background: var(--md-sys-color-primary); }
.secnav-dot[hidden] { display: none; }
.srub-name .secnav-dot { margin-left: 8px; vertical-align: 2px; }
.srub-name .bdg { margin-left: 6px; vertical-align: 1px; }   /* « Modifié » / « À corriger » dans la liste du téléphone */   /* même point dans la liste du téléphone */

/* ── 13b. MISE EN PAGE DES PARAMÈTRES (.setl) ───────────────────────────
   Partagée par /settings (9 sections) et Studio › Paramètres. div.setl[data-mode][data-view]
   > nav.secnav + div.setl-main > section.setl-sec#id (+ la .savebar en dernier enfant).
   data-mode est posé par shared/settings-layout.js (ResizeObserver sur .setl) : « split » à
   partir de 720 px de LARGEUR DE .setl (seuil unique), sinon « stack ». Sans data-mode (script
   pas encore passé), tout s'affiche en une colonne, sans sommaire.
   split : grille [sommaire 220 | contenu 880 au plus], calée à gauche (aucune marge ajoutée,
   pas de largeur max centrée), écart 24 (32 sur grand écran).
   stack : pas de sommaire ; data-view="list" montre la liste .srub-grid (enfant direct de
   .setl) et cache les sections ; data-view="section" ne montre que la section .is-open, avec
   son lien retour .setl-back. */
.setl { display: grid; grid-template-columns: minmax(0, 1fr); gap: 24px; align-items: start; }
.setl[data-mode="split"] { grid-template-columns: var(--setl-nav, 220px) minmax(0, var(--setl-max, 880px)); justify-content: start; }
@media (min-width: 1280px) { .setl[data-mode="split"] { column-gap: 32px; } }
.setl:not([data-mode="split"]) > .secnav { display: none; }
.setl > :is(.setl-list, .srub-grid) { display: none; }
.setl-sec[hidden], .setl-back[hidden] { display: none; }
.setl-main { min-width: 0; display: flex; flex-direction: column; gap: 48px; }
.setl-sec { min-width: 0; display: flex; flex-direction: column; gap: 16px; scroll-margin-top: 16px; }
.setl-sec-head { display: flex; flex-direction: column; align-items: flex-start; gap: 4px; }
.setl-sec-title { margin: 0; font: var(--md-sys-typescale-headline-small); font-weight: 700; letter-spacing: -0.01em; color: var(--md-sys-color-on-surface); }
.setl-sec-title:focus:not(:focus-visible) { outline: none; }
.setl-sec-title:focus-visible { outline: 3px solid var(--md-sys-color-primary); outline-offset: 4px; border-radius: var(--md-sys-shape-corner-extra-small); }
.setl-sec-sub { margin: 0; font: var(--md-sys-typescale-body-medium); color: var(--md-sys-color-on-surface-variant); }
.setl-back { display: none; min-height: 44px; }   /* .lnk.lnk--ink + arrow-left « Paramètres » */
/* Séparateur du sommaire, avant « Zone sensible » : li.setl-sep aria-hidden. */
.setl-sep { height: 1px; margin: 8px 12px; background: var(--md-sys-color-outline-variant); }
/* Dans les réglages, l'en-tête des blocs n'a pas de filet (comme dans .srw). */
.setl .sblk-head { border-bottom: 0; padding-bottom: 2px; }
.setl[data-mode="stack"][data-view="list"] > :is(.setl-list, .srub-grid):not([hidden]) { display: grid; }
.setl[data-mode="stack"][data-view="list"] .setl-sec { display: none; }
.setl[data-mode="stack"][data-view="section"] .setl-sec:not(.is-open) { display: none; }
.setl[data-mode="stack"][data-view="section"] .setl-back { display: inline-flex; }
/* Téléphone : la barre d'enregistrement est posée au-dessus de la barre du bas, visible
   aussi depuis la liste. */
@media (max-width: 760px) {
  .setl .savebar { position: fixed; left: 16px; right: 16px; bottom: calc(84px + 8px + env(safe-area-inset-bottom)); }
}

/* ── 14. LIGNE DE MODÉRATION (.modrow) ──────────────────────────────────
   Un commentaire à trancher (Garder, Masquer ou Réafficher, Supprimer) ou une publication
   signalée regroupée (--pub). article.modrow (aria-labelledby, aria-describedby) dans
   .modrow-list, elle-même dans .sblk-body--rows. Ligne qui attend : + .row-flag (existant),
   toujours avec son badge texte. .is-hidden : texte en on-surface-variant (jamais
   d'opacité sur le texte). Sous 640 px, les actions prennent toute la largeur. */
.modrow-list { display: flex; flex-direction: column; margin: 0; padding: 0; list-style: none; }
.modrow { display: flex; flex-direction: column; gap: 8px; min-width: 0; padding: 16px 0; border-top: 1px solid var(--md-sys-color-outline-variant); }
.modrow-list > .modrow:first-child, .modrow-list > :first-child > .modrow { border-top: 0; }
.modrow-head { display: flex; align-items: center; gap: 12px; min-width: 0; }
.modrow-head > .ava { flex: none; }
.modrow-thumb { position: relative; flex: none; display: grid; place-items: center; width: 112px; aspect-ratio: 16 / 9; overflow: hidden;
  border-radius: var(--md-sys-shape-corner-small); background: var(--md-sys-color-surface-container-high);
  font: var(--md-sys-typescale-title-medium); font-weight: 700; color: var(--md-sys-color-on-surface-faint); }
.modrow-thumb img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; display: block; }
.modrow-who { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; align-items: flex-start; gap: 2px; }
.modrow-name { max-width: 100%; padding: 0; border: 0; background: none; font: var(--md-sys-typescale-title-small); color: var(--md-sys-color-on-surface);
  text-align: left; text-decoration: none; cursor: pointer; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; overflow-wrap: anywhere; }
.modrow-name:hover { text-decoration: underline; text-underline-offset: 3px; }
.modrow-name:focus-visible { outline: 3px solid var(--md-sys-color-primary); outline-offset: 2px; border-radius: var(--md-sys-shape-corner-extra-small); }
.modrow-meta { font: var(--md-sys-typescale-label-medium); color: var(--md-sys-color-on-surface-variant); }
.modrow-badges { flex: 0 1 auto; margin-left: auto; display: flex; flex-wrap: wrap; justify-content: flex-end; gap: 6px; }
.modrow-more { flex: none; border-radius: var(--md-sys-shape-corner-small); }
.modrow-more::after { inset: 6px; }
.modrow-more:focus-visible { outline-offset: -3px; }
.modrow-body { margin: 0; font: var(--md-sys-typescale-body-medium); color: var(--md-sys-color-on-surface); white-space: pre-wrap; overflow-wrap: anywhere; }
.modrow-body.is-clamped { display: -webkit-box; -webkit-line-clamp: 8; -webkit-box-orient: vertical; overflow: hidden; }
.modrow-foot { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 12px; min-width: 0; }
.modrow-ctx { display: inline-flex; align-items: center; gap: 6px; min-width: 0; max-width: 100%; min-height: 24px;
  font: var(--md-sys-typescale-label-medium); color: var(--md-sys-color-on-surface-variant); text-decoration: none; }
.modrow-ctx svg { flex: none; width: 14px; height: 14px; }
.modrow-ctx > span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.modrow-ctx:hover { color: var(--md-sys-color-primary); }
.modrow-ctx:focus-visible { outline: 3px solid var(--md-sys-color-primary); outline-offset: 2px; border-radius: var(--md-sys-shape-corner-extra-small); }
.modrow-foot .lnk { min-height: 24px; }
.modrow-acts { margin-left: auto; display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.modrow-reply { margin-top: 4px; display: flex; flex-direction: column; gap: 8px; }
.modrow-reply[hidden] { display: none; }
.modrow-help { display: flex; align-items: flex-start; justify-content: space-between; gap: 8px; font: var(--md-sys-typescale-body-small); color: var(--md-sys-color-on-surface-variant); }
.modrow-sublist { margin: 0; padding: 0 0 0 calc(112px + 12px); list-style: none; }
.modrow-sublist[hidden] { display: none; }
.modrow-sublist > li { padding: 8px 0; border-top: 1px solid var(--md-sys-color-outline-variant); }
.modrow-sub-h { display: flex; align-items: baseline; gap: 8px; font: var(--md-sys-typescale-label-large); color: var(--md-sys-color-on-surface); }
.modrow-sub-h > :last-child:not(:first-child) { margin-left: auto; font: var(--md-sys-typescale-label-medium); color: var(--md-sys-color-on-surface-variant); }
.modrow-sublist p { margin: 4px 0 0; font: var(--md-sys-typescale-body-small); color: var(--md-sys-color-on-surface-variant); white-space: pre-wrap; overflow-wrap: anywhere; }
.modrow.row-flag { margin: 0 -20px; padding-left: 20px; padding-right: 20px; }
.modrow.is-hidden .modrow-body { color: var(--md-sys-color-on-surface-variant); }
.modrow[aria-busy="true"] { cursor: progress; }
.modrow.is-leaving { opacity: 0; transform: translateX(12px); transition: opacity .2s ease, transform .2s ease; }
@media (max-width: 640px) {
  .modrow-acts { width: 100%; margin-left: 0; }
  .modrow-acts .cbtn { flex: 1 1 0; }
}
@media (max-width: 560px) {
  .modrow-thumb { width: 88px; }
  .modrow-sublist { padding-left: 0; }
  .modrow.row-flag { margin: 0 -16px; padding-left: 16px; padding-right: 16px; }
}
/* Liste étroite (refonte du Studio, À valider) : .modrow-list est la requête de conteneur « modrow ».
   Sous 560 px de liste, les badges prennent leur propre ligne, pleine largeur, sous le nom (calés sur
   lui : avatar 30 ou 44, vignette 88, + 12) ; le ⋯ reste sur la 1re ligne. Badges vides : masqués. */
.modrow-list { container: modrow / inline-size; }
.modrow-badges:empty { display: none; }
@container modrow (max-width: 559px) {
  .modrow-head { --modrow-lead: 30px; flex-wrap: wrap; row-gap: 8px; }
  .modrow-head:has(> .ava:not(.ava--sm)) { --modrow-lead: 44px; }
  .modrow-head:has(> .modrow-thumb) { --modrow-lead: 88px; }
  .modrow-who { flex: 1 1 0; }
  .modrow-badges { order: 3; flex: 1 1 100%; justify-content: flex-start; margin-left: calc(var(--modrow-lead) + 12px); }
  .modrow-thumb { width: 88px; }
}

/* ── 15. GRAPHIQUE INTERACTIF (.chart-head, .chart-tip, .chart-cursor, .chart-dot, .chart-data) ──
   Le rendu validé le 25/09 ne change pas ; on ajoute la légende et le total au-dessus, la
   bulle au survol, au toucher et au clavier (shared/charts.js : enhanceChart), et
   l'alternative en tableau. figure.chart tabindex=0 role=group + aria-describedby vers la
   consigne ; région .sr-only polite pour l'annonce. La bulle reste dans le cadre
   (--start / --end près des bords) et ne capte pas le pointeur. */
.chart-head { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 4px 12px; margin: 0 0 12px; }
/* chartHeadHTML() rend <span><i.chart-key>libellé</span><b>total</b> : mêmes styles que .chart-name / .chart-total. */
.chart-head > span, .chart-name { display: inline-flex; align-items: center; gap: 8px; min-width: 0; margin: 0; font: var(--md-sys-typescale-label-large); color: var(--md-sys-color-on-surface); }
.chart-key { flex: none; display: inline-block; width: 10px; height: 10px; border-radius: var(--md-sys-shape-corner-extra-small); color: var(--md-sys-color-primary); background: currentColor; }
.chart-head > b, .chart-total { margin: 0; font: var(--md-sys-typescale-title-medium); font-variant-numeric: tabular-nums; color: var(--md-sys-color-on-surface); }
figure.chart[tabindex]:focus-visible { outline: 3px solid var(--md-sys-color-primary); outline-offset: 4px; border-radius: var(--md-sys-shape-corner-small); }
.chart-cursor { position: absolute; top: 0; bottom: 0; width: 1px; margin-left: -.5px; background: var(--md-sys-color-outline); pointer-events: none; }
.chart-dot { position: absolute; width: 10px; height: 10px; box-sizing: border-box; border-radius: var(--md-sys-shape-corner-full); background: var(--md-sys-color-primary);
  box-shadow: 0 0 0 2px var(--md-sys-color-surface); transform: translate(-50%, -50%); pointer-events: none; }
:is(.chart-cursor, .chart-dot, .chart-tip)[hidden] { display: none; }
.chart-bars i { transition: opacity .15s ease; }
.chart:is(.is-active, [data-active]) .chart-bars i:not(.is-active, .is-on) { opacity: .55; }   /* enhanceChart : figure[data-active], barre active .is-active ; les autres à 55 % */
.chart-tip { position: absolute; z-index: 2; display: flex; flex-direction: column; gap: 2px; padding: 6px 8px; border-radius: var(--md-sys-shape-corner-extra-small);
  background: var(--md-sys-color-inverse-surface); color: var(--md-sys-color-inverse-on-surface); box-shadow: var(--md-sys-elevation-level2);
  white-space: nowrap; pointer-events: none; transform: translate(-50%, calc(-100% - 12px)); }
.chart-tip--start { transform: translate(0, calc(-100% - 12px)); }
.chart-tip--end { transform: translate(-100%, calc(-100% - 12px)); }
.chart-tip > span, .chart-tip-date { font: var(--md-sys-typescale-label-small); }
.chart-tip > b, .chart-tip-val { font: var(--md-sys-typescale-label-large); font-weight: 600; font-variant-numeric: tabular-nums; }
.chart-data { margin-top: 12px; }
.chart-data + .dstable-wrap { margin-top: 8px; }

/* ── 16. CARTE DE CHOIX EN LIGNE, CARTE D'ACTION, PANNEAU RÉVÉLÉ (extension de .choice) ──
   Choix exclusif décrit (Quand ?, Qui peut la voir ?) : .choice-list de .choice--row, radio
   caché + .choice-card en ligne (.ex-dot + .choice-txt). .choice-panel : ce que révèle
   l'option cochée (aligné sur les textes, hidden sinon ; aria-controls de l'input vers lui).
   .choice--action : la carte est un <button> qui navigue (écran de type). */
.choice-list { display: flex; flex-direction: column; gap: 8px; }
.choice--row .choice-card { flex-direction: row; align-items: center; gap: 12px; min-height: 64px; padding: 12px 16px; }
.choice--row .ex-dot { margin-top: 0; }
.choice-txt { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.choice:has(> input:disabled) { cursor: not-allowed; }
.choice:has(> input:disabled) .choice-card { opacity: var(--md-sys-state-disabled-opacity); }
.choice:has(> input:disabled):hover .choice-card { border-color: var(--md-sys-color-outline-variant); }
.choice-panel { padding-left: 48px; }
.choice-panel[hidden] { display: none; }
.choice--action .choice-card { position: relative; isolation: isolate; width: 100%; height: 100%; font: inherit; text-align: left; cursor: pointer; }
.choice--action .choice-card::after { content: ""; position: absolute; inset: 0; border-radius: inherit; background: currentColor; opacity: 0; pointer-events: none; transition: opacity .15s ease; }
.choice--action .choice-card:hover::after { opacity: var(--md-sys-state-hover-opacity); }
.choice--action .choice-card:active::after { opacity: var(--md-sys-state-pressed-opacity); }
.choice--action .choice-card:focus-visible { outline: 3px solid var(--md-sys-color-primary); outline-offset: 2px; }
.choice--action .choice-card:disabled { opacity: var(--md-sys-state-disabled-opacity); cursor: not-allowed; }

/* ── 17. BARRE D'ÉTAPES À LIBELLÉS (.wiz-steps) ─────────────────────────
   Étapes nommées du compositeur (remplace .wiz-progress / .wiz-step, gardés tant que
   l'ancienne page existe). nav[aria-label] > ol.wiz-steps > li.wiz-steps-it
   (.is-done | .is-current | .is-error | .is-todo) > button.wiz-steps-btn (span pour une
   étape à venir, aria-disabled) : barre de 4 en tête, puis .wiz-steps-lbl (check, circle-alert
   ou .wiz-steps-n, et le nom). Cible de 44. --compact : .wiz-steps-sum (bouton de 44,
   « Étape 2 sur 5 · Œuvre », chevron-down) au-dessus de segments de 4 ; il ouvre un .menu. */
.wiz-steps { display: grid; grid-auto-flow: column; grid-auto-columns: minmax(72px, 1fr); gap: 8px; margin: 0; padding: 0; list-style: none; }
.wiz-steps-it { min-width: 0; }
.wiz-steps-btn { position: relative; isolation: isolate; box-sizing: border-box; display: flex; flex-direction: column; gap: 8px; width: 100%; min-height: 44px; padding: 8px 0 4px;
  border: 0; border-radius: var(--md-sys-shape-corner-small); background: none; color: var(--md-sys-color-on-surface-variant); font: var(--md-sys-typescale-label-large); text-align: left; }
.wiz-steps-btn::before { content: ""; display: block; height: 4px; border-radius: var(--md-sys-shape-corner-full); background: var(--md-sys-color-surface-container-highest); transition: background-color .2s ease; }
button.wiz-steps-btn { cursor: pointer; }
button.wiz-steps-btn::after { content: ""; position: absolute; inset: 16px -6px 0; border-radius: var(--md-sys-shape-corner-small); background: currentColor; opacity: 0; pointer-events: none; transition: opacity .15s ease; }
button.wiz-steps-btn:hover::after { opacity: var(--md-sys-state-hover-opacity); }
button.wiz-steps-btn:active::after { opacity: var(--md-sys-state-pressed-opacity); }
.wiz-steps-btn:focus-visible { outline: 3px solid var(--md-sys-color-primary); outline-offset: 2px; }
.wiz-steps-lbl { display: flex; align-items: center; gap: 6px; min-width: 0; }
.wiz-steps-lbl svg { flex: none; width: 16px; height: 16px; }
.wiz-steps-lbl > span:last-child { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.wiz-steps-n { flex: none; min-width: 16px; text-align: center; font-variant-numeric: tabular-nums; }
.wiz-steps-it:is(.is-done, .is-current) .wiz-steps-btn::before { background: var(--md-sys-color-primary); }
.wiz-steps-it.is-error .wiz-steps-btn::before { background: var(--md-sys-color-error); }
.wiz-steps-it.is-current .wiz-steps-btn { color: var(--md-sys-color-on-surface); font-weight: 700; }
.wiz-steps-it.is-error .wiz-steps-btn { color: var(--md-sys-color-on-error-container); }
.wiz-steps-sum { position: relative; isolation: isolate; display: flex; align-items: center; gap: 8px; height: 44px; padding: 0 12px; margin: 0 -12px 4px; border: 0;
  border-radius: var(--md-sys-shape-corner-medium); background: transparent; color: var(--md-sys-color-on-surface); font: var(--md-sys-typescale-label-large); cursor: pointer; }
.wiz-steps-sum svg { flex: none; width: 18px; height: 18px; color: var(--md-sys-color-on-surface-variant); transition: transform .2s ease; }
.wiz-steps-sum[aria-expanded="true"] svg { transform: rotate(180deg); }
.wiz-steps-sum::after { content: ""; position: absolute; inset: 0; border-radius: inherit; background: currentColor; opacity: 0; pointer-events: none; transition: opacity .15s ease; }
.wiz-steps-sum:hover::after { opacity: var(--md-sys-state-hover-opacity); }
.wiz-steps-sum:focus-visible { outline: 3px solid var(--md-sys-color-primary); outline-offset: 2px; }
.wiz-steps--compact { grid-auto-columns: minmax(0, 1fr); gap: 4px; }
.wiz-steps--compact .wiz-steps-btn { min-height: 0; padding: 0; gap: 0; pointer-events: none; }
.wiz-steps--compact .wiz-steps-btn::after { display: none; }
.wiz-steps--compact .wiz-steps-lbl { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; }

/* ── 18. BARRE D'ACTIONS D'ÉTAPES COLLANTE (.actbar) ────────────────────
   Précédent / Continuer / Publier et la progression d'envoi du compositeur, toujours
   atteignables. Ce n'est PAS la barre « modifications non enregistrées » (.savebar).
   Collée au vrai bas de la zone de contenu (bottom = moins la marge basse --home-pad-b) ;
   sur téléphone hors mode focus, au-dessus de la barre du bas. Barre, pas un contrôle :
   ses boutons font 44. Les champs ne passent pas dessous (scroll-padding, WCAG 2.4.11). */
.actbar { position: sticky; bottom: calc(-1 * var(--home-pad-b, 60px)); z-index: 20; box-sizing: border-box; display: flex; flex-wrap: wrap; align-items: center; gap: 12px 16px;
  padding: 16px 0 calc(16px + env(safe-area-inset-bottom)); background: var(--md-sys-color-surface); border-top: 1px solid var(--md-sys-color-outline-variant); }
.actbar-start { flex: 1 1 auto; min-width: 0; display: flex; flex-wrap: wrap; align-items: center; gap: 8px 12px; }
.actbar-start .prog { flex: 1 1 120px; max-width: 240px; }
.actbar-end { flex: none; margin-left: auto; display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.actbar-msg { margin: 0; font: var(--md-sys-typescale-body-small); color: var(--md-sys-color-on-surface-variant); }
.actbar.is-error .actbar-msg { color: var(--md-sys-color-on-error-container); }
.ds-app-content:has(.actbar) { scroll-padding-bottom: 92px; }
@media (max-width: 760px) {
  .actbar { bottom: calc(-1 * var(--home-pad-b, 104px)); }
  body:not(.ds-focus-flow) .actbar { bottom: calc(84px - var(--home-pad-b, 104px)); }
  body:not(.ds-focus-flow) .ds-app-content:has(.actbar) { scroll-padding-bottom: calc(84px + 92px); }
}

/* ── 19. STATUT D'ENREGISTREMENT AUTOMATIQUE (.savestate) ───────────────
   Dit si le brouillon du compositeur est gardé. span.savestate[data-state] role=status
   (polite : on annonce saved au plus une fois par 30 s, error, offline, expired ; jamais
   saving). Icône 16 + texte + .lnk d'action facultative. */
.savestate { display: inline-flex; align-items: center; gap: 6px; height: 24px; font: var(--md-sys-typescale-label-medium); color: var(--md-sys-color-on-surface-variant); white-space: nowrap; }
.savestate[hidden] { display: none; }
.savestate svg { flex: none; width: 16px; height: 16px; }
.savestate .lnk { font: var(--md-sys-typescale-label-medium); font-weight: 600; }
.savestate[data-state="saving"] svg { animation: sp-spin .8s linear infinite; }   /* loader-circle */
.savestate:is([data-state="error"], [data-state="expired"], [data-state="full"], [data-state="conflict"]) { color: var(--md-sys-color-on-error-container); }
.savestate[data-state="dirty"]::before { content: ""; flex: none; width: 8px; height: 8px; border-radius: var(--md-sys-shape-corner-full); background: var(--md-sys-color-primary); }

/* ── 20. LIEN VIDÉO VÉRIFIÉ (.vlink) ────────────────────────────────────
   .ex-field (input url) + .vlink-status (role=status : checking, ok, warn, error) +
   .vlink-card (miniature 16:9, source, durée, « Ouvrir la vidéo » (nouvel onglet)). */
.vlink { display: flex; flex-direction: column; gap: 8px; min-width: 0; }
.vlink-status { display: flex; align-items: center; gap: 6px; margin: 0; min-height: 20px; font: var(--md-sys-typescale-body-small); color: var(--md-sys-color-on-surface-variant); }
.vlink-status:empty { display: none; }
.vlink-status svg { flex: none; width: 16px; height: 16px; }
.vlink-status[data-state="checking"] svg { animation: sp-spin .8s linear infinite; }
.vlink-status[data-state="ok"] svg { color: var(--md-sys-color-on-success-container); }
.vlink-status[data-state="error"] { color: var(--md-sys-color-on-error-container); }
.vlink-card { display: grid; grid-template-columns: 160px minmax(0, 1fr); align-items: center; gap: 12px; box-sizing: border-box; padding: 8px;
  border: 1px solid var(--md-sys-color-outline-variant); border-radius: var(--md-sys-shape-corner-medium); }
.vlink-card[hidden] { display: none; }
.vlink-thumb { position: relative; aspect-ratio: 16 / 9; overflow: hidden; border-radius: var(--md-sys-shape-corner-small); background: var(--md-sys-color-surface-container-high); }
.vlink-thumb img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; display: block; }
.vlink-txt { min-width: 0; display: flex; flex-direction: column; align-items: flex-start; gap: 2px; }
.vlink-src { font: var(--md-sys-typescale-label-large); font-weight: 700; color: var(--md-sys-color-on-surface); }
.vlink-dur { font: var(--md-sys-typescale-body-small); color: var(--md-sys-color-on-surface-variant); font-variant-numeric: tabular-nums; }
.vlink-txt .lnk { margin-top: 4px; }
@media (max-width: 560px) { .vlink-card { grid-template-columns: 112px minmax(0, 1fr); } }

/* ── 21. SÉLECTEUR D'ŒUVRE (.wpick) ─────────────────────────────────────
   Recherche TMDB dans un formulaire (range les classes provisoires .wiz-combo, .wiz-mock-*,
   .wiz-picked, .wiz-lnk). .ex-search (input role=combobox ARIA 1.2) + .wpick-list (listbox
   à la peau du menu) de .wpick-opt (44) ; .wpick-empty ; .wpick-picked une fois choisie.
   Option active (aria-activedescendant) : .is-active. */
.wpick { position: relative; display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.wpick > .ex-search { width: 100%; }
.wpick-list { position: absolute; left: 0; right: 0; top: calc(100% + 8px); z-index: 30; box-sizing: border-box; max-height: 340px; overflow-y: auto; margin: 0; padding: 6px; list-style: none;
  background: var(--md-sys-color-surface); color: var(--md-sys-color-on-surface); border: 1px solid var(--md-sys-color-outline);
  border-radius: var(--md-sys-shape-corner-medium); box-shadow: var(--md-sys-elevation-level2); }
.wpick-list[hidden] { display: none; }
.wpick-opt { position: relative; isolation: isolate; display: flex; align-items: center; gap: 10px; min-height: 44px; padding: 4px 8px; box-sizing: border-box;
  border-radius: var(--md-sys-shape-corner-small); cursor: pointer; }
.wpick-opt::after { content: ""; position: absolute; inset: 0; border-radius: inherit; background: currentColor; opacity: 0; pointer-events: none; transition: opacity .15s ease; }
.wpick-opt:hover::after { opacity: var(--md-sys-state-hover-opacity); }
.wpick-opt:is(.is-active, [aria-selected="true"])::after { opacity: var(--md-sys-state-focus-opacity); }
.wpick-opt.is-active { box-shadow: inset 0 0 0 2px var(--md-sys-color-primary); }
.wpick-cover { flex: none; width: 24px; height: 36px; overflow: hidden; border-radius: var(--md-sys-shape-corner-extra-small); background: var(--md-sys-color-surface-container-high); object-fit: cover; display: block; }
.wpick-cover img { width: 100%; height: 100%; object-fit: cover; display: block; }
.wpick-txt { min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.wpick-title { font: var(--md-sys-typescale-label-large); font-weight: 600; color: var(--md-sys-color-on-surface); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.wpick-meta { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 6px; font: var(--md-sys-typescale-body-small); color: var(--md-sys-color-on-surface-variant); }
.wpick-empty { display: flex; flex-direction: column; align-items: flex-start; gap: 8px; padding: 12px; font: var(--md-sys-typescale-body-small); color: var(--md-sys-color-on-surface-variant); }
.wpick-picked { display: flex; align-items: center; gap: 12px; box-sizing: border-box; min-height: 64px; padding: 8px 12px;
  border: 1px solid var(--md-sys-color-primary); border-radius: var(--md-sys-shape-corner-medium); background: color-mix(in srgb, var(--md-sys-color-primary) 8%, transparent); }
.wpick-picked[hidden] { display: none; }
.wpick-picked .wpick-cover { width: 32px; height: 48px; }
.wpick-picked .lnk { flex: none; margin-left: auto; min-height: 44px; }

/* ── 22. DÉPÔT D'IMAGES (.upl --single, --grid) ─────────────────────────
   --single : label.upl-drop 16:9 (360 au plus, pointillé), input file focusable par-dessus ;
   rempli (.is-filled) : l'image en cover + .upl-acts (Remplacer, Retirer).
   --grid : ul.upl-grid de li.upl-tile carrées (10 au plus) + li.upl-add. Badge
   « Couverture » (.bdg--sm.bdg--dark), menu .ibtn de 44 sur un dégradé scrim (alternative au
   glisser, WCAG 2.5.7). Envoi : .upl-busy (voile scrim 50 %, spinner, « Envoi… »).
   États : .is-over (survol de dépôt), .is-error (contour 2 error + .ex-err), .is-dragging,
   .is-drop-target ; plein = la tuile d'ajout est retirée par le script. */
.upl { display: flex; flex-direction: column; gap: 8px; min-width: 0; }
.upl-drop { position: relative; box-sizing: border-box; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 6px; width: 100%; max-width: 360px;
  aspect-ratio: 16 / 9; padding: 16px; overflow: hidden; border: 1px dashed var(--md-sys-color-outline); border-radius: var(--md-sys-shape-corner-medium);
  background: var(--md-sys-color-surface-container); color: var(--md-sys-color-on-surface-variant); text-align: center; cursor: pointer; }
.upl-drop svg { flex: none; width: 22px; height: 22px; }
.upl-drop input[type="file"] { position: absolute; inset: 0; z-index: 2; width: 100%; height: 100%; margin: 0; opacity: 0; cursor: pointer; }
.upl-drop:focus-within { outline: 3px solid var(--md-sys-color-primary); outline-offset: 2px; }
.upl-drop:hover, .upl-drop.is-over { border-style: solid; border-color: var(--md-sys-color-primary); background: color-mix(in srgb, var(--md-sys-color-primary) 8%, var(--md-sys-color-surface-container)); }
.upl-drop-t { font: var(--md-sys-typescale-label-large); color: var(--md-sys-color-on-surface); }
.upl-drop-s { font: var(--md-sys-typescale-body-small); }
.upl-drop.is-filled { padding: 0; border-style: solid; border-color: var(--md-sys-color-outline-variant); }
.upl-drop.is-filled > img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; display: block; }
.upl-acts { display: flex; flex-wrap: wrap; gap: 8px; }
.upl-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(112px, 1fr)); gap: 8px; margin: 0; padding: 0; list-style: none; }
.upl-tile, .upl-add { position: relative; aspect-ratio: 1; overflow: hidden; border-radius: var(--md-sys-shape-corner-medium); }
.upl-tile { background: var(--md-sys-color-surface-container-high); }
.upl-tile > img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; display: block; }
.upl-tile::before { content: ""; position: absolute; inset: 0 0 auto; z-index: 1; height: 56px; pointer-events: none;
  background: linear-gradient(to bottom, color-mix(in srgb, var(--md-sys-color-scrim) 55%, transparent), transparent); }
.upl-tile > .bdg { position: absolute; left: 8px; bottom: 8px; z-index: 1; }
.upl-tile > .ibtn { position: absolute; top: 0; right: 0; z-index: 2; color: var(--md-sys-color-on-media); }
.upl-tile.is-dragging { opacity: .5; }
.upl-tile.is-drop-target { box-shadow: inset 0 0 0 2px var(--md-sys-color-primary); }
.upl-drop.is-error, .upl-tile.is-error { border: 2px solid var(--md-sys-color-error); }
.upl-add { border: 1px dashed var(--md-sys-color-outline); box-sizing: border-box; }
.upl-add > :is(button, label) { position: relative; isolation: isolate; box-sizing: border-box; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 4px;
  width: 100%; height: 100%; padding: 8px; border: 0; background: none; color: var(--md-sys-color-on-surface-variant); font: var(--md-sys-typescale-label-large); cursor: pointer; }
.upl-add > :is(button, label)::after { content: ""; position: absolute; inset: 0; background: currentColor; opacity: 0; pointer-events: none; transition: opacity .15s ease; }
.upl-add > :is(button, label):hover::after { opacity: var(--md-sys-state-hover-opacity); }
.upl-add > :is(button, label):focus-visible { outline: 3px solid var(--md-sys-color-primary); outline-offset: -3px; }
.upl-add svg { width: 22px; height: 22px; }
.upl-add small { font: var(--md-sys-typescale-label-small); font-variant-numeric: tabular-nums; }
.upl-add input[type="file"] { position: absolute; inset: 0; z-index: 2; width: 100%; height: 100%; margin: 0; opacity: 0; cursor: pointer; }
.upl-add:focus-within { outline: 3px solid var(--md-sys-color-primary); outline-offset: 2px; }
.upl-busy { position: absolute; inset: 0; z-index: 3; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 6px;
  background: color-mix(in srgb, var(--md-sys-color-scrim) 50%, transparent); color: var(--md-sys-color-on-media); font: var(--md-sys-typescale-label-small); }
.upl-busy[hidden] { display: none; }
.upl-busy svg { width: 22px; height: 22px; animation: sp-spin .8s linear infinite; }

/* ── 23. PANNEAU D'APERÇU (.pvpane) ─────────────────────────────────────
   aside aria-label « Aperçu » : en-tête (titre + .ex-seg Carte | Fil), scène inerte
   (.pvpane-stage, inert + aria-hidden, la vraie carte de 360 au plus), « Ce que tu as réglé »
   en .bdg. Fond surface-container-high, rayon 16, collé pendant la saisie. Feuille plein écran
   sur téléphone : le même contenu dans un .ex-panel. */
.pvpane { position: sticky; top: 0; box-sizing: border-box; display: flex; flex-direction: column; gap: 16px; min-width: 0; padding: 24px;
  border-radius: var(--md-sys-shape-corner-large); background: var(--md-sys-color-surface-container-high); }
.pvpane-head { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 8px 12px; }
.pvpane-t { margin: 0; font: var(--md-sys-typescale-title-small); color: var(--md-sys-color-on-surface); }
.pvpane-stage { display: flex; justify-content: center; min-width: 0; }
.pvpane-stage > * { width: 100%; max-width: 360px; }
.pvpane-sec { display: flex; flex-direction: column; gap: 8px; }
.pvpane-sec-t { margin: 0; font: var(--md-sys-typescale-label-medium); font-weight: 600; color: var(--md-sys-color-on-surface-variant); }

/* ── 24. ÉTAT DE RÉUSSITE (.empty-state--ok + .empty-acts) ──────────────
   Écran de réussite du compositeur, qui garde le créateur dans le Studio : l'anatomie de
   .empty-state, icône circle-check sur success-container, titre focalisable (tabindex -1),
   emplacement de carte de 320 (.empty-card), actions centrées (empilées sous 560 px). */
.empty-state--ok .empty-ic { background: var(--md-sys-color-success-container); color: var(--md-sys-color-on-success-container); }
.empty-state--ok .empty-title:focus:not(:focus-visible) { outline: none; }
.empty-card { width: 100%; max-width: 320px; margin-top: 24px; text-align: left; }
.empty-acts { display: flex; flex-wrap: wrap; justify-content: center; gap: 8px; margin-top: 24px; }
@media (max-width: 560px) {
  .empty-acts { flex-direction: column; align-self: stretch; }
  .empty-acts > .cbtn { width: 100%; }
}

/* ── 25. CHAMP DE TEMPS ET LIGNES DE CALAGE · révision ──────────────────
   Faite EN PLACE dans la section « Publier en étapes » plus haut (.tf, .tf-pop, .tstep,
   .wiz-row, .wiz-add, .wiz-tl, et les tuiles .wiz-plat) : hauteurs de 44, rayons du DS,
   polices en jetons, couleurs sur les jetons --sp-tl-*. Rien à ajouter ici. */

/* ── 26. MATRICE DES PALIERS v2 · téléphone et clavier (extension de .tier-matrix) ──
   Ordinateur : inchangé. Chaque .tier-mx-row devient role=radiogroup (aria-labelledby vers
   son service), chaque .tier-mx-c role=radio + aria-checked + aria-label « {service} : à
   partir de « {palier} » » (plus de title). Un span .tier-mx-c-lbl porte le nom du palier :
   réservé aux lecteurs d'écran sur ordinateur, visible sous 720 px où la ligne devient le
   service puis des pastilles de 44 qui passent à la ligne. Tabulation itinérante (Tab entre
   les lignes, flèches dans une ligne). */
.tier-mx-c-lbl { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; border: 0; }
/* La mise en page téléphone ne s'applique qu'à une matrice v2 (cases avec leur nom) : l'ancienne
   page Studio › Abonnements garde son rendu jusqu'à son remplacement. */
@media (max-width: 720px) {
  .tier-matrix:has(.tier-mx-c-lbl) :is(.tier-mx-head, .tier-mx-row, .tier-mx-grp, .tier-mx-note) { min-width: 0; }
  .tier-mx-row:has(.tier-mx-c-lbl) { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
  .tier-mx-row:has(.tier-mx-c-lbl) .tier-mx-svc { flex: 1 0 100%; }
  .tier-mx-row .tier-mx-c:has(.tier-mx-c-lbl) { display: inline-flex; align-items: center; height: 44px; padding: 0 12px; border-radius: var(--md-sys-shape-corner-small); }
  .tier-mx-c .tier-mx-c-lbl { position: static; width: auto; height: auto; margin: 0; overflow: visible; clip: auto; clip-path: none;
    font: var(--md-sys-typescale-label-medium); color: var(--md-sys-color-on-surface); }
  .tier-mx-c.is-start .tier-mx-c-lbl { color: var(--md-sys-color-on-primary); }
  .tier-mx-c--no.is-on .tier-mx-c-lbl { color: var(--md-sys-color-surface); }
}

/* ── 27. RAPPEL DE DÉMARRAGE COMPACT (.launch--mini) ────────────────────
   Le SEUL rappel de préparation de la chaîne dans le Studio (remplace .launch--rail et
   .launch--notice, gardés tant que l'ancienne coquille existe). Un lien, la peau de .launch :
   tuile .launch-ic de 36, « Chaîne en préparation » + « {n} étapes sur 5 », .prog dessous
   (aria-hidden : l'info est dans le nom accessible). Rail : sous la liste ; replié (ou
   1000 px et moins) : carré de 44 avec l'icône eye-off seule. Burger : pleine largeur. */
.launch--mini { position: relative; isolation: isolate; display: grid; grid-template-columns: 36px minmax(0, 1fr); align-items: center; gap: 8px; padding: 12px; text-decoration: none; }
.launch--mini .launch-ic { width: 36px; height: 36px; border-radius: var(--md-sys-shape-corner-small); }
.launch--mini .launch-txt { gap: 2px; }
.launch--mini .launch-txt b { font: var(--md-sys-typescale-title-small); }
.launch--mini .launch-txt > span { font: var(--md-sys-typescale-body-small); font-variant-numeric: tabular-nums; }
.launch--mini .prog { grid-column: 1 / -1; }
.launch--mini::after { content: ""; position: absolute; inset: 0; border-radius: inherit; background: currentColor; opacity: 0; pointer-events: none; transition: opacity .15s ease; }
.launch--mini:hover::after { opacity: var(--md-sys-state-hover-opacity); }
.launch--mini:active::after { opacity: var(--md-sys-state-pressed-opacity); }
.launch--mini:focus-visible { outline: 3px solid var(--md-sys-color-primary); outline-offset: 2px; }
.sbar > .launch--mini { flex: none; width: auto; margin: 8px 20px 0; }
.sbar.is-collapsed > .launch--mini:not([hidden]) { display: flex; width: 44px; margin: 8px auto 0; padding: 0; border: 0; background: transparent; }
.sbar.is-collapsed > .launch--mini .launch-ic { width: 44px; height: 44px; border-radius: var(--md-sys-shape-corner-medium); }
.sbar.is-collapsed > .launch--mini :is(.launch-txt, .prog) { display: none; }
@media (max-width: 1000px) {
  .ds-app .sbar > .launch--mini:not([hidden]) { display: flex; width: 44px; margin: 8px auto 0; padding: 0; border: 0; background: transparent; }
  .ds-app .sbar > .launch--mini .launch-ic { width: 44px; height: 44px; border-radius: var(--md-sys-shape-corner-medium); }
  .ds-app .sbar > .launch--mini :is(.launch-txt, .prog) { display: none; }
}

/* ── 27b. SORTIE DU RAIL (.sbar-exit) ET POINT SANS CHIFFRE (.tbar-dot--plain) ──
   « Retour à SydePlay » : un .sbar-btn isolé en bas du rail, fixe sous la liste et au-dessus
   de .sbar-foot (replié : carré de 44, infobulle title). .tbar-dot--plain : le point
   d'alerte sans nombre (8 × 8), déplacé tel quel depuis feed-ds.css (la copie de feed-ds.css
   est à retirer par la coquille) ; dans le rail, il suit le libellé comme .tbar-dot. Toujours
   aria-hidden, avec un .sr-only dans le lien. */
.sbar > .sbar-exit { flex: none; width: auto; margin: 8px 20px 0; }
.sbar.is-collapsed > .sbar-exit { width: 44px; margin: 8px auto 0; }
.sbar-foot:has(> .sbar-exit) { align-items: center; gap: 8px; }
.sbar-foot > .sbar-exit { flex: 1 1 auto; width: auto; min-width: 0; }
.sbar.is-collapsed .sbar-foot:has(> .sbar-exit) { flex-direction: column; }
.sbar.is-collapsed .sbar-foot > .sbar-exit { flex: none; width: 44px; }
@media (max-width: 1000px) {
  .ds-app .sbar > .sbar-exit { width: 44px; margin: 8px auto 0; }
  .ds-app .sbar .sbar-foot:has(> .sbar-exit) { flex-direction: column; }
  .ds-app .sbar .sbar-foot > .sbar-exit { flex: none; width: 44px; }
}
.tbar-dot--plain { min-width: 8px; width: 8px; height: 8px; padding: 0; top: 9px; right: 9px; border-radius: var(--md-sys-shape-corner-full); }

/* ── 28. PASTILLE D'ÉTAT DE CHAÎNE (.tbar-studio-state, téléphone) ──────
   « En préparation » dans la barre du haut, là où il n'y a pas de rail (760 px et moins, chaîne
   non lancée : hidden sinon). Lien de 44 avec un .bdg--orange (avertissement, pas erreur) ;
   sous 420 px, l'icône seule (le lien garde son aria-label complet). */
.tbar-studio-state { display: none; flex: none; align-items: center; height: 44px; margin-left: 8px; border-radius: var(--md-sys-shape-corner-small); text-decoration: none; }
.tbar-studio-state:hover .bdg { filter: brightness(1.15); }
.tbar-studio-state:focus-visible { outline: 3px solid var(--md-sys-color-primary); outline-offset: 2px; }
@media (max-width: 760px) { .tbar-studio-state { display: inline-flex; } }
@media (max-width: 420px) {
  .tbar-studio-state .bdg { width: 30px; padding: 0; }
  .tbar-studio-state .bdg > span { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; }
}
.tbar-studio-state[hidden] { display: none; }

/* ── 29. BARRE DU BAS À LIBELLÉS AVEC PUBLIER CENTRAL (.ds-bottomnav--labels) ──
   Studio, téléphone : icône + libellé, au plus 5 éléments, Publier au centre (toujours plein,
   inverse-surface, PUBLISH_IC dont le + pivote à l'ouverture). La barre elle-même (84 de haut,
   fixe, cachée au-dessus de 760 px) est celle de feed-ds.css ; on n'en change que la
   répartition. nav aria-label « Navigation du Studio » ; actif = aria-current=page ; le
   compteur (.tbar-dot sur le coin de l'icône) fait partie du nom accessible ;
   body.ds-focus-flow masque la barre (coquille). */
.ds-app .ds-bottomnav.ds-bottomnav--labels { justify-content: space-around; gap: 0; padding: 0 8px env(safe-area-inset-bottom); }
.ds-bottomnav--labels > * { flex: 1 1 0; min-width: 0; display: flex; justify-content: center; }
.bnav-item, .bnav-pub { position: relative; isolation: isolate; box-sizing: border-box; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 2px;
  height: 44px; min-width: 64px; padding: 0; border: 0; border-radius: var(--md-sys-shape-corner-medium); background: transparent;
  color: var(--md-sys-color-on-surface-variant); font: var(--md-sys-typescale-label-small); line-height: 1.2; text-decoration: none; cursor: pointer; }
.bnav-item::after, .bnav-pub::after { content: ""; position: absolute; inset: 0; border-radius: inherit; background: currentColor; opacity: 0; pointer-events: none; transition: opacity .15s ease; }
.bnav-item:hover::after, .bnav-pub:hover::after { opacity: var(--md-sys-state-hover-opacity); }
.bnav-item:active::after, .bnav-pub:active::after { opacity: var(--md-sys-state-pressed-opacity); }
.bnav-item:focus-visible, .bnav-pub:focus-visible { outline: 3px solid var(--md-sys-color-primary); outline-offset: -3px; }
.bnav-ic { position: relative; flex: none; display: flex; align-items: center; justify-content: center; width: 48px; height: 28px; border-radius: var(--md-sys-shape-corner-full); }
.bnav-ic svg { width: 22px; height: 22px; }
.bnav-ic .tbar-dot { top: -2px; right: 2px; }
.bnav-item[aria-current="page"] { color: var(--md-sys-color-on-surface); font-weight: 700; }
.bnav-item[aria-current="page"] .bnav-ic, .bnav-pub .bnav-ic { background: var(--md-sys-color-inverse-surface); color: var(--md-sys-color-inverse-on-surface); }
.bnav-pub .bnav-ic svg { width: 20px; height: 20px; }
.bnav-pub[aria-expanded="true"] .tbar-pub-a { transform: translate(-3px, 0) rotate(-45deg); stroke-dasharray: 8.49 100; stroke-dashoffset: -2.76; }
.bnav-pub[aria-expanded="true"] .tbar-pub-b { transform: translate(3px, 0) rotate(-45deg); stroke-dasharray: 8.49 100; stroke-dashoffset: -2.76; }

/* ── 30. MENU OUVERT VERS LE HAUT (.tbar-dd-panel--up) ──────────────────
   Variante de placement : au-dessus du bouton, centré sur lui, peau .menu inchangée.
   Menu Publier de la barre du bas (dans un .tbar-dd, data-open), menu « Actions » de
   .bulkbar--dock (dans .bulkbar-acts, hidden). role=menu, focus sur la 1re ligne, Échap. */
.tbar-dd-panel--up { position: absolute; top: auto; bottom: calc(100% + 8px); right: 50%; z-index: 60; transform: translateX(50%);
  max-height: calc(100vh - 200px); overflow-y: auto; }
.tbar-dd-panel--up[hidden] { display: none; }

/* ── 31. LIEN D'ÉVITEMENT (.skip-link) ──────────────────────────────────
   a.cbtn.cbtn--noir.skip-link, premier élément focusable : « Aller au contenu » vers #ds-main
   (tabindex=-1). Hors écran au repos, visible au focus ; au-dessus de la barre du haut,
   sous les fenêtres. Aucune transition sous prefers-reduced-motion. */
.skip-link { position: fixed; top: 8px; left: 8px; z-index: 100; transform: translateY(-200%); transition: transform .15s ease; }
.skip-link:focus, .skip-link:focus-visible { transform: translateY(0); }

/* ── 32. GRILLE DE RUBRIQUES COMPACTE (.srub-grid--compact) ─────────────
   Accès rapide aux 6 types de publication du tableau de bord (même ordre que le menu
   Publier) ; aussi la liste du téléphone des Paramètres. À toutes les largeurs, chaque .srub
   prend la mise en page téléphone : une ligne, l'icône à gauche, le chevron au bout. */
.srub-grid--compact { grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); gap: 8px; }
.srub-grid--compact .srub { flex-direction: row; align-items: center; gap: 16px; padding: 12px 16px; }
.srub-grid--compact .srub-go { position: static; margin-left: auto; }
a.srub { text-decoration: none; }

/* ── 33. SAISIE DE DIALOGUE AVEC LIBELLÉ VISIBLE ET COMPTEUR (.dlg-field--labeled + .dlg-help) ──
   shared/dialog.js : avec fieldLabel, le libellé caché devient un .ex-lbl visible (le label
   porte .dlg-field--labeled) ; avec maxLength, maxlength sur le champ et p.dlg-help
   « {n} / {max} » relié par aria-describedby (sans aria-live). */
.dlg-field.dlg-field--labeled { display: flex; flex-direction: column; gap: 6px; }
.dlg-help { display: flex; justify-content: flex-end; margin: 4px 0 0; font: var(--md-sys-typescale-body-small); color: var(--md-sys-color-on-surface-variant); font-variant-numeric: tabular-nums; }
.dlg-field--labeled > .dlg-help { margin-top: -2px; }   /* 4 sous le champ, l'écart de 6 du champ compris */

/* ── 34. [hidden] TOUJOURS RESPECTÉ (intégration de la refonte du Studio, 07/10/2026) ──────
   Le « display: flex / grid / inline-flex » d'un composant l'emporte sur le [hidden] du
   navigateur : un bloc « masqué » restait visible (.sblk-body, .sblk-acts, .lnk, .ex-meta…) et
   chaque page ajoutait sa règle locale. Une seule règle ici pour les composants du DS qu'on
   montre et cache (spécificité 0,2,0 : passe devant leur display ; posée après eux pour les
   égalités). Les fenêtres et overlays gardent leur propre mécanique (.is-on). */
:is(.lnk, .bdg, .chip, .ava, .numpill, .statc-delta, .code-inline,
    .ex-field, .ex-meta, .ex-affix, .ex-select, .ex-search, .ex-seg, .ex-selbtn, .ex-check, .ex-toggle, .ex-dt, .ex-tabs, .errsum-acts,
    .sblk-head, .sblk-body, .sblk-acts, .sblk-two, .stp-rows, .stp-row, .lrow-list, .lrow, .srub-grid, .srub, .srub-ic,
    .alert, .statc, .statc-grid, .statc-grid--kpi, .checklist, .checklist-item, .checklist-act, .checklist-done, .checklist-count,
    .launch-actions, .empty-state, .empty-acts, .prog,
    .dstable-media, .dstable-meta, .dstable-more, .bulkbar-acts, .phead-txt, .phead-tabs, .secnav-meta,
    .modrow, .modrow-head, .modrow-badges, .modrow-foot, .modrow-acts, .modrow-ctx, .modrow-help, .modrow-more,
    .chart-head, .chart-data, .choice, .choice-list, .choice-grid, .wiz-steps, .wiz-steps-sum,
    .actbar, .actbar-start, .actbar-end, .actbar-msg, .vlink, .vlink-status, .wpick, .wpick-empty,
    .upl, .upl-drop, .upl-acts, .upl-grid, .pvpane, .pvpane-sec, .lhead-tools)[hidden] { display: none; }

/* ── DÉMOS DE L'ATELIER (page /design-system seulement) ─────────────────
   Les composants fixés ou collés (.snack, .savebar, .bulkbar--dock, .skip-link, .actbar,
   .chart-tip) sont montrés à plat ; la barre du bas reçoit le fond que feed-ds.css lui
   donne dans l'appli (non chargée ici). Aucune de ces classes ne sert dans les pages. */
.ds-pin-demo { display: flex; flex-direction: column; align-items: flex-start; gap: 12px; }
.ds-pin-demo > :is(.snack, .savebar, .bulkbar, .skip-link, .actbar, .tbar-dd-panel--up) { position: relative; inset: auto; transform: none; animation: none; z-index: auto; }
.ds-pin-demo > .snack { width: auto; max-width: 100%; }   /* démo à plat : jamais la largeur d'écran du téléphone */
.ds-pin-demo > :is(.savebar, .bulkbar, .actbar) { align-self: stretch; }
.ds-pin-demo > .snack { left: auto; bottom: auto; }
.ds-bnav-demo { position: relative; display: flex; align-items: center; box-sizing: border-box; width: 390px; max-width: 100%; height: 84px; padding: 0 8px;
  background: var(--md-sys-color-surface); border: 1px solid var(--md-sys-color-outline-variant); border-radius: var(--md-sys-shape-corner-large); }
.ds-setl-demo { padding: 24px; border: 1px solid var(--md-sys-color-outline-variant); border-radius: var(--md-sys-shape-corner-large); background: var(--md-sys-color-surface); }
.ds-setl-demo .secnav { position: static; max-height: none; }
.ds-setl-demo .savebar { position: relative; bottom: auto; left: auto; right: auto; }
.ds-chart-demo .chart-plot { overflow: visible; }

/* ════════════════════════════════════════════════════════════════════
   FINITIONS DU NAVIGATEUR (14/10/2026) · ce que le DS ne dessinait pas encore
   Sélection de texte, contrôles natifs restants (cases, radios, curseurs), coupure des titres,
   toucher sur mobile. Aucun composant ne change de forme.
   ════════════════════════════════════════════════════════════════════ */
.ds-app ::selection { background: color-mix(in srgb, var(--md-sys-color-primary) 30%, transparent); }
.ds-app { accent-color: var(--md-sys-color-primary); }
/* Titres sur deux lignes : coupés en lignes de longueur voisine (plus de mot seul en bas) ;
   paragraphes : pas de dernier mot orphelin. Sans effet sur un titre d'une ligne ou tronqué. */
.ds-app :is(h1, h2, h3) { text-wrap: balance; }
.ds-app p { text-wrap: pretty; }
/* Mobile : pas de zoom au double toucher sur une commande, pas de rectangle gris d'Android / iOS
   au toucher (les états :active et :focus-visible du DS donnent le retour). */
.ds-app :is(a, button, [role="button"], label, summary, select, input, textarea) {
  touch-action: manipulation; -webkit-tap-highlight-color: transparent; }

/* ════════════════════════════════════════════════════════════════════
   ANIMATIONS RÉDUITES (prefers-reduced-motion) · bloc global, en dernier
   Rail (repli), « + » de Publier, chevrons d'accordéon et de menus, spinners (l'icône se
   fige, le texte reste), apparitions (fondu seul, ou rien), sorties de ligne, défilement doux.
   ════════════════════════════════════════════════════════════════════ */
@media (prefers-reduced-motion: reduce) {
  html, .ds-app-content { scroll-behavior: auto; }
  .sbar, .sbar-btn, .sbar-creator, .sbar-label, .sbar-cname, .ds-app-content { transition: none; }
  .tbar-pub-ic path, .bnav-pub .tbar-pub-ic path { transition: none; }
  .accord-caret, .accord-plus, .ds-specs-caret, .tbar-caret, .lhead-caret, .wiz-steps-sum svg { transition: none; }
  .sp-spin, .grid-state .big.spin svg, .ex-help--wait svg, .ex-help--busy svg, .savebar.is-saving .savebar-ic svg,
  .savestate[data-state="saving"] svg, .vlink-status[data-state="checking"] svg, .statc[aria-busy="true"] .statc-val svg, .upl-busy svg { animation: none; }
  .snack { animation-name: sp-fade-in; }
  .savebar, .bulkbar { animation: none; }
  .skip-link, .ex-dot, .ex-dot::after, .chart-bars i, .wiz-steps-btn::before { transition: none; }
  .dstable tr.is-flash td { animation: none; background-color: var(--md-sys-color-primary-container); }
  .dstable tr.is-leaving { transform: none; }
  .modrow.is-leaving { transform: none; transition-duration: .05s; }
  .chart-tip, .chart-cursor, .chart-dot { transition: none; }
  .is-target { animation: none; }   /* contour fixe, sans fondu : le script retire la classe après 2 s */
  /* Survol des cartes : plus de mouvement, l'état reste lisible (bouton lecture et éclairage en fondu, lueur fixe). */
  html[data-survol="projecteur"] .rcard:hover { transform: none; }
  html[data-survol="projecteur"] .rcard:hover .rcard-shine { animation: none; opacity: 0; }
  .rcard-play i { transform: none; }
  html[data-survol="relief"] .rcard, html[data-survol="relief"] .rcard.is-tilting { transform: none; }
}

/* ════════════════════════════════════════════════════════════════════
   COMPOSITEUR V2 (Studio › Publier, 07/10/2026, À valider par le porteur)
   1. .tierpick : carte de palier dans un choix exclusif (extension de .choice--row) pour
      « Réserver à un palier » : tuile d'icône ou d'image (.tierpick-ic), nom, « et les paliers
      au-dessus », ligne d'infos (.tierpick-meta : abonnés qui y ont accès, avance), prix par
      mois (.tierpick-price). .tierpick--new : carte d'action (lien) « Crée ton premier palier ».
   2. .pvx : panneau d'aperçu v2 (sur .pvpane) : « Vu par » (.pvx-who, .ex-seg--fill dont les
      libellés se coupent en « … »), scène calme (.pvx-stage : légende .pvx-cap + .pvx-scene
      inerte), cadre de téléphone (.pvx-phone : écran de 375 px réduit, --pvx-k), lignes
      « pour qui, et quand » (.pvx-facts, la 1re en .pvx-fact--main avec data-tone
      open | soon | locked).
   ════════════════════════════════════════════════════════════════════ */
.tierpick .choice-card { gap: 12px; }
.tierpick .choice-txt { flex: 1 1 0; }
.tierpick-ic { display: grid; place-items: center; flex: none; width: 44px; height: 44px; overflow: hidden;
  border-radius: var(--md-sys-shape-corner-medium); background: var(--md-sys-color-surface-container-high); color: var(--md-sys-color-on-surface); }
.tierpick-ic > img { display: block; width: 100%; height: 100%; object-fit: cover; }
.choice input:checked + .choice-card .tierpick-ic { background: color-mix(in srgb, var(--md-sys-color-primary) 16%, transparent); }
.tierpick-meta { display: flex; flex-wrap: wrap; gap: 2px 12px; margin-top: 4px; font: var(--md-sys-typescale-label-medium); color: var(--md-sys-color-on-surface-variant); }
.tierpick-meta > span { display: inline-flex; align-items: center; gap: 4px; }
.tierpick-meta svg { flex: none; }
.choice input:checked + .choice-card .tierpick-meta svg { color: inherit; }
.tierpick-price { flex: none; display: flex; flex-direction: column; align-items: flex-end; gap: 0; margin-left: auto; text-align: right; }
.tierpick-price b { font: var(--md-sys-typescale-title-medium); font-weight: 700; color: var(--md-sys-color-on-surface); white-space: nowrap; }
.tierpick-price span { font: var(--md-sys-typescale-body-small); color: var(--md-sys-color-on-surface-variant); }
.tierpick--new .choice-card { flex-direction: row; align-items: center; gap: 12px; min-height: 64px; padding: 12px 16px; border-style: dashed; text-decoration: none; color: var(--md-sys-color-on-surface-variant); }
.tierpick--new .choice-card > svg:last-child { flex: none; margin-left: auto; }
.tierpick--new .tierpick-ic { color: var(--md-sys-color-primary); }
@media (max-width: 480px) {
  .tierpick .choice-card { flex-wrap: wrap; }
  .tierpick-price { flex-direction: row; align-items: baseline; gap: 4px; width: 100%; padding-left: 88px; box-sizing: border-box; text-align: left; }   /* sous le nom : point (20) + tuile (44) + écarts (2 × 12) */
}

.pvx .pvpane-head .ex-seg button { padding: 0 14px; }
.pvx-who { display: flex; flex-direction: column; gap: 8px; min-width: 0; }
.pvx-who-t { font: var(--md-sys-typescale-label-medium); color: var(--md-sys-color-on-surface-variant); }
.pvx-who .ex-seg { min-width: 0; }
.pvx-who .ex-seg button { gap: 6px; padding: 0 10px; }
.pvx-who .ex-seg button > svg, .pvx-who-ic { flex: none; }
.pvx-who-ic { display: grid; place-items: center; width: 16px; height: 16px; overflow: hidden; border-radius: var(--md-sys-shape-corner-full); }
.pvx-who-ic > img { display: block; width: 100%; height: 100%; object-fit: cover; }
.pvx-who-lbl { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.pvx-stage { container: pvx-stage / inline-size; display: flex; flex-direction: column; gap: 12px; min-width: 0; padding: 16px;
  border: 1px solid var(--md-sys-color-outline-variant); border-radius: var(--md-sys-shape-corner-large);
  background: radial-gradient(120% 70% at 50% 0%, color-mix(in srgb, var(--md-sys-color-primary) 8%, transparent), transparent 72%), var(--md-sys-color-surface); }
.pvx-cap { display: inline-flex; align-items: center; gap: 6px; margin: 0; font: var(--md-sys-typescale-label-medium); color: var(--md-sys-color-on-surface-variant); }
.pvx-cap svg { flex: none; }
.pvx-scene { display: flex; justify-content: center; min-width: 0; }
.pvx-scene > :is(.rcard, .cf-post) { flex: 1 1 auto; box-sizing: border-box; width: 100%; max-width: 360px; margin: 0; }
.pvx-phone { --pvx-k: .6; flex: none; box-sizing: content-box; width: calc(375px * var(--pvx-k)); height: calc(667px * var(--pvx-k)); padding: 8px; overflow: hidden;
  border: 1px solid var(--md-sys-color-outline-variant); border-radius: var(--md-sys-shape-corner-extra-large);
  background: var(--md-sys-color-surface-container-highest); box-shadow: var(--md-sys-elevation-level2); }
@container pvx-stage (min-width: 290px) { .pvx-phone { --pvx-k: .72; } }
@container pvx-stage (min-width: 440px) { .pvx-phone { --pvx-k: .86; } }
.pvx-phone-screen { position: relative; box-sizing: border-box; width: 375px; height: 667px; overflow: hidden; transform: scale(var(--pvx-k)); transform-origin: 0 0;
  border-radius: calc((var(--md-sys-shape-corner-extra-large) - 8px) / var(--pvx-k)); background: var(--md-sys-color-surface); }   /* rayon vu = celui du cadre moins sa marge */
.pvx-phone-screen::after { content: ""; position: absolute; left: 0; right: 0; bottom: 0; height: 96px; pointer-events: none;
  background: linear-gradient(to bottom, transparent, var(--md-sys-color-surface)); }
.pvx-phone-bar { position: relative; display: flex; align-items: center; height: 48px; padding: 0 32px; font: var(--md-sys-typescale-label-large); font-weight: 600; color: var(--md-sys-color-on-surface); }
.pvx-phone-island { position: absolute; top: 10px; left: 50%; width: 104px; height: 28px; transform: translateX(-50%); border-radius: var(--md-sys-shape-corner-full); background: var(--md-sys-color-scrim); }
.pvx-phone-feed { padding: 4px 16px 16px; }
.pvx-facts { display: flex; flex-direction: column; gap: 8px; margin: 0; padding: 0; list-style: none; }
.pvx-fact { display: flex; align-items: flex-start; gap: 8px; margin: 0; font: var(--md-sys-typescale-body-small); color: var(--md-sys-color-on-surface-variant); }
.pvx-fact svg { flex: none; margin-top: 1px; }
.pvx-fact--main { font: var(--md-sys-typescale-body-medium); color: var(--md-sys-color-on-surface); }
.pvx-fact--main[data-tone="open"] svg { color: var(--md-sys-color-success); }
.pvx-fact--main[data-tone="soon"] svg { color: var(--md-sys-color-warning); }
.pvx-fact--main[data-tone="locked"] svg { color: var(--md-sys-color-primary); }
.pvx-who[hidden], .pvx-facts[hidden] { display: none; }
/* Fil : titre long et badge de type passent sur deux lignes quand la scène est étroite (le fil réel est plus large). */
.pvx-stage[data-view="feed"] .cf-titlerow { flex-wrap: wrap; row-gap: 6px; }
/* L'écran du téléphone rejoue les règles « téléphone » du post du fil (reaction-modal-ds.css, ≤ 560 px) : la fenêtre, elle, est large. */
.pvx-phone-screen .cf-post { padding: 16px; }
.pvx-phone-screen .cf-title { font-size: var(--md-sys-typescale-body-large-size); }

/* ════════════════════════════════════════════════════════════════════
   PARAMÈTRES v2 (07/10/2026, À valider) · /settings et Studio › Paramètres
   Retour du porteur : le sommaire latéral (.secnav) posé contre le rail faisait DEUX listes
   verticales côte à côte. Les deux pages de réglages deviennent, avec les mêmes composants :
   1. .sethero : carte d'en-tête pleine largeur. Bannière facultative (Studio), avatar, nom et
      pastille d'état, ligne d'identité, actions rapides à droite ; dessous, la recherche
      « Rechercher un réglage » (.ex-search) et son compteur (role=status).
   2. .setg : grille de cartes en DEUX colonnes fixes (.setg-col) à partir de 880 px de largeur
      de grille (requête de conteneur), une seule en dessous (la 2e colonne passe sous la 1re).
      Colonnes empilées plutôt que CSS columns : une liste déroulante ouverte n'est jamais
      coupée entre deux colonnes, et l'ordre au clavier suit la colonne.
   3. .setc : carte de section = .sblk + .setc. Petit libellé h2 en capitales, couleur de marque
      (on-error-container pour .setc--danger), marque « Modifié » / « À corriger » et action
      facultative au bout de l'en-tête, puis des lignes .stp-row (titre et aide à gauche,
      contrôle au bout : interrupteur, groupe .ex-seg, liste .ex-select, petit bouton), filets
      fins ; pied .setc-foot (« Tout voir ») facultatif.
   4. Recherche : ligne trouvée .is-hit (fond primary 8 %), mot surligné ::highlight(setq) ;
      les cartes sans résultat sont masquées (hidden).
   Le contenu lourd (factures, appareils, commentaires, formulaires longs) s'ouvre dans la
   fenêtre de rubrique .srw, avec le pied .stp-foot (Annuler / Enregistrer). Contrôleur commun :
   pages/settings/settings-grid.js. Placement et peau seulement : champs, boutons, lignes,
   interrupteurs et tableaux viennent des sections précédentes.
   ════════════════════════════════════════════════════════════════════ */

/* ── 1. Carte d'en-tête ── */
.sethero { container: sethero / inline-size; min-width: 0; margin: 0 0 24px; box-sizing: border-box;
  background: var(--md-sys-color-surface); color: var(--md-sys-color-on-surface);
  border: 1px solid var(--md-sys-color-outline-variant); border-radius: var(--md-sys-shape-corner-large); }
.sethero-banner { position: relative; display: grid; place-items: center; height: clamp(88px, 18cqi, 200px); overflow: hidden;   /* bande : 18 % de la largeur de la carte */
  border-radius: calc(var(--md-sys-shape-corner-large) - 1px) calc(var(--md-sys-shape-corner-large) - 1px) 0 0;
  background: var(--md-sys-color-surface-container-high) center / cover no-repeat; color: var(--md-sys-color-on-surface-variant); }
.sethero-banner > svg { flex: none; }
.sethero-banner > .bdg { position: absolute; top: 12px; right: 12px; }
.sethero-main { display: flex; flex-wrap: wrap; align-items: center; gap: 16px 20px; padding: 24px; }
.sethero-ava { flex: none; }
/* Avec bannière : l'avatar la chevauche (comme .banner-ava), le texte se cale en bas. */
.sethero-banner + .sethero-main { align-items: flex-end; padding-top: 12px; }
.sethero-banner + .sethero-main > .sethero-ava { margin-top: -44px; border: 3px solid var(--md-sys-color-surface); }
.sethero-banner + .sethero-main > .sethero-ava:has(> img) { background: var(--md-sys-color-surface); }
.sethero-txt { flex: 1 1 240px; min-width: 0; display: flex; flex-direction: column; gap: 4px; }
.sethero-name { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 10px; margin: 0; overflow-wrap: anywhere;
  font: var(--md-sys-typescale-headline-small); font-weight: 700; letter-spacing: -.01em; color: var(--md-sys-color-on-surface); }
.sethero-sub { margin: 0; overflow-wrap: anywhere; font: var(--md-sys-typescale-body-medium); color: var(--md-sys-color-on-surface-variant); }
.sethero-acts { flex: 0 1 auto; display: flex; flex-wrap: wrap; align-items: center; justify-content: flex-end; gap: 8px; margin-left: auto; }
.sethero-tools { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 16px; padding: 16px 24px; border-top: 1px solid var(--md-sys-color-outline-variant); }
.sethero-search { flex: 0 1 400px; min-width: 0; }
.sethero-search input::-webkit-search-cancel-button,
.sethero-search input::-webkit-search-decoration { -webkit-appearance: none; appearance: none; display: none; }
.sethero-search-x { flex: none; margin: 0 -12px 0 -8px; color: inherit; }   /* .ibtn « Effacer la recherche » */
.sethero-search-x[hidden] { display: none; }
.sethero-count { margin: 0; font: var(--md-sys-typescale-body-small); color: var(--md-sys-color-on-surface-variant); }
.sethero-count:empty { display: none; }
@container sethero (max-width: 679px) {
  .sethero-main { gap: 12px 16px; padding: 16px; }
  .sethero-tools { padding: 12px 16px 16px; }
  .sethero-acts { flex: 1 1 100%; justify-content: flex-start; margin-left: 0; }
  .sethero-search { flex: 1 1 100%; }
}
@container sethero (max-width: 459px) {
  .sethero-txt { flex-basis: 160px; }   /* le nom reste à côté de l'avatar */
  .sethero-acts > .cbtn { flex: 1 1 auto; justify-content: center; }
  .sethero-banner + .sethero-main > .sethero-ava { margin-top: -36px; }
}

/* ── 2. Grille de cartes ── */
.setg { container: setg / inline-size; min-width: 0; }
.setg > .empty-state { margin: 0 0 24px; }
.setg-cols { display: grid; grid-template-columns: minmax(0, 1fr); gap: 24px; align-items: start; }
.setg-col { display: flex; flex-direction: column; gap: 24px; min-width: 0; }
.setg-col > [hidden], .setg-col:not(:has(> :not([hidden]))) { display: none; }
@container setg (min-width: 880px) {
  .setg-cols { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* ── 3. Carte de section (.sblk.setc) ── */
.setc { scroll-margin-top: 16px; }
.setc-head { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 12px; min-height: 24px; padding: 16px 20px 4px; }
.setc-label { display: inline-flex; align-items: center; gap: 8px; min-width: 0; margin: 0;
  font: var(--md-sys-typescale-label-large); font-weight: 700; letter-spacing: 0; color: var(--md-sys-color-primary); }
.setc-label svg { flex: none; width: 16px; height: 16px; }
.setc-label:focus { outline: none; }
.setc-label:focus-visible { outline: 3px solid var(--md-sys-color-primary); outline-offset: 4px; border-radius: var(--md-sys-shape-corner-extra-small); }
.setc--danger .setc-label { color: var(--md-sys-color-on-error-container); }
.setc-mark { display: inline-flex; }
.setc-mark:empty { display: none; }
.setc-side { display: inline-flex; flex-wrap: wrap; align-items: center; gap: 8px; margin-left: auto; }
.setc-side:empty { display: none; }
.setc-intro { margin: 0; padding: 4px 20px 0; font: var(--md-sys-typescale-body-small); color: var(--md-sys-color-on-surface-variant); }
.setc-body { display: flex; flex-direction: column; min-width: 0; padding: 0 20px 8px; }
.setc-body > :is(.alert, .grid-state, .empty-state) { margin: 12px 0; }
.setc-body > .sblk-empty { padding: 12px 0 16px; }
.setc-foot { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 16px; padding: 0 20px 4px; border-top: 1px solid var(--md-sys-color-outline-variant); }
.setc-foot > .lnk { min-height: 44px; }
.setc-foot[hidden] { display: none; }
/* Lignes : un interrupteur ou un bouton icône seul reste au bout de la ligne, même étroite. */
.setc .stp-row { min-height: 44px; }
.setc .stp-row:has(> .ex-toggle),
.setc .stp-row:has(> .stp-row-acts > :is(.ex-toggle, .ibtn):only-child) { flex-wrap: nowrap; }
.setc .stp-row-acts > .ex-field { width: 220px; max-width: 100%; }   /* liste au bout de la ligne : .ex-field > .ex-select */
.setc .stp-row-sub .lnk { vertical-align: baseline; }
.setc .stp-row-clamp { display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; overflow: hidden; }
.setc .sblk-sep { margin-top: 4px; }
.setc .stp-infos { border-top: 0; }
.setc .stp-info:last-child { border-bottom: 0; }
@media (max-width: 560px) {
  .setc-head, .setc-intro, .setc-body, .setc-foot { padding-left: 16px; padding-right: 16px; }
  .setc .stp-row-acts:has(> .ex-field) { flex: 1 1 100%; }   /* la liste passe sous le texte, pleine largeur */
  .setc .stp-row-acts > .ex-field { width: 100%; }
}

/* ── 4. Recherche : ligne trouvée, mot surligné ── */
.setc :is(.stp-row, .snotif-row, .stp-info).is-hit { margin-inline: -8px; padding-inline: 8px; border-radius: var(--md-sys-shape-corner-small);
  background: color-mix(in srgb, var(--md-sys-color-primary) 8%, transparent); }
::highlight(setq) { background-color: color-mix(in srgb, var(--md-sys-color-primary) 32%, transparent); color: var(--md-sys-color-on-surface); }

/* ── 5. Fenêtre de rubrique avec pied d'actions (.srw > .stp-foot) ── */
@media (max-width: 600px) {
  .srw > .stp-foot { padding: 12px 16px calc(12px + env(safe-area-inset-bottom)); }
  .srw > .stp-foot > .cbtn { flex: 1 1 0; justify-content: center; }
}

/* ═══════════════════════════════════════════════════════════════════════
   BASCULE STUDIO / SITE (.tbar-switch) · À décider (demande du porteur du 07/10/2026)
   Créateurs seulement : à côté du logo, le nom de l'espace courant ouvre un menu à deux
   choix, « SydePlay » (/) et « Studio » (/studio), le choix courant coché. Le logo reste
   un lien vers l'accueil de l'espace. Mécanique et peau des autres menus de la barre :
   .tbar-dd (pleine hauteur, data-open), panneau .tbar-dd-panel.menu ouvert 8 px SOUS la
   barre, aligné à GAUCHE sur le logo. Posé par shared/shell-ds.js (barre du haut et tête
   du burger). Spectateurs et visiteurs : le logo seul (.tbar-logo-link), inchangé.
   ═══════════════════════════════════════════════════════════════════════ */
.tbar-switch { gap: 0; }
/* Déclencheur : 44 de haut, rayon 12, couche d'état, chevron 18 qui se retourne (.tbar-caret).
   Studio : le mot « Studio » garde le dessin du logo du Studio (.tbar-logo-studio), toujours
   8 px après le logo (2 de marge + 6 de retrait). Site : le chevron seul, centré sur 44 × 44. */
.tbar-switch-t { flex: none; display: inline-flex; align-items: center; gap: 4px; height: 44px; margin: 0 0 0 2px; padding: 0 6px;
  border: 0; border-radius: var(--md-sys-shape-corner-medium); background: transparent; color: var(--md-sys-color-on-surface-variant);
  cursor: pointer; transition: background-color .15s ease; }
.tbar-switch-t:hover { background: var(--sp-hover-bg); }
.tbar-switch-t:focus-visible { outline: 3px solid var(--md-sys-color-primary); outline-offset: 2px; }
.tbar-switch-t .tbar-logo-studio { margin-left: 0; }
.tbar-switch-t > svg { flex: none; }
.tbar-switch-t--icon { min-width: 44px; justify-content: center; }
/* Panneau : aligné sur le bord gauche du logo, 360 de large, jamais plus que l'écran moins 32. */
.tbar-switch > .tbar-dd-panel { left: 0; right: auto; width: 360px; max-width: calc(100vw - 32px); box-sizing: border-box; }
/* Ligne : icône 20, nom (label-large 600) et sa phrase (body-small, on-surface-variant) sur
   deux lignes de texte, coche primary au bout ; 44 de haut tant que la phrase tient sur une
   ligne, elle ne grandit que si la phrase passe à la ligne (téléphone étroit). */
.tbar-switch-panel [role="menuitemradio"] { height: auto; min-height: 44px; padding: 4px 12px; white-space: normal; }
.tbar-switch-txt { display: flex; flex-direction: column; min-width: 0; }
.tbar-switch-txt b { font: var(--md-sys-typescale-label-large); font-weight: 600; color: var(--md-sys-color-on-surface); }
.tbar-switch-txt i { font: var(--md-sys-typescale-body-small); font-style: normal; color: var(--md-sys-color-on-surface-variant); }
@media (prefers-reduced-motion: reduce) { .tbar-switch-t { transition: none; } }

/* ── PARAMÈTRES v2 · ONGLETS PAR FAMILLES (retour du porteur, 07/10/2026, à valider) ─────────────
   Barre d'onglets .ex-tabs.setg-tabs au-dessus de la grille .setg : une famille de réglages par
   onglet (Compte, Abonnements…). Pendant une recherche, les onglets s'estompent (la recherche porte
   sur toutes les familles). Une famille d'une seule carte prend toute la largeur (.is-single). */
.setg-tabs { margin: 8px 0 20px; border-bottom: 1px solid var(--md-sys-color-outline-variant); overflow-x: auto; scrollbar-width: none; }
.setg-tabs::-webkit-scrollbar { display: none; }
.setg-tabs [role="tab"] { white-space: nowrap; }
.setg-tabs.is-searching [role="tab"] { opacity: var(--md-sys-state-disabled-opacity, .38); }
.setg-cols.is-single { grid-template-columns: minmax(0, 1fr); }

/* ═══════════════════════════════════════════════════════════════════════
   FILTRE PAR ŒUVRE (shared/work-filter.js, posé par la barre de liste) · À décider
   Demande du porteur du 07/10/2026 : dans Contenus, Statistiques et les recherches du site,
   la saisie propose les ŒUVRES qui correspondent, dans le panneau de la recherche de la barre
   du haut (.tbar-search-panel, .tbar-sr-item, .tbar-sr-cover, .tbar-sr-txt) : affiche, titre,
   nature (.bdg--sm pastel) et nombre de lignes. Combobox ARIA 1.2 (flèches, Entrée, Échap,
   souris) ; option active .is-active (couche focus + anneau 2 px primary, comme .wpick-opt).
   L'œuvre choisie devient une puce DANS le champ (.chip.chip--on.wf-chip : petite affiche,
   titre coupé par « … », croix ; un clic, ou Effacer dans le champ vide, la retire). Ensuite,
   dans la barre, juste après le champ (.wf-row) : « Saisons » puis « Épisodes » (sélecteurs à menu .ex-selbtn + menus
   du DS à cases .ex-box, groupés par saison avec .menu-label, nombre de lignes en bout).
   Placement et états seulement : les peaux viennent des composants cités.
   ═══════════════════════════════════════════════════════════════════════ */
/* Le champ et son panneau : le bloc garde la place de .lhead-search (280 à 400). */
.wf-search { position: relative; display: flex; }
.wf-search > .ex-search { flex: 1 1 auto; width: auto; min-width: 0; }
/* Puce dans le champ : 32 de haut (.chip), affiche 18 × 24 au rayon 4, croix 16. */
.wf-chip { flex: 0 1 auto; min-width: 0; max-width: 55%; gap: 6px; padding: 0 8px 0 4px; }
.wf-chip svg { width: 16px; height: 16px; }
.wf-chip-cover { flex: none; display: inline-flex; align-items: center; justify-content: center; width: 18px; height: 24px; overflow: hidden;
  border-radius: var(--md-sys-shape-corner-extra-small); background: var(--md-sys-color-surface-container-high); color: var(--md-sys-color-on-surface-variant); }
.wf-chip-cover img { width: 100%; height: 100%; object-fit: cover; display: block; }
.wf-chip-cover svg { width: 14px; height: 14px; }
.wf-chip-t { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* Panneau des suggestions : sous le champ, de sa largeur (300 à 420 du panneau de la barre du haut). */
.wf-panel { position: absolute; top: calc(100% + 8px); left: 0; z-index: 45; width: 100%; }
.wf-panel[hidden] { display: none; }
.wf-panel .tbar-sr-item.is-active { box-shadow: inset 0 0 0 2px var(--md-sys-color-primary); }
.wf-panel .tbar-sr-item.is-active::after { opacity: var(--md-sys-state-focus-opacity); }
/* Même repère dans la recherche de la barre du haut (combobox : les flèches posent .is-active). */
.tbar-search-panel .tbar-sr-item.is-active { box-shadow: inset 0 0 0 2px var(--md-sys-color-primary); }
.tbar-search-panel .tbar-sr-item.is-active::after { opacity: var(--md-sys-state-focus-opacity); }
.wf-opt-meta { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 6px; margin-top: 2px; }
/* Saisons / Épisodes : DANS la barre, juste après le champ (retour du porteur du 07/10 : seuls
   sur une 2e ligne, ils paraissaient détachés). .wf-row ne fait que les grouper : ses menus sont
   des outils de la barre comme les autres et passent à la ligne avec eux. */
.wf-row { display: contents; }
.wf-row[hidden] { display: none; }
.wf-selbtn { max-width: 100%; }
.wf-selbtn-t { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
/* Menus : une colonne, 240 à 440 de large ; un titre d'épisode trop long est coupé (titre complet en infobulle). */
.wf-pop { width: max-content; min-width: 240px; max-width: min(440px, calc(100vw - 32px)); max-height: min(60vh, 440px); overflow-y: auto; }
.wf-pop [role="menuitemcheckbox"] > .wf-opt-t { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.wf-ep-n { font-weight: 600; }
.wf-count { flex: none; margin-left: auto; padding-left: 8px; font: var(--md-sys-typescale-body-small); font-variant-numeric: tabular-nums; color: var(--md-sys-color-on-surface-variant); }
/* Barre étroite (téléphone) : panneau et menus de toute la largeur de la barre, titres d'épisode sur plusieurs lignes. */
@container lhead (max-width: 479px) {
  /* Une œuvre choisie : le champ prend toute la ligne (Filtre et Trier passent dessous), la puce les deux tiers. */
  .wf-search:has(.wf-chip) { flex-basis: 100%; }
  .wf-chip { max-width: 66%; }
  .wf-panel { width: 100cqw; min-width: 0; max-width: none; }
  .wf-pop { width: auto; min-width: 0; max-width: none; }
  .wf-pop [role="menuitemcheckbox"] { height: auto; min-height: 44px; padding-top: 10px; padding-bottom: 10px; white-space: normal; }
  .wf-pop [role="menuitemcheckbox"] > .wf-opt-t { overflow: visible; text-overflow: clip; overflow-wrap: anywhere; }
}

/* ════════════════════════════════════════════════════════════════════
   RÉGIE — studio v2 (07/10/2026, À valider)
   Les composants rg- du nouveau Studio (Plateau, Œuvres, Publier, Salle). Documentés sur
   /design-system (Patterns, « Régie · … »), statut À décider. Uniquement des jetons : couleurs
   --md-sys-color-* (et --sp-tl-* pour la frise), typo --md-sys-typescale-*, rayons
   --md-sys-shape-corner-*. Couleurs (07/10/2026) : le rose SydePlay et les neutres seulement,
   voir « STUDIO — couleurs SydePlay » (plus de warning ni de badges de palette). Éléments cliquables de 44 px
   au moins, anneau de focus 3 px primary, couche d'état currentColor comme .tbar-sr-item.
   Seules valeurs posées par le JS : les positions et largeurs en % (frise, barres de pays).
   ════════════════════════════════════════════════════════════════════ */

/* ── Affiche (toutes les cartes rg-) : fond surface-container-high ; sans image, l'icône film de
   Lucide (dessinée par masque quand la case est vide, ou icon("film") posée par le JS). ── */
:is(.rg-work-poster, .rg-next-poster, .rg-reco-poster, .rg-workhead-poster) {
  position: relative; flex: none; display: inline-flex; align-items: center; justify-content: center; overflow: hidden;
  aspect-ratio: 2 / 3; box-sizing: border-box; border-radius: var(--md-sys-shape-corner-small);
  background: var(--md-sys-color-surface-container-high); color: var(--md-sys-color-on-surface-variant); }
:is(.rg-work-poster, .rg-next-poster, .rg-reco-poster, .rg-workhead-poster) img { display: block; width: 100%; height: 100%; object-fit: cover; }
:is(.rg-work-poster, .rg-next-poster, .rg-reco-poster, .rg-workhead-poster) svg { width: 40%; max-width: 32px; height: auto; }
:is(.rg-work-poster, .rg-next-poster, .rg-reco-poster, .rg-workhead-poster):empty::before {
  content: ""; width: 40%; max-width: 32px; aspect-ratio: 1; background: currentColor;
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect width='18' height='18' x='3' y='3' rx='2'/%3E%3Cpath d='M7 3v18M3 7.5h4M3 12h18M3 16.5h4M17 3v18M17 7.5h4M17 16.5h4'/%3E%3C/svg%3E") center / contain no-repeat;
          mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect width='18' height='18' x='3' y='3' rx='2'/%3E%3Cpath d='M7 3v18M3 7.5h4M3 12h18M3 16.5h4M17 3v18M17 7.5h4M17 16.5h4'/%3E%3C/svg%3E") center / contain no-repeat; }

/* ── Couche d'état et focus des éléments cliquables rg- ── */
:is(.rg-work, .rg-pcard, .rg-step, .rg-ep) { position: relative; isolation: isolate; }
:is(.rg-work, .rg-pcard, .rg-step, .rg-ep)::after { content: ""; position: absolute; inset: 0; z-index: -1; border-radius: inherit;
  background: currentColor; opacity: 0; pointer-events: none; transition: opacity .15s ease; }
:is(.rg-work, .rg-pcard, .rg-step, .rg-ep):hover::after { opacity: var(--md-sys-state-hover-opacity); }
:is(.rg-work, .rg-pcard, .rg-step, .rg-ep):focus-visible::after { opacity: var(--md-sys-state-focus-opacity); }
:is(.rg-work, .rg-pcard, .rg-step, .rg-ep):active::after { opacity: var(--md-sys-state-pressed-opacity); }
:is(.rg-work, .rg-pcard, .rg-step, .rg-ep):focus-visible { outline: 3px solid var(--md-sys-color-primary); outline-offset: 2px; }
:is(.rg-step, .rg-ep):disabled { cursor: not-allowed; opacity: var(--md-sys-state-disabled-opacity); }
:is(.rg-step, .rg-ep):disabled::after { display: none; }
/* Présence (07/10/2026) : les cartes bordées marquent le survol par un filet plus net (outline). */
:is(.rg-work, .rg-pcard, .rg-ep) { transition: border-color .15s ease; }
:is(.rg-work, .rg-pcard, .rg-ep):not([aria-pressed="true"]):not(:disabled):hover { border-color: var(--md-sys-color-outline); }

/* ── 1. Couverture épisode par épisode : un carré par épisode, une ligne par saison. ── */
.rg-cov { display: flex; align-items: flex-start; gap: 8px; min-width: 0; }
.rg-cov-l { flex: none; min-width: 26px; font: var(--md-sys-typescale-label-small); font-weight: 600; line-height: 14px;
  font-variant-numeric: tabular-nums; color: var(--md-sys-color-on-surface-variant); }
.rg-cov-sq { flex: 1; min-width: 0; display: flex; flex-wrap: wrap; gap: 3px; }
.rg-cov-n { flex: none; font: var(--md-sys-typescale-label-small); line-height: 14px; font-variant-numeric: tabular-nums; color: var(--md-sys-color-on-surface-variant); }
.rg-sq { flex: none; display: inline-block; width: 12px; height: 12px; margin-top: 1px; box-sizing: border-box;
  border-radius: calc(var(--md-sys-shape-corner-extra-small) / 2);   /* 2 px : la case reste une case (maquette) */
  background: var(--md-sys-color-surface-container-high); }
/* Couleurs SydePlay (07/10/2026, À valider) : le rose de marque et les neutres seulement ; la forme
   (plein, contour, tirets) distingue les états autant que la teinte. */
.rg-sq--on { background: var(--sp-grad-brand); }                                                              /* en ligne */
.rg-sq--scheduled { background: transparent; border: 2px solid var(--md-sys-color-primary); }                 /* programmée */
.rg-sq--private { background: transparent; border: 2px solid var(--md-sys-color-on-surface-variant); }        /* privée, prête */
.rg-sq--draft { background: color-mix(in srgb, var(--md-sys-color-primary) 45%, transparent); }               /* au calage, brouillon */
/* À tourner : contour en TIRETS. Un border dashed de 2 sur une case de 12 se dessine plein à l'écran ;
   les tirets sont donc peints : 3 tirets de 2 par côté (1, 5 et 9 px), coins ouverts. */
.rg-sq--planned { --rg-dash: var(--md-sys-color-on-surface-variant);
  background:
    linear-gradient(90deg, transparent 1px, var(--rg-dash) 1px 3px, transparent 3px) 0 0 / 4px 2px repeat-x,
    linear-gradient(90deg, transparent 1px, var(--rg-dash) 1px 3px, transparent 3px) 0 100% / 4px 2px repeat-x,
    linear-gradient(180deg, transparent 1px, var(--rg-dash) 1px 3px, transparent 3px) 0 0 / 2px 4px repeat-y,
    linear-gradient(180deg, transparent 1px, var(--rg-dash) 1px 3px, transparent 3px) 100% 0 / 2px 4px repeat-y; }
.rg-sq--none { background: var(--md-sys-color-surface-container-high); }                                      /* rien, pas encore */
.rg-legend { display: flex; flex-wrap: wrap; gap: 8px 16px; margin: 0; padding: 0; list-style: none;
  font: var(--md-sys-typescale-label-medium); color: var(--md-sys-color-on-surface-variant); }
.rg-legend li { display: inline-flex; align-items: center; gap: 6px; }
.rg-legend li[hidden] { display: none; }   /* sinon inline-flex l'emporte sur hidden (« Saison longue… » toujours affichée) */
.rg-legend .rg-sq { margin-top: 0; }

/* ── 2. Carte d'œuvre du studio et sa grille (présence 07/10/2026 : carte bordée sur
   surface-container-low, affiche 92, titre headline-small 700). ── */
.rg-works { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, 300px), 1fr)); gap: 16px; }
.rg-work { display: flex; gap: 16px; min-width: 0; min-height: 44px; padding: 16px; box-sizing: border-box; text-decoration: none;
  background: var(--md-sys-color-surface-container-low); border: 1px solid var(--md-sys-color-outline-variant);
  border-radius: var(--md-sys-shape-corner-large); color: var(--md-sys-color-on-surface); }
.rg-work-poster { width: 92px; align-self: flex-start; }
.rg-work-b { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 8px; }
.rg-work-t { font: var(--md-sys-typescale-headline-small); font-weight: 700; letter-spacing: -.01em; color: var(--md-sys-color-on-surface);
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; overflow-wrap: anywhere; }
.rg-work-sub { margin-top: -4px; font: var(--md-sys-typescale-body-small); color: var(--md-sys-color-on-surface-variant); }
.rg-work-b > .rg-cov + .rg-cov { margin-top: -2px; }
.rg-work-f { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 4px 12px; margin-top: auto; padding-top: 8px;
  font: var(--md-sys-typescale-label-medium); font-weight: 600; font-variant-numeric: tabular-nums; color: var(--md-sys-color-on-surface-variant); }
.rg-work-f > span { display: inline-flex; align-items: center; gap: 4px; }
.rg-work-f svg { flex: none; width: 14px; height: 14px; }

/* ── 3. Table de montage : 4 colonnes à 1100 px et plus, 2 de 720 à 1099, 1 en dessous.
   Présence (07/10/2026) : colonnes bordées et hautes (220), cartes bordées sur surface-container. ── */
.rg-pipe { display: grid; grid-template-columns: minmax(0, 1fr); gap: 12px; align-items: stretch; }
@media (min-width: 720px) { .rg-pipe { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (min-width: 1100px) { .rg-pipe { grid-template-columns: repeat(4, minmax(0, 1fr)); } }
.rg-pcol { min-width: 0; min-height: 220px; display: flex; flex-direction: column; gap: 8px; padding: 12px; box-sizing: border-box;
  background: var(--md-sys-color-surface-container-lowest); border: 1px solid var(--md-sys-color-outline-variant);
  border-radius: var(--md-sys-shape-corner-medium); }
.rg-pcol-h { display: flex; align-items: center; justify-content: space-between; gap: 8px; min-height: 30px; padding: 2px 2px 6px; }
.rg-pcol-n { font: var(--md-sys-typescale-title-large); font-weight: 700; font-variant-numeric: tabular-nums; color: var(--md-sys-color-on-surface); }
.rg-pcard { display: flex; flex-direction: column; gap: 4px; min-height: 44px; padding: 12px; box-sizing: border-box; text-decoration: none;
  background: var(--md-sys-color-surface-container); border: 1px solid var(--md-sys-color-outline-variant);
  border-radius: var(--md-sys-shape-corner-small); color: var(--md-sys-color-on-surface); }
.rg-pcard-t { font: var(--md-sys-typescale-title-medium); font-weight: 700; overflow-wrap: anywhere;
  display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden; }   /* 3 lignes au plus (infobulle : title), audit break-ui du 15/10/2026 */
.rg-pcard-sub { font: var(--md-sys-typescale-body-small); color: var(--md-sys-color-on-surface-variant); overflow-wrap: anywhere; }
.rg-pcard-meta { font: var(--md-sys-typescale-label-small); font-variant-numeric: tabular-nums; color: var(--md-sys-color-on-surface-variant); }

/* ── 4. Frise de synchronisation (seed) : ta vidéo en entier, l'épisode posé dessus, les pauses
   (orange du calage, --sp-tl-pause) et les points d'ancrage (rose du calage, --sp-tl-point). ── */
.rg-sync { display: flex; flex-direction: column; gap: 8px; min-width: 0; }
.rg-sync-row { display: grid; grid-template-columns: 72px minmax(0, 1fr); align-items: center; gap: 12px; }
.rg-sync-l { font: var(--md-sys-typescale-label-medium); color: var(--md-sys-color-on-surface-variant); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.rg-lane { position: relative; display: block; height: 20px; overflow: hidden; border-radius: var(--md-sys-shape-corner-small);
  background: var(--md-sys-color-surface-container-high); }
.rg-seg, .rg-gap { position: absolute; top: 0; bottom: 0; display: block; }
.rg-seg--me { background: var(--md-sys-color-primary); }                 /* ta vidéo */
.rg-seg--ep { background: var(--md-sys-color-on-surface-strong); }       /* l'épisode */
.rg-gap { z-index: 1; background: var(--sp-tl-pause); }                  /* pause : l'épisode attend */
.rg-mark { position: absolute; z-index: 2; top: 3px; bottom: 3px; display: block; width: 3px; transform: translateX(-1.5px);
  border-radius: var(--md-sys-shape-corner-full); background: var(--sp-tl-point); box-shadow: 0 0 0 1px var(--md-sys-color-surface); }
.rg-sync-scale { display: flex; justify-content: space-between; gap: 8px; margin-left: 84px;
  font: var(--md-sys-typescale-label-small); font-variant-numeric: tabular-nums; color: var(--md-sys-color-on-surface-variant); }
/* Sous 360 px, trois repères seulement (début, milieu, fin) : cinq heures « 1:50:36 » ne tenaient pas, la
   dernière sortait du panneau (audit break-ui du 15/10/2026). */
@media (max-width: 359px) { .rg-sync-scale > span:nth-child(even) { display: none; } }

/* ── 5. Pays : drapeau + nom, barre, part, nombre. Liste de 420 px ou moins : la barre passe dessous. ── */
.rg-geo { container: rg-geo / inline-size; display: flex; flex-direction: column; gap: 4px; margin: 0; padding: 0; list-style: none; }
.rg-geo-row { display: grid; grid-template-columns: minmax(0, 1.3fr) minmax(64px, 2fr) 4em 5em; align-items: center; gap: 4px 12px; min-height: 40px; }
.rg-geo-n { display: flex; align-items: center; gap: 8px; min-width: 0; font: var(--md-sys-typescale-body-medium); color: var(--md-sys-color-on-surface);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.rg-geo-n > span[aria-hidden] { flex: none; }
/* Le nom du pays dans son propre span : dans le flex, un texte nu était coupé net, sans points de suspension. */
.rg-geo-n > .rg-geo-nt { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.rg-geo-bar { display: block; height: 10px; overflow: hidden; border-radius: var(--md-sys-shape-corner-full); background: var(--md-sys-color-surface-container-high); }
.rg-geo-bar > span { display: block; height: 100%; border-radius: var(--md-sys-shape-corner-full); background: var(--sp-grad-brand-bar); }
.rg-geo-v { text-align: right; font: var(--md-sys-typescale-label-large); font-weight: 600; font-variant-numeric: tabular-nums; color: var(--md-sys-color-on-surface); }
.rg-geo-c { text-align: right; font: var(--md-sys-typescale-body-small); font-weight: 600; font-variant-numeric: tabular-nums; color: var(--md-sys-color-on-surface-variant); }
@container rg-geo (max-width: 420px) {
  .rg-geo-row { grid-template-columns: minmax(0, 1fr) 3.5em 3.5em; padding: 4px 0; }   /* la place gagnée va au nom */
  .rg-geo-bar { grid-column: 1 / -1; grid-row: 2; }
}

/* ── 6. Glissement d'accès : de la plus haute marche (rose plein) à « gratuite » (rose pâle).
   Passé = gris, aujourd'hui = date en rose et marche plus épaisse. Liste étroite : verticale. ── */
.rg-ladder { container: rg-ladder / inline-size; display: grid; grid-auto-flow: column; grid-auto-columns: minmax(0, 1fr); gap: 4px; margin: 0; padding: 0; list-style: none; }
.rg-ladder-s { --rg-k: 30%; position: relative; display: flex; flex-direction: column; gap: 2px; min-width: 0; padding-top: 14px; }
.rg-ladder-s:nth-child(1) { --rg-k: 100%; }
.rg-ladder-s:nth-child(2) { --rg-k: 75%; }
.rg-ladder-s:nth-child(3) { --rg-k: 55%; }
.rg-ladder-s:nth-child(4) { --rg-k: 40%; }
.rg-ladder-s:last-child:not(:first-child) { --rg-k: 22%; }
.rg-ladder-s::before { content: ""; position: absolute; top: 0; left: 0; right: 0; height: 6px; border-radius: var(--md-sys-shape-corner-full);
  background: color-mix(in srgb, var(--md-sys-color-primary) var(--rg-k), var(--md-sys-color-surface-container-high)); }
.rg-ladder-s b { font: var(--md-sys-typescale-label-large); font-weight: 600; font-variant-numeric: tabular-nums; color: var(--md-sys-color-on-surface); }
.rg-ladder-s span { font: var(--md-sys-typescale-body-small); color: var(--md-sys-color-on-surface-variant); overflow-wrap: anywhere; }
.rg-ladder-s.is-past::before { background: var(--md-sys-color-outline-variant); }
.rg-ladder-s.is-past b { color: var(--md-sys-color-on-surface-variant); font-weight: 500; }
.rg-ladder-s.is-now::before { top: -2px; height: 10px; }
.rg-ladder-s.is-now b { color: var(--md-sys-color-primary); }
@container rg-ladder (max-width: 420px) {
  .rg-ladder-s { grid-column: 1; padding: 0 0 6px 16px; }   /* une marche par ligne, marche verticale à gauche */
  .rg-ladder-s::before, .rg-ladder-s.is-now::before { top: 2px; bottom: 8px; left: 0; right: auto; width: 6px; height: auto; }
  .rg-ladder-s.is-now::before { top: 0; bottom: 6px; left: -2px; width: 10px; }
}

/* ── 7. Étapes du Publier : des segments sur une seule ligne (un par étape), trait de 3 en haut
   (outline-variant ; faite = primary atténué ; en cours = primary), numéro en chasse fixe, nom en
   capitales, rappel du choix. Présence 07/10/2026. Sous 480 px : seul le nom de l'étape en cours
   reste visible (les autres gardent leur nom pour les lecteurs d'écran). ── */
.rg-steps { display: grid; grid-auto-flow: column; grid-auto-columns: minmax(0, 1fr); gap: 4px; }
.rg-step { display: flex; flex-direction: column; align-items: flex-start; gap: 2px; min-width: 0; min-height: 56px;
  padding: 8px 12px 10px; box-sizing: border-box; cursor: pointer; text-align: left; font: inherit;
  background: transparent; border: 0; border-top: 3px solid var(--md-sys-color-outline-variant);
  border-radius: 0 0 var(--md-sys-shape-corner-small) var(--md-sys-shape-corner-small); color: var(--md-sys-color-on-surface-variant); }
.rg-step:hover:not(:disabled) { color: var(--md-sys-color-on-surface); }
.rg-step-n { font-family: var(--sp-font-mono); font-size: var(--md-sys-typescale-label-small-size); font-weight: 500; letter-spacing: .04em;
  line-height: var(--md-sys-typescale-label-small-line-height); font-variant-numeric: tabular-nums; }
.rg-step b { max-width: 100%; font: var(--md-sys-typescale-title-medium); font-weight: 700; letter-spacing: 0;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.rg-step-sub { max-width: 100%; font: var(--md-sys-typescale-body-small); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.rg-step-sub:empty { display: none; }
.rg-step.is-done { border-top-color: color-mix(in srgb, var(--md-sys-color-primary) 45%, transparent); }
.rg-step.is-cur { border-top-color: var(--md-sys-color-primary); color: var(--md-sys-color-on-surface); }
.rg-step.is-cur .rg-step-n { color: var(--md-sys-color-primary); }
@media (max-width: 760px) {
  .rg-step { padding: 8px 8px 10px; }
  .rg-step b { font: var(--md-sys-typescale-label-large); font-weight: 700; letter-spacing: .02em; }
  .rg-step-sub { display: none; }
}
@media (max-width: 479px) {
  .rg-steps { grid-auto-columns: minmax(max-content, 1fr); }
  .rg-step:not(.is-cur) b { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }
}

/* ── 8. Prochaine sortie : la grande carte vedette du Plateau. Affiche 168 | clé (warning) + titre
   en capitales + phrase + chiffres géants entre deux filets + actions. Présence 07/10/2026.
   Le corps passe sous l'affiche quand la carte est étroite. ── */
.rg-next { display: flex; flex-wrap: wrap; gap: 24px; min-width: 0; padding: 20px; box-sizing: border-box;
  background: var(--md-sys-color-surface-container-low); border: 1px solid var(--md-sys-color-outline-variant); border-radius: var(--md-sys-shape-corner-large); }
.rg-next-poster { width: 168px; align-self: flex-start; border-radius: var(--md-sys-shape-corner-small); }
.rg-next-b { flex: 1 1 340px; min-width: 0; display: flex; flex-direction: column; gap: 12px; }
.rg-next-k { margin: 0; font: var(--md-sys-typescale-label-large); font-weight: 600; letter-spacing: 0; color: var(--sp-brand-ink); }
.rg-next-t { margin: 0; font: var(--md-sys-typescale-headline-large); font-weight: 700; line-height: 1.1; letter-spacing: -.02em;
  color: var(--md-sys-color-on-surface); overflow-wrap: anywhere; }
.rg-next-b > p:not(.rg-next-k) { margin: 0; font: var(--md-sys-typescale-body-large); color: var(--md-sys-color-on-surface-variant); }
.rg-next-facts { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 140px), 1fr)); gap: 16px; margin: 0; padding: 14px 0;
  border-top: 1px solid var(--md-sys-color-outline-variant); border-bottom: 1px solid var(--md-sys-color-outline-variant); }
.rg-next-facts > div { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.rg-next-facts dt { order: 2; font: var(--md-sys-typescale-body-small); color: var(--md-sys-color-on-surface-variant); }
.rg-next-facts dd { order: 1; margin: 0; font: var(--md-sys-typescale-display-small); font-weight: 700; line-height: 1; letter-spacing: -.01em;
  font-variant-numeric: tabular-nums; color: var(--md-sys-color-on-surface); }
.rg-next-acts { display: flex; flex-wrap: wrap; gap: 8px; margin-top: auto; padding-top: 4px; }
@media (min-width: 900px) {
  .rg-next { padding: 24px; }
  .rg-next-t { font: var(--md-sys-typescale-display-small); font-weight: 700; line-height: 1.05; letter-spacing: -.01em; }
}
@media (max-width: 600px) { .rg-next { gap: 16px; padding: 16px; } .rg-next-poster { width: 120px; } }

/* ── 9. Ligne d'épisode (liste à choix) : code, titre et sous-titre, état, spectateurs.
   Présence 07/10/2026 : lignes bordées sur surface-container-low, code en gros (headline-small 700),
   ligne choisie = filet primary et fond teinté de primary. ── */
.rg-eps { container: rg-eps / inline-size; display: flex; flex-direction: column; gap: 6px; }
/* Code : 52 px au moins, et la place d'un code à 4 chiffres (« E1068 ») quand il le faut. */
.rg-ep { display: grid; grid-template-columns: minmax(52px, max-content) minmax(0, 1fr) auto auto; align-items: center; gap: 4px 12px; width: 100%; min-height: 56px;
  padding: 8px 14px; box-sizing: border-box; cursor: pointer; text-align: left; font: inherit;
  background: var(--md-sys-color-surface-container-low); border: 1px solid var(--md-sys-color-outline-variant);
  border-radius: var(--md-sys-shape-corner-small); color: var(--md-sys-color-on-surface); }
.rg-ep[aria-pressed="true"] { border-color: var(--md-sys-color-primary);
  background: var(--sp-grad-brand-soft), color-mix(in srgb, var(--md-sys-color-primary) 6%, var(--md-sys-color-surface-container-low)); }
.rg-ep-code { font: var(--md-sys-typescale-headline-small); font-weight: 700; letter-spacing: -.01em; font-variant-numeric: tabular-nums; color: var(--md-sys-color-on-surface); }
.rg-ep[aria-pressed="true"] .rg-ep-code { color: var(--md-sys-color-primary); }
.rg-ep-t { display: flex; flex-direction: column; min-width: 0; }
.rg-ep-t > span:first-child { font: var(--md-sys-typescale-title-medium); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.rg-ep-sub { font: var(--md-sys-typescale-body-small); color: var(--md-sys-color-on-surface-variant); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.rg-ep-m { min-width: 7em; text-align: right; white-space: nowrap; font: var(--md-sys-typescale-body-small); font-variant-numeric: tabular-nums; color: var(--md-sys-color-on-surface-variant); }
@container rg-eps (max-width: 479px) {
  .rg-ep { grid-template-columns: minmax(44px, max-content) minmax(0, 1fr) auto; padding: 8px 12px; }
  .rg-ep-m { grid-column: 2 / -1; min-width: 0; text-align: left; }
}

/* ── 10. Recommandation (studio) : nombre, affiche, œuvre et statut, actions. ── */
.rg-recos { container: rg-recos / inline-size; display: flex; flex-direction: column; margin: 0; padding: 0; list-style: none; }
.rg-reco { display: grid; grid-template-columns: 68px 52px minmax(0, 1fr) auto; align-items: center; gap: 8px 14px; padding: 14px 0;
  border-bottom: 1px solid var(--md-sys-color-outline-variant); }
.rg-reco:last-child { border-bottom: 0; }
/* Présence 07/10/2026 : le nombre en gros, couleur « à faire » (warning), « reco. » en petit espacé. */
.rg-reco-n { display: flex; flex-direction: column; align-items: center; min-width: 0; }
.rg-reco-n b { font: var(--md-sys-typescale-headline-medium); font-weight: 700; line-height: 1.1; letter-spacing: -.01em; font-variant-numeric: tabular-nums; color: var(--md-sys-color-primary); }
.rg-reco-n span { font: var(--md-sys-typescale-label-small); font-weight: 600; letter-spacing: .14em; text-transform: lowercase; color: var(--md-sys-color-on-surface-variant); }
.rg-reco-poster { width: 52px; }
.rg-reco-b { display: flex; flex-direction: column; align-items: flex-start; gap: 2px; min-width: 0; }
.rg-reco-b > b { max-width: 100%; font: var(--md-sys-typescale-title-large); font-weight: 700; color: var(--md-sys-color-on-surface);
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }   /* titre sur 2 lignes (infobulle : title) */
.rg-reco-sub { font: var(--md-sys-typescale-body-small); color: var(--md-sys-color-on-surface-variant); }
.rg-reco-b > :is(.bdg, .st-state) { margin-top: 4px; }
.rg-reco-acts { display: flex; flex-wrap: wrap; justify-content: flex-end; gap: 8px; }
@container rg-recos (max-width: 519px) {
  .rg-reco { grid-template-columns: 56px 44px minmax(0, 1fr); gap: 8px 12px; }
  .rg-reco-poster { width: 44px; }
  .rg-reco-acts { grid-column: 1 / -1; justify-content: flex-start; }
}

/* ── 11. Bande « cette semaine » : les chiffres EN LIGNE sous le titre de page, sans boîte
   (présence 07/10/2026) : sur-titre discret, chiffre géant (display-small 700), écart en petit.
   Passe à la ligne quand la place manque. ── */
.rg-week { display: flex; flex-wrap: wrap; gap: 16px 40px; margin: 0; padding: 0; }
.rg-week-i { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.rg-week-i dt { font: var(--md-sys-typescale-label-large); font-weight: 500; letter-spacing: 0; color: var(--md-sys-color-on-surface-variant); }
.rg-week-i dd { margin: 0; }
.rg-week-v { font: var(--md-sys-typescale-display-small); font-weight: 700; line-height: 1.05; letter-spacing: -.01em; font-variant-numeric: tabular-nums; color: var(--md-sys-color-on-surface); }
.rg-week-d { display: flex; align-items: center; gap: 4px; font: var(--md-sys-typescale-body-small); font-weight: 600; font-variant-numeric: tabular-nums; color: var(--md-sys-color-on-surface-variant); }
.rg-week-d svg { flex: none; width: 14px; height: 14px; }
/* Couleurs SydePlay (07/10/2026) : hausse et baisse restent neutres, l'icône trending-up / -down porte le sens. */
.rg-week-d.is-up, .rg-week-d.is-down { color: var(--md-sys-color-on-surface-variant); }
@media (max-width: 600px) { .rg-week { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 16px; } }

/* ── 12. En-tête d'œuvre : affiche 150, clé discrète, titre géant en capitales (comme .h-display),
   gros chiffres (.rg-facts), actions. Présence 07/10/2026 : le bloc s'aligne en bas de l'affiche. ── */
.rg-workhead { display: grid; grid-template-columns: auto minmax(0, 1fr) auto; align-items: end; gap: 16px 28px; }
.rg-workhead-poster { width: 150px; border-radius: var(--md-sys-shape-corner-small); }
.rg-workhead-b { display: flex; flex-direction: column; gap: 10px; min-width: 0; }
.rg-workhead-k { margin: 0; font: var(--md-sys-typescale-label-large); font-weight: 500; letter-spacing: 0; color: var(--md-sys-color-on-surface-variant); }
.rg-workhead-t { margin: 0; font: var(--md-sys-typescale-display-medium); font-weight: 700; line-height: 1.08; letter-spacing: -.02em;
  color: var(--md-sys-color-on-surface); overflow-wrap: anywhere; }
/* Chiffres : le nombre en gros AU-DESSUS de sa légende (dt reste avant dd dans le code). */
.rg-facts { display: flex; flex-wrap: wrap; gap: 12px 36px; margin: 6px 0 0; padding: 0; }
.rg-facts > div { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.rg-facts dt { order: 2; font: var(--md-sys-typescale-body-small); color: var(--md-sys-color-on-surface-variant); }
.rg-facts dd { order: 1; margin: 0; font: var(--md-sys-typescale-display-small); font-weight: 700; line-height: 1.05; letter-spacing: -.01em;
  font-variant-numeric: tabular-nums; color: var(--md-sys-color-on-surface); }
.rg-workhead-acts { display: flex; flex-wrap: wrap; justify-content: flex-end; gap: 8px; }
@media (max-width: 760px) {
  .rg-workhead { grid-template-columns: auto minmax(0, 1fr); align-items: start; }
  .rg-workhead-poster { width: 110px; }
  .rg-workhead-t { font: var(--md-sys-typescale-display-small); font-weight: 700; line-height: 1.02; letter-spacing: -.01em; }
  .rg-workhead-acts { grid-column: 1 / -1; justify-content: flex-start; }
}

/* 13. Suggestion d'œuvre dans « Recommander » : .tbar-sr-item (+ .tbar-sr-cover, .tbar-sr-txt,
   .is-active) dans .dlg-ov + .ex-panel existants. Aucune nouvelle classe de voile ; seul ajout :
   la suggestion active au clavier est cerclée de rose, comme dans .wf-panel. */
.ex-panel .tbar-sr-item.is-active { box-shadow: inset 0 0 0 2px var(--md-sys-color-primary); }
.ex-panel .tbar-sr-item.is-active::after { opacity: var(--md-sys-state-focus-opacity); }

/* Animations réduites : pas de fondu de la couche d'état ni du filet. */
@media (prefers-reduced-motion: reduce) {
  :is(.rg-work, .rg-pcard, .rg-step, .rg-ep), :is(.rg-work, .rg-pcard, .rg-step, .rg-ep)::after { transition: none; }
}

/* ════════════════════════════════════════════════════════════════════
   STUDIO — présence (07/10/2026, À valider)
   Retour du porteur : « même structure, même énergie que la maquette, design de SydePlay ».
   La maquette parlait en grands titres en capitales, gros chiffres, sur-titres espacés et
   cartes bien bordées ; ici, la même voix avec nos seuls jetons. Refonte du 14/10/2026 (accord du
   porteur) : titres, sur-titres et libellés en ÉCRITURE NORMALE (plus de capitales : quand tout
   crie, rien ne ressort) ; la force passe par la taille et la graisse : Noto Sans 700 (jamais une
   autre police), --md-sys-typescale-*, --md-sys-color-* (clair et sombre), --md-sys-shape-*.
   Documenté sur /design-system (Patterns, « Studio · … »), statut À décider. Les pages du
   Studio (Plateau, Œuvres, Salle, Publier) ne font que la mise en page autour.
   ════════════════════════════════════════════════════════════════════ */

/* ── Titres : titre de page géant, titre de section fort, sur-titre discret (écriture normale
   depuis le 14/10/2026 ; « --caps » est un nom historique).
   .h-display remplace .h-page sur une page du Studio (pas en plus) ; .h-sec--caps et
   .h-eyebrow--quiet sont des modificateurs, à poser AVEC .h-sec / .h-eyebrow. ── */
.h-display { margin: 0; font: var(--md-sys-typescale-display-medium); font-weight: 700; line-height: 1.08; letter-spacing: -.02em;
  color: var(--md-sys-color-on-surface); overflow-wrap: anywhere; }
@media (max-width: 760px) { .h-display { font: var(--md-sys-typescale-display-small); font-weight: 700; line-height: 1.08; letter-spacing: -.02em; } }
.h-sec--caps { font: var(--md-sys-typescale-headline-medium); font-weight: 700; line-height: 1.15; letter-spacing: -.01em; }
.h-eyebrow--quiet { font: var(--md-sys-typescale-label-large); font-weight: 500; letter-spacing: 0; text-transform: none; color: var(--md-sys-color-on-surface-variant); }

/* ── Carte bordée du Studio : filet 1 outline-variant, fond surface-container-low, rayon 16,
   padding 20 (24 à 900 px et plus). En-tête .st-card-h : titre à gauche, lien ou compteur à
   droite, alignés en bas, 16 au-dessus du contenu. .st-card--flush : sans padding (liste ou
   table qui touche les bords ; la page règle alors le retrait de ses lignes). ── */
.st-card { min-width: 0; padding: 20px; box-sizing: border-box; color: var(--md-sys-color-on-surface);
  background: var(--md-sys-color-surface-container-low); border: 1px solid var(--md-sys-color-outline-variant); border-radius: var(--md-sys-shape-corner-large); }
@media (min-width: 900px) { .st-card { padding: 24px; } }
.st-card.st-card--flush { padding: 0; }

/* En-tête de carte ET en-tête de section hors carte : bloc de gauche (sur-titre + titre, 4 entre
   eux), action à droite (lien, compteur, bouton), alignés en bas, passent à la ligne si besoin. */
:is(.st-card-h, .st-sec-h) { display: flex; flex-wrap: wrap; align-items: flex-end; justify-content: space-between; gap: 8px 16px; min-width: 0; margin: 0 0 16px; }
:is(.st-card-h, .st-sec-h) > div:first-child { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
:is(.st-card-h, .st-sec-h) > :last-child:not(:first-child) { flex: none; }
.st-card--flush > .st-card-h { margin: 0; padding: 20px 20px 16px; }
@media (min-width: 900px) { .st-card--flush > .st-card-h { padding: 24px 24px 16px; } }

/* ════════════════════════════════════════════════════════════════════
   STUDIO — Statistiques et Communauté (07/10/2026, À valider)
   Ce que les deux nouveaux onglets du Studio demandent au DS et qui n'y était pas :
   la légende de graphique et la période précédente en tirets (shared/charts.js : options
   compare et color, chartLegendHTML), les barres horizontales sans drapeau (« par œuvre »),
   et la liste des membres avec sa barre d'outils. Jetons seulement ; les pages ne posent
   que la mise en page autour. Documenté sur /design-system (Patterns, « Régie · … »).
   ════════════════════════════════════════════════════════════════════ */

/* ── 1. Graphique : 2e série en bleu, période précédente en tirets, légende. ──
   .chart--blue : la série principale prend --sp-chart-blue (ligne, zone, barres, point).
   .chart--compare : la figure porte en plus un svg .chart-svg--cmp, posé AVANT la série
   (donc derrière), tirets 4 3 de 1,5 px en --sp-chart-compare ; l'échelle l'englobe.
   .chart-legend : une pastille .chart-key de 10 par série (primary, --blue, --compare en
   tirets) suivie de son libellé, label-medium on-surface-variant, 16 entre les séries. */
.chart--blue .chart-plot { color: var(--sp-chart-blue); }
.chart--blue .chart-dot { background: var(--sp-chart-blue); }
.chart-svg--cmp { color: var(--sp-chart-compare); }
.chart-key--blue { color: var(--sp-chart-blue); }
.chart-key--compare { color: var(--sp-chart-compare); background: transparent; border: 1.5px dashed currentColor; }
.chart-legend { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 16px; margin: 0 0 12px; padding: 0; list-style: none;
  font: var(--md-sys-typescale-label-medium); color: var(--md-sys-color-on-surface-variant); }
.chart-legend li { display: inline-flex; align-items: center; gap: 6px; min-width: 0; }
.chart-legend li > span { overflow-wrap: anywhere; }
.chart-head + .chart-legend { margin-top: -4px; }
.chart + .chart-legend { margin: 12px 0 0; }
/* Infobulle à deux valeurs : celle du jour en gras, la période précédente dessous en label-small atténué. */
.chart-tip > small, .chart-tip-cmp { display: block; font: var(--md-sys-typescale-label-small); color: color-mix(in srgb, currentColor 78%, transparent); font-variant-numeric: tabular-nums; }
.chart-tip > small[hidden] { display: none; }

/* ── 2. Barres horizontales sans drapeau (.rg-geo--plain) : le même composant que les pays,
   pour « par œuvre » ou « par nature ». La ligne peut être un lien (a.rg-geo-row, même survol
   gris que les menus), le nom peut porter une seconde ligne .rg-geo-sub (nature, épisodes),
   et la colonne de la part est facultative (3 colonnes quand elle manque). ── */
.rg-geo--plain .rg-geo-row { min-height: 44px; }
.rg-geo--plain .rg-geo-row:not(:has(.rg-geo-v)) { grid-template-columns: minmax(0, 1.3fr) minmax(64px, 2fr) 5em; }
.rg-geo--plain .rg-geo-n { display: flex; flex-direction: column; align-items: flex-start; gap: 0; white-space: normal; overflow: visible; }
.rg-geo--plain .rg-geo-n > b { font-weight: 600; max-width: 100%; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.rg-geo-sub { font: var(--md-sys-typescale-body-small); color: var(--md-sys-color-on-surface-variant); max-width: 100%; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.rg-geo a.rg-geo-row { color: inherit; text-decoration: none; margin: 0 -8px; padding: 0 8px; border-radius: var(--md-sys-shape-corner-small); }
.rg-geo a.rg-geo-row:hover { background: var(--sp-hover-bg); }
.rg-geo a.rg-geo-row:focus-visible { outline: 3px solid var(--md-sys-color-primary); outline-offset: -3px; }
.rg-geo--blue .rg-geo-bar > span { background: var(--sp-chart-blue); }   /* gardé pour compatibilité : le Studio prend .rg-geo--soft */
.rg-geo--soft .rg-geo-bar > span { background: color-mix(in srgb, var(--md-sys-color-primary) 45%, transparent); }
@container rg-geo (max-width: 420px) {
  .rg-geo--plain .rg-geo-row:not(:has(.rg-geo-v)) { grid-template-columns: minmax(0, 1fr) 5em; }
}

/* ── 3. Liste des membres (Communauté) : une ligne de 64 par membre, avatar 44, nom 600 et
   sous-ligne, palier en .bdg, « depuis », actions ; filet outline-variant entre les lignes,
   survol surface-container. La liste touche les bords d'une .st-card--flush (la carte
   règle le retrait) ou vit nue dans la page. Clavier : la ligne entière n'est pas un lien,
   ses actions le sont (44 au moins). ── */
.rg-members { container: rg-members / inline-size; display: flex; flex-direction: column; margin: 0; padding: 0; list-style: none; }
.rg-member { display: grid; grid-template-columns: 44px minmax(0, 1fr) auto minmax(0, auto) auto; align-items: center; gap: 16px;
  min-height: 64px; padding: 10px 0; box-sizing: border-box; color: var(--md-sys-color-on-surface); }
.rg-member + .rg-member { border-top: 1px solid var(--md-sys-color-outline-variant); }
.rg-member:hover { background: var(--md-sys-color-surface-container); }
.rg-member > .ava { flex: none; }
.rg-member-b { min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.rg-member-n { margin: 0; font: var(--md-sys-typescale-title-small); font-weight: 600; color: var(--md-sys-color-on-surface); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.rg-member-n a { color: inherit; text-decoration: none; }
.rg-member-n a:hover { text-decoration: underline; }
.rg-member-sub { margin: 0; font: var(--md-sys-typescale-body-small); color: var(--md-sys-color-on-surface-variant); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.rg-member > :is(.bdg, .st-state) { justify-self: start; }
.rg-member-since { font: var(--md-sys-typescale-body-small); color: var(--md-sys-color-on-surface-variant); font-variant-numeric: tabular-nums; white-space: nowrap; }
.rg-member-acts { display: flex; align-items: center; justify-content: flex-end; gap: 8px; }
/* Membre banni : le texte passe en gris ET le badge le dit (jamais la couleur seule). */
.rg-member.is-banned :is(.rg-member-n, .rg-member-since) { color: var(--md-sys-color-on-surface-variant); }
.rg-member.is-banned > .ava { opacity: .6; }
/* Dans une carte sans marges : les lignes reprennent le retrait de la carte (20, 24 à 900 px). */
.st-card--flush > .rg-members .rg-member, .st-card--flush > .rg-members-tools { padding-left: 20px; padding-right: 20px; }
@media (min-width: 900px) { .st-card--flush > .rg-members .rg-member, .st-card--flush > .rg-members-tools { padding-left: 24px; padding-right: 24px; } }
.st-card--flush > .rg-members .rg-member:last-child { border-radius: 0 0 var(--md-sys-shape-corner-large) var(--md-sys-shape-corner-large); }
/* Liste étroite (moins de 720 px) : le palier et « depuis » passent sous le nom, les actions à droite. */
@container rg-members (max-width: 720px) {
  .rg-member { grid-template-columns: 44px auto minmax(0, 1fr) auto; gap: 8px 16px; }
  .rg-member-b { grid-column: 2 / span 2; }
  .rg-member > :is(.bdg, .st-state) { grid-column: 2; grid-row: 2; }
  .rg-member-since { grid-column: 3; grid-row: 2; }
  .rg-member-acts { grid-column: 4; grid-row: 1 / span 2; }
}

/* ── 4. Barre d'outils de la liste : recherche .ex-search (s'étire, 240 au moins) et filtres
   .ex-seg, écart 8 ; passe à la ligne quand la place manque ; 16 au-dessus de la liste. ── */
.rg-members-tools { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin: 0 0 16px; min-width: 0; }
.rg-members-tools > .ex-search { flex: 1 1 240px; max-width: 420px; }
.rg-members-tools > .ex-seg { flex: none; }
.st-card--flush > .rg-members-tools { margin: 0; padding-bottom: 16px; }

/* ════════════════════════════════════════════════════════════════════
   STUDIO — couleurs SydePlay (07/10/2026, À valider)
   Retour du porteur : « trop de couleurs différentes et moches ». Le Studio ne parle plus qu'en
   rose de marque (--md-sys-color-primary) et en neutres du DS ; une autre couleur seulement si
   elle est justifiée (retard de paiement : --md-sys-color-error avec son icône). Sinon, c'est une
   ICÔNE Lucide qui porte le sens. Dégradés de rose pour les cases clés (carte vedette, barres,
   cases « en ligne »), tous calculés en color-mix sur primary : le même rose en clair et en sombre.
   Interdits dans le Studio : .bdg--orange, --yellow, --blue, --violet, --green et les pastels de
   nature (.bdg--film, --serie, --anime). Documenté sur /design-system (Patterns, « Studio · … »),
   statut À décider.
   ════════════════════════════════════════════════════════════════════ */

/* ── 1. Jetons ── */
.ds-app, .ds-solo, :root {
  /* Plein : 135°, primary → primary mêlé à 30 % de noir. Cases « en ligne », barres de données,
     pastille d'icône forte (icône blanche : 3,5:1 au plus clair, jamais de petit texte dessus). */
  --sp-grad-brand: linear-gradient(135deg, var(--md-sys-color-primary), color-mix(in srgb, var(--md-sys-color-primary) 70%, black));
  /* Voile : 135°, primary à 16 % → transparent à 65 %. Carte vedette, bandeau du haut du Plateau,
     tuile mise en avant ; posé en background-image SUR le fond de la carte. */
  --sp-grad-brand-soft: linear-gradient(135deg, color-mix(in srgb, var(--md-sys-color-primary) 16%, transparent), transparent 65%);
  /* Barres horizontales : 90°, primary à 55 % → primary (la barre se fonce vers sa valeur). */
  --sp-grad-brand-bar: linear-gradient(90deg, color-mix(in srgb, var(--md-sys-color-primary) 55%, transparent), var(--md-sys-color-primary));
  /* Bannière de chaîne sans image (et repli d'une carte sans visuel) : 120°, presque noir teinté
     rose → primary. Texte et avatar posés dessus restent blancs. */
  --sp-grad-banner: linear-gradient(120deg, color-mix(in srgb, var(--md-sys-color-primary) 14%, var(--md-sys-color-scrim)),
    color-mix(in srgb, var(--md-sys-color-primary) 28%, var(--md-sys-color-scrim)) 45%, var(--md-sys-color-primary));
  /* Vignette d'une publication sans couverture (coverGradient de reaction-ui.js, choisie par son
     identifiant) : six teintes du thème mêlées au scrim, assez sombres pour un texte blanc
     (ardoise, rose, vert, mauve, indigo, ambre). Plus profondes en sombre (bloc ci-dessous). */
  --sp-cover-1: linear-gradient(135deg, color-mix(in srgb, var(--md-sys-color-on-surface-variant) 60%, var(--md-sys-color-scrim)), color-mix(in srgb, var(--md-sys-color-on-surface-variant) 30%, var(--md-sys-color-scrim)));
  --sp-cover-2: linear-gradient(135deg, color-mix(in srgb, var(--md-sys-color-primary) 45%, var(--md-sys-color-scrim)), color-mix(in srgb, var(--md-sys-color-primary) 22%, var(--md-sys-color-scrim)));
  --sp-cover-3: linear-gradient(135deg, color-mix(in srgb, var(--md-sys-color-success) 45%, var(--md-sys-color-scrim)), color-mix(in srgb, var(--md-sys-color-success) 22%, var(--md-sys-color-scrim)));
  --sp-cover-4: linear-gradient(135deg, color-mix(in srgb, var(--md-sys-color-secondary) 70%, var(--md-sys-color-scrim)), color-mix(in srgb, var(--md-sys-color-secondary) 35%, var(--md-sys-color-scrim)));
  --sp-cover-5: linear-gradient(135deg, color-mix(in srgb, var(--sp-kind-serie) 40%, var(--md-sys-color-scrim)), color-mix(in srgb, var(--sp-kind-serie) 22%, var(--md-sys-color-scrim)));
  --sp-cover-6: linear-gradient(135deg, color-mix(in srgb, var(--md-sys-color-warning) 40%, var(--md-sys-color-scrim)), color-mix(in srgb, var(--md-sys-color-warning) 20%, var(--md-sys-color-scrim)));
  /* Rose LISIBLE (petit texte, icône sur fond rose) : primary seul fait 3,5:1 sur blanc et 3:1 sur
     sa teinte, sous l'AA. Clair : primary mêlé à 30 % de noir (le bout foncé du dégradé), 6,3:1
     sur blanc, 5,2:1 sur la teinte à 12 %. Sombre : primary éclairci (20 % de blanc), plus de 5:1. */
  --sp-brand-ink: color-mix(in srgb, var(--md-sys-color-primary) 70%, black);
  /* Teinte rose de fond : état « en ligne », pastille d'icône d'une tuile chiffre. */
  --sp-brand-tint: color-mix(in srgb, var(--md-sys-color-primary) 12%, transparent);
  /* Natures d'œuvre (07/10/2026, demande du porteur : « des couleurs plus belles pour les pastilles
     série, film, animé ») : le seul jeu de couleurs catégorielles du Studio, thème « projection » —
     série = indigo (la lueur de l'écran), film = ambre (la lumière du projecteur), animé = turquoise
     (le néon). Teintes validées (séparation daltonisme ΔE ≥ 14 entre elles et avec le rose de marque) ;
     -ink = nuance du texte, AA sur sa teinte en clair comme en sombre. */
  --sp-kind-serie: #6F7CFF;  --sp-kind-serie-ink: #3D4FD8;
  --sp-kind-film:  #E9A23B;  --sp-kind-film-ink:  #8F5300;
  --sp-kind-anime: #1FB5AE;  --sp-kind-anime-ink: #08716C;
}
[data-theme="dark"] .ds-app, [data-theme="dark"] .ds-solo, [data-theme="dark"]:root,
.ds-sec--dark, .tbar-dd-panel.is-dark, .tbar-search-panel.is-dark {
  --sp-brand-ink: color-mix(in srgb, var(--md-sys-color-primary) 80%, white);
  /* Sombre : la bannière finit sur un rose plus profond, les vignettes se fondent dans le fond. */
  --sp-grad-banner: linear-gradient(120deg, color-mix(in srgb, var(--md-sys-color-primary) 10%, var(--md-sys-color-scrim)),
    color-mix(in srgb, var(--md-sys-color-primary) 22%, var(--md-sys-color-scrim)) 45%, color-mix(in srgb, var(--md-sys-color-primary) 75%, var(--md-sys-color-scrim)));
  --sp-cover-1: linear-gradient(135deg, color-mix(in srgb, var(--md-sys-color-on-surface-variant) 40%, var(--md-sys-color-scrim)), color-mix(in srgb, var(--md-sys-color-on-surface-variant) 20%, var(--md-sys-color-scrim)));
  --sp-cover-2: linear-gradient(135deg, color-mix(in srgb, var(--md-sys-color-primary) 32%, var(--md-sys-color-scrim)), color-mix(in srgb, var(--md-sys-color-primary) 16%, var(--md-sys-color-scrim)));
  --sp-cover-3: linear-gradient(135deg, color-mix(in srgb, var(--md-sys-color-success) 32%, var(--md-sys-color-scrim)), color-mix(in srgb, var(--md-sys-color-success) 16%, var(--md-sys-color-scrim)));
  --sp-cover-4: linear-gradient(135deg, color-mix(in srgb, var(--md-sys-color-secondary) 35%, var(--md-sys-color-scrim)), color-mix(in srgb, var(--md-sys-color-secondary) 18%, var(--md-sys-color-scrim)));
  --sp-cover-5: linear-gradient(135deg, color-mix(in srgb, var(--sp-kind-serie) 30%, var(--md-sys-color-scrim)), color-mix(in srgb, var(--sp-kind-serie) 15%, var(--md-sys-color-scrim)));
  --sp-cover-6: linear-gradient(135deg, color-mix(in srgb, var(--md-sys-color-warning) 30%, var(--md-sys-color-scrim)), color-mix(in srgb, var(--md-sys-color-warning) 15%, var(--md-sys-color-scrim)));
  --sp-kind-serie-ink: #AEB8FF;  --sp-kind-film-ink: #F7C873;  --sp-kind-anime-ink: #72E4DD;
}

/* ── 2. Pastille d'état (.st-state) : NEUTRE, une icône Lucide de 14 + le mot. Fond
   surface-container-high, texte on-surface (14,6:1), icône on-surface-variant, rayon plein, 24 de
   haut. .st-state--live (en ligne) est la SEULE colorée : teinte rose 12 %, texte et icône
   --sp-brand-ink. Icônes : en ligne circle-check · programmée calendar-clock · brouillon, au calage,
   seed à poser pencil · prête check · à tourner clapperboard · privée, masqué eye-off · pas encore
   circle-dashed · signalé flag · nouvelle sparkles · écartée x. ── */
.st-state { display: inline-flex; flex: none; align-items: center; gap: 6px; max-width: 100%; height: 24px; padding: 0 10px; box-sizing: border-box;
  border-radius: var(--md-sys-shape-corner-full); background: var(--md-sys-color-surface-container-high); color: var(--md-sys-color-on-surface);
  font: var(--md-sys-typescale-label-medium); font-weight: 600; line-height: 1; white-space: nowrap; }
.st-state:has(> svg) { padding-left: 8px; }
.st-state > span { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.st-state > svg { flex: none; width: 14px; height: 14px; color: var(--md-sys-color-on-surface-variant); }
.st-state--live { background: var(--sp-brand-tint); color: var(--sp-brand-ink); }
.st-state--live > svg { color: currentColor; }

/* ── 3. Nature d'œuvre (.st-kind) : NEUTRE, contour 1 outline, texte on-surface-variant, icône 14 :
   série tv, film film, animé sparkles. Remplace les pastels .bdg--serie / --film / --anime dans le
   Studio. Même gabarit que .st-state (24, rayon plein) : le contour la distingue d'un état. ── */
.st-kind { display: inline-flex; flex: none; align-items: center; gap: 6px; height: 24px; padding: 0 10px; box-sizing: border-box;
  border: 1px solid var(--md-sys-color-outline); border-radius: var(--md-sys-shape-corner-full); background: transparent;
  color: var(--md-sys-color-on-surface-variant); font: var(--md-sys-typescale-label-medium); font-weight: 600; line-height: 1; white-space: nowrap; }
.st-kind:has(> svg) { padding-left: 8px; }
.st-kind > svg { flex: none; width: 14px; height: 14px; }
/* Couleur de la nature (teinte 14 %, contour 38 %, texte -ink) : la couleur double l'icône et le mot,
   elle ne porte jamais le sens seule. */
.st-kind--serie, .st-kind--film, .st-kind--anime {
  background: color-mix(in srgb, var(--k) 14%, transparent);
  border-color: color-mix(in srgb, var(--k) 38%, transparent); color: var(--k-ink); }
.st-kind--serie { --k: var(--sp-kind-serie); --k-ink: var(--sp-kind-serie-ink); }
.st-kind--film  { --k: var(--sp-kind-film);  --k-ink: var(--sp-kind-film-ink); }
.st-kind--anime { --k: var(--sp-kind-anime); --k-ink: var(--sp-kind-anime-ink); }
/* ── Part par nature (.st-share, Statistiques) : une barre fine part-à-tout (12 de haut, un segment
   par nature, bouts arrondis 4, 2 px de vide entre deux) SANS texte dedans, puis la légende :
   une colonne par nature, pastille 40 teintée avec l'icône, le nom, la part en grand et le nombre.
   Les natures se suivent de la plus regardée à la moins regardée, dans la barre comme dessous.
   .k-serie / .k-film / .k-anime posent la couleur (--k) et son texte lisible (--k-ink). ── */
.st-share { display: flex; flex-direction: column; gap: 20px; }
.st-share .k-serie { --k: var(--sp-kind-serie); --k-ink: var(--sp-kind-serie-ink); }
.st-share .k-film  { --k: var(--sp-kind-film);  --k-ink: var(--sp-kind-film-ink); }
.st-share .k-anime { --k: var(--sp-kind-anime); --k-ink: var(--sp-kind-anime-ink); }
.st-share-bar { display: flex; gap: 2px; height: 12px; }
.st-share-bar > i { flex: 0 1 var(--w, 0%); min-width: 4px; border-radius: var(--md-sys-shape-corner-extra-small); background: var(--k); }
.st-share-legend { display: grid; grid-template-columns: repeat(auto-fit, minmax(170px, 1fr)); gap: 16px 24px; margin: 0; padding: 0; list-style: none; }
.st-share-item { display: grid; grid-template-columns: 40px minmax(0, 1fr); grid-template-areas: "ic l" "ic v" "ic n"; column-gap: 12px; align-items: center; min-width: 0; }
.st-share-ic { grid-area: ic; align-self: start; display: inline-flex; align-items: center; justify-content: center; width: 40px; height: 40px;
  border-radius: var(--md-sys-shape-corner-full); background: color-mix(in srgb, var(--k) 16%, transparent); color: var(--k-ink); }
.st-share-ic > svg { width: 20px; height: 20px; }
.st-share-l { grid-area: l; min-width: 0; font: var(--md-sys-typescale-body-medium); color: var(--md-sys-color-on-surface-variant); }
.st-share-v { grid-area: v; font: var(--md-sys-typescale-headline-small); font-weight: 700; line-height: 1.1; color: var(--md-sys-color-on-surface); font-variant-numeric: tabular-nums; }
.st-share-n { grid-area: n; min-width: 0; margin-top: 2px; font: var(--md-sys-typescale-body-small); color: var(--md-sys-color-on-surface-variant); }

/* ── 4. Tuile chiffre (.st-kpi) dans sa rangée (.st-kpis). Pastille 40 (teinte rose, icône 20
   --sp-brand-ink) et libellé sur la 1re ligne, grand chiffre display-small 700, puis la variation
   (icône trending-up / trending-down + texte) en on-surface-variant : JAMAIS de vert ni de rouge,
   l'icône porte le sens. .st-kpi--lead : la tuile mise en avant, voile --sp-grad-brand-soft, filet
   rosé, pastille pleine --sp-grad-brand à icône blanche. ── */
.st-kpis { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 200px), 1fr)); gap: 12px; min-width: 0; }
.st-kpi { display: grid; grid-template-columns: 40px minmax(0, 1fr); grid-template-areas: "ic l" "v v" "d d"; align-items: center; column-gap: 12px;
  min-width: 0; margin: 0; padding: 16px; box-sizing: border-box; color: var(--md-sys-color-on-surface);
  background-color: var(--md-sys-color-surface-container-low); border: 1px solid var(--md-sys-color-outline-variant); border-radius: var(--md-sys-shape-corner-large); }
.st-kpi-ic { grid-area: ic; display: inline-flex; align-items: center; justify-content: center; width: 40px; height: 40px;
  border-radius: var(--md-sys-shape-corner-full); background: var(--sp-brand-tint); color: var(--sp-brand-ink); }
.st-kpi-ic > svg { width: 20px; height: 20px; }
.st-kpi-l { grid-area: l; min-width: 0; margin: 0; font: var(--md-sys-typescale-label-large); font-weight: 500; letter-spacing: 0;
  color: var(--md-sys-color-on-surface-variant); overflow-wrap: anywhere; }
.st-kpi-v { grid-area: v; min-width: 0; margin: 16px 0 0; font: var(--md-sys-typescale-display-small); font-weight: 700; line-height: 1.05; letter-spacing: -.01em;
  font-variant-numeric: tabular-nums; color: var(--md-sys-color-on-surface); overflow-wrap: anywhere; }
.st-kpi-d { grid-area: d; display: flex; align-items: center; gap: 4px; min-width: 0; margin: 6px 0 0;
  font: var(--md-sys-typescale-body-small); font-weight: 600; font-variant-numeric: tabular-nums; color: var(--md-sys-color-on-surface-variant); }
.st-kpi-d > svg { flex: none; width: 14px; height: 14px; }
.st-kpi--lead { background-image: var(--sp-grad-brand-soft); }
.st-kpi--lead .st-kpi-ic { background: var(--sp-grad-brand); color: var(--md-sys-color-on-primary); }

/* ── 5. Bandeau du haut du Plateau (.st-hero, TOUJOURS avec .st-card) : voile --sp-grad-brand-soft
   sur le fond de la carte, filet rosé, en-tête .st-hero-h (sur-titre discret + titre .h-display +
   phrase .st-hero-sub à gauche, actions .st-hero-acts à droite), puis la rangée .st-kpis. Dans le
   bandeau, les tuiles passent sur surface (blanches en clair, plus claires que la carte en sombre). ── */
.st-hero { display: flex; flex-direction: column; gap: 24px; background-image: var(--sp-grad-brand-soft); }
@media (min-width: 900px) { .st-card.st-hero { padding: 32px; gap: 28px; } }
:is(.st-hero, .st-kpi--lead) { border-color: color-mix(in srgb, var(--md-sys-color-primary) 22%, var(--md-sys-color-outline-variant)); }
.st-hero-h { display: flex; flex-wrap: wrap; align-items: flex-end; justify-content: space-between; gap: 16px 24px; min-width: 0; }
.st-hero-h > div:first-child { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.st-hero-sub { max-width: 60ch; margin: 2px 0 0; font: var(--md-sys-typescale-body-large); color: var(--md-sys-color-on-surface-strong); }
.st-hero-acts { display: flex; flex-wrap: wrap; gap: 8px; }
.st-hero .st-kpi { background-color: var(--md-sys-color-surface); }
/* Sur le voile rose, on-surface-variant tombe à 3,7:1 en clair : le texte secondaire passe en
   on-surface-strong (8:1 et plus, clair et sombre). */
:is(.st-hero-h .h-eyebrow--quiet, .st-kpi--lead .st-kpi-l, .st-kpi--lead .st-kpi-d) { color: var(--md-sys-color-on-surface-strong); }
/* ── 5b. Carte vedette (.st-card--lead, TOUJOURS avec .st-card, une seule par page) : la carte qui
   porte le travail principal de la page (Statistiques : les spectateurs). Même voile et même filet
   que le bandeau du Plateau, sans toucher à la mise en page de la carte. Sur le voile, tout le texte
   secondaire (notes, écarts, légende et axes des graphiques) passe en on-surface-strong : le jeton
   on-surface-variant y est redéfini (il tomberait à 3,7:1 en clair). Ajout du 07/10/2026, à valider. */
.st-card--lead { background-image: var(--sp-grad-brand-soft); border-color: color-mix(in srgb, var(--md-sys-color-primary) 22%, var(--md-sys-color-outline-variant));
  --md-sys-color-on-surface-variant: var(--md-sys-color-on-surface-strong); }
/* ── 5c. Menu à longue liste (.st-menu--scroll, posé par openMenu(…, { className })) : un menu de
   choix dont la liste grandit avec les données (Salle : « Publication affichée ») s'arrête à
   440 px (ou à la hauteur de l'écran moins 96) et défile dedans, au lieu de sortir de l'écran.
   Ajout du 07/10/2026, à valider. */
.rcard-menu.st-menu--scroll { max-height: min(440px, calc(100vh - 96px)); overflow-y: auto; overscroll-behavior: contain; }

/* ── 6. Badge de palier : neutre (.bdg--gray) avec l'icône crown ; le palier le plus haut peut
   prendre .bdg--brand : dégradé de rose foncé (primary mêlé à 20 puis 38 % de noir), blanc à 5,2:1
   au plus clair. Seul ajout à la palette des badges, réservé au Studio. ── */
.bdg--brand { --s: color-mix(in srgb, var(--md-sys-color-primary) 80%, black); --t: var(--md-sys-color-primary);
  background: linear-gradient(135deg, var(--s), color-mix(in srgb, var(--md-sys-color-primary) 62%, black)); }

/* ── 7. Graphiques (shared/charts.js) : la série principale reste primary, ses barres verticales
   prennent le dégradé --sp-grad-brand ; color: "soft" (figure.chart--soft) = 2e série en primary
   à 45 % (ligne, zone, barres, point, pastille .chart-key--soft) à la place du bleu. La période
   précédente reste en tirets gris. .chart--blue est gardé pour compatibilité, plus utilisé. ── */
.chart--bars:not(.chart--blue, .chart--soft) .chart-bars i { background: var(--sp-grad-brand); }
.chart--soft .chart-plot, .chart-key--soft { color: color-mix(in srgb, var(--md-sys-color-primary) 45%, transparent); }
.chart--soft .chart-dot { background: color-mix(in srgb, var(--md-sys-color-primary) 45%, var(--md-sys-color-surface)); }

/* ════════════════════════════════════════════════════════════════════
   DÉCOUVRIR v2 (refonte du 07/10/2026) : billboard, rangées, affiches, pionniers, top 10,
   « comment ça marche ». Page /discover (frontend/pages/discover/). Documenté sur
   /design-system (Patterns, « Découvrir · … »), statut À décider.
   ════════════════════════════════════════════════════════════════════ */

/* ── Billboard (.bb) : LA chose forte de Découvrir. Image de fond de l'œuvre, voile à gauche et en
   bas, titre en capitales SydePlay, ligne « avec <créateur> », deux actions ; et la BULLE du créateur
   (photo ronde cerclée de rose, en bas à droite) qui rejoue l'incrustation du produit. Hauteur qui
   suit l'écran (360 à 560), arrondi fluide des grands blocs. .bb--welcome : étape « vide », fond au
   dégradé de marque, sans bulle. ── */
.bb { position: relative; isolation: isolate; display: flex; align-items: flex-end; min-height: clamp(360px, 52vh, 560px);
  overflow: hidden; border-radius: var(--sp-shape-corner-large-fluid, 28px); background: #141416; color: #fff; }
/* L'image n'est plus étirée sur tout le bloc (retour du porteur du 13/10/2026 : sur un écran large, le
   remplissage « cover » d'un bloc de 3 à 4,6:1 ne gardait qu'un tiers de la hauteur d'une image 16:9,
   d'où des visages en gros plan et des miniatures floues). Elle garde son format 16:9, calée à droite,
   à au moins --bb-media-min de la largeur (recadrage limité), et se fond vers la gauche. .bb-amb : la
   même image très floue et assombrie remplit tout le bloc, qui prend ainsi les couleurs de l'œuvre au
   lieu d'un noir uni. Sur téléphone (plus bas), l'image entière en haut, fondue vers le texte. */
.bb-amb { position: absolute; inset: -12%; z-index: -3; background-size: cover; background-position: center;
  filter: blur(56px) saturate(1.3) brightness(.5); pointer-events: none; }
.bb-bg { position: absolute; inset: 0 0 0 auto; z-index: -2; height: 100%; aspect-ratio: 16 / 9; min-width: var(--bb-media-min, 58%); max-width: 100%;
  background-size: cover; background-position: center 30%; animation: bb-in .5s ease both;
  -webkit-mask-image: linear-gradient(90deg, transparent 0%, rgba(0, 0, 0, .6) 16%, #000 40%);
          mask-image: linear-gradient(90deg, transparent 0%, rgba(0, 0, 0, .6) 16%, #000 40%); }
.bb-shade { position: absolute; inset: 0; z-index: -1;
  background: linear-gradient(90deg, rgba(0, 0, 0, .86) 0%, rgba(0, 0, 0, .6) 34%, rgba(0, 0, 0, 0) 68%),
              linear-gradient(0deg, rgba(0, 0, 0, .72) 0%, rgba(0, 0, 0, 0) 46%); }
.bb-in { display: flex; flex-direction: column; align-items: flex-start; gap: 14px; max-width: min(620px, 100%); box-sizing: border-box;
  padding: clamp(24px, 4vw, 48px); }
.bb-meta { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 12px; font: var(--md-sys-typescale-label-large); color: rgba(255, 255, 255, .82); }
.bb-meta-it { display: inline-flex; align-items: center; gap: 6px; }
.bb-meta svg { width: 16px; height: 16px; }
.bb-h { margin: 0; font: var(--md-sys-typescale-display-medium); font-weight: 700; line-height: 1.02; letter-spacing: -.01em;
  text-transform: uppercase; color: #fff; overflow-wrap: anywhere; text-wrap: balance; }
.bb-with { margin: 0; font: var(--md-sys-typescale-body-large); color: rgba(255, 255, 255, .88); }
.bb-with strong { color: #fff; font-weight: 700; }
.bb-acts { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 6px; }
/* Photo du créateur : jamais un rond (règle du porteur, 14/10/2026). Carré aux bords arrondis (forme
   large du DS) ; jamais posée sur une miniature vidéo (les pages ne la rendent alors pas). */
.bb-bubble { position: absolute; right: clamp(20px, 3vw, 40px); bottom: clamp(20px, 3vw, 40px); display: grid; place-items: center;
  width: clamp(84px, 10vw, 140px); aspect-ratio: 1; border-radius: var(--md-sys-shape-corner-large); overflow: hidden; box-sizing: border-box;
  border: 3px solid var(--md-sys-color-primary); box-shadow: 0 0 0 6px rgba(0, 0, 0, .35);
  background: var(--sp-grad-brand); color: #fff; font: var(--md-sys-typescale-headline-medium); font-weight: 700; }
.bb-bubble img { width: 100%; height: 100%; object-fit: cover; }
.bb-dots { position: absolute; top: clamp(20px, 3vw, 32px); right: clamp(20px, 3vw, 40px); display: flex; gap: 7px; }
.bb--welcome { background: var(--sp-grad-brand); min-height: clamp(320px, 44vh, 460px); }
/* .bb--compact : billboard plus bas, sous une autre grande image (accueil d'une chaîne, sous sa bannière). */
.bb--compact { min-height: clamp(260px, 36vh, 380px); --bb-media-min: 52%; }
.bb--compact .bb-h { font: var(--md-sys-typescale-headline-large); font-weight: 700; line-height: 1.08; }
.bb--compact .bb-bubble { width: clamp(72px, 8vw, 112px); }
/* Voile sombre à gauche : le texte blanc passe au-dessus de 4,5:1 sur le rose (7:1 au bord). */
.bb--welcome .bb-shade { background: linear-gradient(90deg, rgba(0, 0, 0, .32) 0%, rgba(0, 0, 0, .12) 55%, rgba(0, 0, 0, 0) 80%),
  radial-gradient(120% 90% at 100% 0%, rgba(255, 255, 255, .14), transparent 60%); }
/* Illustration de l'étape vide (à droite) : un écran et la bulle du créateur dans son coin, l'idée
   de SydePlay en une image. Décorative (aria-hidden), masquée sous 900 px. */
.bb-illu { position: absolute; right: clamp(40px, 6vw, 96px); top: 50%; width: min(36%, 420px); aspect-ratio: 16 / 9; transform: translateY(-50%);
  border-radius: var(--md-sys-shape-corner-large); background: rgba(0, 0, 0, .3); box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .2); }
.bb-illu::before { content: ""; position: absolute; left: 16px; right: 16px; bottom: 16px; height: 4px; border-radius: var(--md-sys-shape-corner-full);
  background: linear-gradient(90deg, #fff 38%, rgba(255, 255, 255, .28) 38%); }
.bb-illu-play { position: absolute; inset: 0; display: grid; place-items: center; width: 56px; height: 56px; margin: auto; border-radius: 50%;
  background: rgba(255, 255, 255, .18); color: #fff; }
.bb-illu-play svg { width: 26px; height: 26px; }
.bb-illu-bubble { position: absolute; right: -20px; bottom: -20px; display: grid; place-items: center; width: 32%; aspect-ratio: 1; border-radius: var(--md-sys-shape-corner-large);
  box-sizing: border-box; border: 3px solid #fff; background: #1B1C1E; color: #fff; box-shadow: 0 0 0 6px rgba(0, 0, 0, .18); }
.bb-illu-bubble svg { width: 42%; height: 42%; }
@media (max-width: 900px) { .bb-illu { display: none; } }
@keyframes bb-in { from { opacity: 0; } to { opacity: 1; } }
@media (prefers-reduced-motion: reduce) { .bb-bg { animation: none; } }
@media (max-width: 760px) {
  .bb-h { font: var(--md-sys-typescale-display-small); font-weight: 700; line-height: 1.02; }
  .bb-bubble { top: 20px; bottom: auto; width: 72px; }
  /* La bulle (72 + marge) ne se pose plus sur « Animé · 307 réactions » sur un écran bas (audit break-ui). */
  .bb-meta { padding-right: 96px; }
  .bb-dots { top: auto; bottom: 16px; }
  /* Téléphone : l'image entière (16:9) en haut, fondue vers le bas où se pose le texte. */
  .bb-bg { inset: 0 0 auto 0; width: 100%; height: auto; min-width: 0;
    -webkit-mask-image: linear-gradient(180deg, #000 55%, transparent 100%);
            mask-image: linear-gradient(180deg, #000 55%, transparent 100%); }
}

/* ── Rangée (.shelf) : titre en casse normale (title-large 700), phrase facultative, « Tout voir » et
   flèches .ibtn à droite (masquées sur écran tactile) ; la piste défile à l'horizontale, aimantée,
   au clavier (région focusable), et déborde sur la marge droite du contenu pour montrer qu'il y a
   une suite. Largeur d'un élément : --shelf-w (réaction 300, affiche 168, créateur 240). ── */
.shelf { display: flex; flex-direction: column; gap: 14px; min-width: 0; }
.shelf-h { display: flex; align-items: flex-end; gap: 12px; min-width: 0; }
.shelf-h-txt { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.shelf-t { margin: 0; font: var(--md-sys-typescale-title-large); font-weight: 700; color: var(--md-sys-color-on-surface); }
.shelf-sub { margin: 0; font: var(--md-sys-typescale-body-medium); color: var(--md-sys-color-on-surface-variant); }
.shelf-tools { display: flex; align-items: center; gap: 8px; margin-left: auto; flex: none; }
.shelf-track { display: grid; grid-auto-flow: column; grid-auto-columns: var(--shelf-w, 300px); gap: 16px; align-items: start;
  overflow-x: auto; overscroll-behavior-x: contain; scroll-snap-type: x mandatory; scroll-behavior: smooth;
  margin-right: calc(-1 * var(--home-pad-x, 32px)); padding: 4px var(--home-pad-x, 32px) 8px 0;
  scrollbar-width: none; }
.shelf-track::-webkit-scrollbar { display: none; }
.shelf-track > * { scroll-snap-align: start; min-width: 0; }
.shelf-track:focus-visible { outline: 3px solid var(--md-sys-color-primary); outline-offset: 2px; border-radius: var(--md-sys-shape-corner-medium); }
.shelf--works { --shelf-w: 168px; }
.shelf--creators { --shelf-w: 240px; }
.shelf--lead.shelf--creators { --shelf-w: 300px; }
@media (hover: none) { .shelf-nav { display: none; } }
@media (prefers-reduced-motion: reduce) { .shelf-track { scroll-behavior: auto; } }

/* ── Affiche d'œuvre (.wtile) : affiche 2:3 (arrondi 12), titre sur deux lignes au plus, une ligne
   d'info. Lien vers la fiche de l'œuvre. ── */
.wtile { display: flex; flex-direction: column; gap: 8px; min-width: 0; color: inherit; text-decoration: none; }
.wtile-img { aspect-ratio: 2 / 3; border-radius: var(--md-sys-shape-corner-medium); background: var(--md-sys-color-surface-container-high) center / cover no-repeat;
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--md-sys-color-on-surface) 8%, transparent); transition: box-shadow .15s ease; }
/* Survol seulement sur un écran à survol : au toucher, :hover reste collé après l'appui, et sur une
   affiche à cocher (.wtile--pick) ce contour est celui de l'état choisi (une affiche décochée aurait
   l'air encore choisie). */
@media (hover: hover) {
  .wtile:hover .wtile-img { box-shadow: inset 0 0 0 2px var(--md-sys-color-primary); }
}
.wtile:focus-visible { outline: none; }
.wtile:focus-visible .wtile-img { outline: 3px solid var(--md-sys-color-primary); outline-offset: 2px; }
.wtile-t { font: var(--md-sys-typescale-title-small); font-weight: 600; color: var(--md-sys-color-on-surface);
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.wtile-sub { margin-top: -4px; font: var(--md-sys-typescale-body-small); color: var(--md-sys-color-on-surface-variant); }

/* ── Affiche à cocher (.wtile.wtile--pick, 21/10/2026, À valider) : la même affiche, en bouton à bascule
   (aria-pressed), pour choisir plusieurs œuvres (accueil guidé « Qu'est-ce que tu aimes regarder ? »,
   Mes œuvres). Choisie : contour rose de 2 px ET pastille de coche en coin (.wtile-check, rond rose
   plein de 28, coche blanche, liseré blanc) : le choix ne se lit jamais par la seule couleur (audit du
   13/10/2026). Au survol ou au focus d'une affiche libre, la pastille en creux (rond vide). Plafond
   atteint : aria-disabled="true" (reste atteignable au clavier, le script ignore le clic). Sans affiche :
   .wtile-img--vide, l'icône de la nature au centre. ── */
.wtile--pick { appearance: none; box-sizing: border-box; width: 100%; margin: 0; padding: 0; border: 0; background: none;
  font: inherit; text-align: left; cursor: pointer; }
.wtile--pick[hidden] { display: none; }
.wtile--pick[aria-pressed="true"] .wtile-img { box-shadow: inset 0 0 0 2px var(--md-sys-color-primary); }
.wtile-check { position: absolute; top: 8px; right: 8px; z-index: 1; display: grid; place-items: center; width: 28px; height: 28px;
  box-sizing: border-box; border-radius: var(--md-sys-shape-corner-full); pointer-events: none;
  background: var(--md-sys-color-primary); color: var(--md-sys-color-on-primary);
  box-shadow: 0 0 0 2px var(--md-sys-color-on-media), var(--md-sys-elevation-level2);
  opacity: 0; transform: scale(.6); transition: opacity .15s ease, transform .15s ease;
  --wtile-ghost: color-mix(in srgb, var(--md-sys-color-scrim) 40%, transparent); --wtile-ghost-ring: var(--md-sys-color-on-media); }
.wtile-img--vide .wtile-check { --wtile-ghost: var(--md-sys-color-surface); --wtile-ghost-ring: var(--md-sys-color-on-surface-variant); }
.wtile-check svg { width: 16px; height: 16px; stroke-width: 3; transition: opacity .15s ease; }
.wtile--pick[aria-pressed="true"] .wtile-check { opacity: 1; transform: none; }
/* Pastille en creux : rond vide (voile sur une affiche, surface sur une vignette vide), seulement là où
   le survol existe, et au clavier. */
.wtile--pick:not([aria-pressed="true"]):not([aria-disabled="true"]):focus-visible .wtile-check { opacity: 1; transform: none;
  background: var(--wtile-ghost); box-shadow: 0 0 0 2px var(--wtile-ghost-ring); }
.wtile--pick:not([aria-pressed="true"]) .wtile-check svg { opacity: 0; }
@media (hover: hover) {
  .wtile--pick:not([aria-pressed="true"]):not([aria-disabled="true"]):hover .wtile-check { opacity: 1; transform: none;
    background: var(--wtile-ghost); box-shadow: 0 0 0 2px var(--wtile-ghost-ring); }
}
/* Plafond atteint : estompée (voile de surface sur l'affiche, texte à l'opacité d'état désactivé ; pas
   d'opacité sur le bouton, qui pâlirait aussi l'anneau de focus), plus de survol, curseur interdit. */
.wtile--pick[aria-disabled="true"]:not([aria-pressed="true"]) { cursor: not-allowed; }
.wtile--pick[aria-disabled="true"]:not([aria-pressed="true"]) :is(.wtile-t, .wtile-sub) { opacity: var(--md-sys-state-disabled-opacity); }
.wtile--pick[aria-disabled="true"]:not([aria-pressed="true"]) .wtile-img::after { content: ""; position: absolute; inset: 0; border-radius: inherit;
  background: color-mix(in srgb, var(--md-sys-color-surface) 62%, transparent); pointer-events: none; }
.wtile--pick[aria-disabled="true"]:not([aria-pressed="true"]):hover .wtile-img { box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--md-sys-color-on-surface) 8%, transparent); }
/* Déjà prise, « Dans tes œuvres » (cochée ET figée : déjà dans Mes œuvres, hors du compte des 5), rendu de la
   maquette « Fiche » choisie par le porteur (21/10/2026, À valider) : la coche passe au neutre (inverse-surface)
   et l'affiche s'estompe (voile de surface à 55 %, filet ramené à 1 px, titre à l'opacité désactivée), pour ne
   pas la confondre avec un choix en cours. Remplace l'ancienne règle « l'état choisi reste entier » ; l'accueil
   guidé en hérite. */
.wtile--pick[aria-pressed="true"][aria-disabled="true"] { cursor: default; }
.wtile--pick[aria-pressed="true"][aria-disabled="true"] .wtile-img { box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--md-sys-color-on-surface) 8%, transparent); }
.wtile--pick[aria-pressed="true"][aria-disabled="true"] .wtile-img::after { content: ""; position: absolute; inset: 0; border-radius: inherit;
  background: color-mix(in srgb, var(--md-sys-color-surface) 55%, transparent); pointer-events: none; }
.wtile--pick[aria-pressed="true"][aria-disabled="true"] .wtile-check { background: var(--md-sys-color-inverse-surface); color: var(--md-sys-color-inverse-on-surface); z-index: 2; }
.wtile--pick[aria-pressed="true"][aria-disabled="true"] .wtile-t { opacity: var(--md-sys-state-disabled-opacity); }
.wtile--pick .wtile-sub { overflow-wrap: anywhere; }
/* Sans affiche : la surface de la vignette, l'icône de la nature (film, tv, clapperboard) au centre. */
.wtile-img--vide { display: grid; place-items: center; background-image: none; color: var(--md-sys-color-on-surface-variant); }
.wtile-img--vide > svg { width: 32px; height: 32px; }
@media (prefers-reduced-motion: reduce) {
  .wtile--pick .wtile-img, .wtile-check, .wtile-check svg { transition: none; }
  .wtile-check { transform: none; }
}

/* ── Créateur pionnier (.ptile) : bannière 16:7, photo ronde 64 qui mord sur la bannière, nom,
   rang d'arrivée (« 1re chaîne de SydePlay », icône award, rose lisible), nombre de réactions.
   Lien vers la chaîne. ── */
.ptile { display: flex; flex-direction: column; min-width: 0; overflow: hidden; color: inherit; text-decoration: none;
  border-radius: var(--md-sys-shape-corner-large); background: var(--md-sys-color-surface-container);
  box-shadow: inset 0 0 0 1px var(--md-sys-color-outline); transition: box-shadow .15s ease; }
.ptile:hover { box-shadow: inset 0 0 0 2px var(--md-sys-color-primary); }
.ptile:focus-visible { outline: 3px solid var(--md-sys-color-primary); outline-offset: 2px; }
.ptile-banner { aspect-ratio: 16 / 7; background: var(--sp-grad-brand) center / cover no-repeat; }
.ptile-ava { position: relative; display: grid; place-items: center; width: 64px; height: 64px; margin: -32px 0 0 16px; border-radius: var(--md-sys-shape-corner-medium); overflow: hidden;
  box-sizing: border-box; border: 3px solid var(--md-sys-color-surface-container); background: var(--sp-grad-brand); color: #fff;
  font: var(--md-sys-typescale-title-medium); font-weight: 700; }
.ptile-ava img { width: 100%; height: 100%; object-fit: cover; }
.ptile-b { display: flex; flex-direction: column; gap: 4px; padding: 8px 16px 16px; min-width: 0; }
.ptile-name { font: var(--md-sys-typescale-title-medium); font-weight: 700; color: var(--md-sys-color-on-surface); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ptile-rank { display: inline-flex; align-items: center; gap: 6px; font: var(--md-sys-typescale-label-large); font-weight: 600; color: var(--sp-brand-ink); }
.ptile-rank svg { width: 16px; height: 16px; flex: none; }
.ptile-sub { font: var(--md-sys-typescale-body-small); color: var(--md-sys-color-on-surface-variant); }

/* ── Réacteur recommandé (.crecos > .creco, 21/10/2026, À valider) : une liste de lignes, pas de cartes.
   Photo .ava de 44 (rayon 12, jamais ronde), nom et raison (« A réagi à … ») sur une ligne chacun,
   coupés proprement, puis « Voir la chaîne » (.cbtn--contour, 44) au bout. Filet outline-variant
   entre les lignes, aucune autre élévation. Seul le bouton est actionnable : la ligne n'a pas de survol.
   Sous 480 px d'écran, le bouton passe sous le texte (il garde ses 44 px) et la raison a deux lignes. ── */
.crecos { display: flex; flex-direction: column; margin: 0; padding: 0; list-style: none; min-width: 0; }
.creco { display: grid; grid-template-columns: 44px minmax(0, 1fr) auto; align-items: center; column-gap: 12px; row-gap: 8px;
  min-width: 0; padding: 12px 0; }
.creco + .creco { border-top: 1px solid var(--md-sys-color-outline-variant); }
.creco:first-child { padding-top: 0; }
/* La dernière ligne MONTRÉE : la dernière tout court, ou celle que suivent des lignes encore cachées (« Voir les N autres »). */
.creco:last-child, .creco:has(+ .creco[hidden]) { padding-bottom: 0; }
.crecos[hidden], .creco[hidden] { display: none; }
.creco-ava { width: 44px; height: 44px; border-radius: var(--md-sys-shape-corner-medium); }
img.creco-ava { object-fit: cover; background: var(--md-sys-color-surface-container-high); }
.creco-txt { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
/* .creco devant : dans l'appli, `.ds-app p { text-wrap: pretty }` (plus précise) remettait le retour à la
   ligne, et le nom comme la raison s'étalaient sur autant de lignes qu'il fallait. */
.creco :is(.creco-name, .creco-why) { margin: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.creco-name { font: var(--md-sys-typescale-title-small); font-weight: 600; color: var(--md-sys-color-on-surface); }
.creco-why { font: var(--md-sys-typescale-body-small); color: var(--md-sys-color-on-surface-variant); }
.creco-act { justify-self: end; }
@media (max-width: 479px) {
  .creco { grid-template-columns: 44px minmax(0, 1fr); }
  .creco-act { grid-column: 2; justify-self: start; }
  /* La raison est ce qui justifie la proposition : deux lignes sur téléphone, coupée par « … » au-delà
     (le texte complet passe alors en infobulle, createurs-oeuvres.js). */
  .creco .creco-why { display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; white-space: normal; }
}

/* ── Classement de la semaine (.top10) : le MÊME top 10, trois lectures ; la forme est choisie par le
   serveur selon la rotation du jour (jamais de minuteur ni de bouton pour en changer).
   Commun : chaque billet ou carte est un bouton (.top10-it, 44 de haut au moins) qui ouvre la réaction ;
   image (.top10-img, contour rose au survol) avec la BULLE du créateur (.top10-ava, cerclée de rose) ;
   titre .top10-t, ligne .top10-sub ; mouvement .top10-mv (icône Lucide + texte, NEUTRE : monte
   trending-up « +2 depuis lundi », descend trending-down, stable minus, nouvelle entrée sparkles en
   rose lisible ; jamais de vert ni de rouge). .top10-scroll : défilement horizontal de la trajectoire
   quand elle ne tient pas (10 × 112), qui déborde sur la marge droite comme les rangées.
   • .top10--billets (forme par défaut) : piste .shelf-track de billets de cinéma (.top10-ticket >
     .top10-tk) : affiche 2:3 de l'œuvre (.top10-poster) avec la bulle, perforation (tirets + deux
     encoches rondes découpées par un masque CSS, à 150cqw du haut = le bas de l'affiche), puis le talon
     (.top10-stub : « Nº 1 » .top10-no en headline-large 700, le nº 1 en --sp-brand-ink ; titre,
     « avec … », spectateurs, mouvement calé en bas). Pas de grand chiffre détouré à côté de l'affiche.
   • .top10--barres : piste .shelf-track de cartes (.top10-tile : rang discret .top10-rk en haut à
     gauche, titre en bas sur un voile, bulle en bas à droite) et, sous chacune, .top10-bar : longueur =
     spectateurs / ceux du nº 1 (--w), dégradé --sp-grad-brand-bar qui pâlit avec le rang (--o).
     Aucun gros chiffre.
   • .top10--trajectoire : un SVG (.top10-curve, trait en tirets) relie les pastilles numérotées
     (.top10-dot, la 1re au dégradé de marque) placées selon les spectateurs (--y : 0 en haut, 1 en bas) ;
     sous chacune (.top10-col), la carte puis le mouvement.
   Entrée (discover.js + Motion, une fois, coupée si moins d'animations) : transform et opacity
   seulement, plus le tracé du trait (masque .top10-draw). ── */
.top10 { container: top10 / inline-size; min-width: 0; }
/* position: relative : le texte .sr-only reste dans son bouton (sinon il échappe à la piste qui défile
   et élargit la page). */
.top10-it { position: relative; appearance: none; min-width: 0; margin: 0; padding: 0; border: 0; background: none; color: inherit; font: inherit; text-align: left; cursor: pointer; }
.top10-it:focus-visible { outline: 3px solid var(--md-sys-color-primary); outline-offset: 2px; border-radius: var(--md-sys-shape-corner-medium); }
.top10-img { position: relative; display: block; aspect-ratio: 16 / 9; border-radius: var(--md-sys-shape-corner-medium);
  background: var(--md-sys-color-surface-container-high) center / cover no-repeat; }
/* Filet et contour de survol posés AU-DESSUS de l'image et de son voile (la bulle reste devant). */
.top10-img::after { content: ""; position: absolute; inset: 0; border-radius: inherit; pointer-events: none;
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--md-sys-color-on-surface) 8%, transparent); transition: box-shadow .15s ease; }
.top10-it:hover .top10-img::after { box-shadow: inset 0 0 0 2px var(--md-sys-color-primary); }
.top10-ava { position: absolute; z-index: 1; right: 8px; bottom: 8px; display: grid; place-items: center; width: 40px; height: 40px; border-radius: var(--md-sys-shape-corner-small); overflow: hidden;
  box-sizing: border-box; border: 2px solid var(--md-sys-color-primary); box-shadow: 0 0 0 3px rgba(0, 0, 0, .35);
  background: var(--sp-grad-brand); color: #fff; font: var(--md-sys-typescale-label-medium); font-weight: 700; }
.top10-ava img { width: 100%; height: 100%; object-fit: cover; }
.top10-t { display: block; min-width: 0; font: var(--md-sys-typescale-title-small); font-weight: 700; color: var(--md-sys-color-on-surface);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.top10-sub { display: block; min-width: 0; font: var(--md-sys-typescale-body-small); color: var(--md-sys-color-on-surface-variant);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.top10-mv { display: inline-flex; align-items: flex-start; gap: 4px; min-width: 0; font: var(--md-sys-typescale-label-medium); font-weight: 600;
  color: var(--md-sys-color-on-surface-variant); }
.top10-mv svg { width: 16px; height: 16px; flex: none; }
.top10-mv[data-mv="new"] { color: var(--sp-brand-ink); }
.top10-scroll { overflow-x: auto; overscroll-behavior-x: contain; scroll-behavior: smooth; scrollbar-width: none;
  margin: 0 calc(-1 * var(--home-pad-x, 32px)) 0 -6px; padding: 6px var(--home-pad-x, 32px) 6px 6px; }
.top10-scroll::-webkit-scrollbar { display: none; }
.top10-scroll:focus-visible { outline: 3px solid var(--md-sys-color-primary); outline-offset: -3px; border-radius: var(--md-sys-shape-corner-medium); }
@media (prefers-reduced-motion: reduce) { .top10-scroll { scroll-behavior: auto; } }

/* Pistes des billets et des barres : la piste habituelle des rangées (.shelf-track) posée sur une liste. */
.top10-track { margin-top: 0; margin-bottom: 0; list-style: none; }

/* Billets : un billet de cinéma par place. Le billet (.top10-tk) porte le fond, le filet et le masque
   qui découpe les deux encoches de la perforation ; le bouton autour garde l'anneau de focus entier.
   Les billets d'une piste ont tous la même hauteur (talon étiré, mouvement calé en bas). */
.top10--billets .top10-track { --shelf-w: 188px; align-items: stretch; }
.top10-ticket { display: flex; width: 100%; height: 100%; container-type: inline-size; }
.top10-ticket:focus-visible { border-radius: var(--md-sys-shape-corner-large); }
.top10-tk { --cut: 150cqw; --notch: 10px; position: relative; display: flex; flex-direction: column; width: 100%; overflow: hidden;
  border-radius: var(--md-sys-shape-corner-large); background: var(--md-sys-color-surface-container);
  box-shadow: inset 0 0 0 1px var(--md-sys-color-outline-variant); transition: box-shadow .15s ease;
  -webkit-mask: radial-gradient(circle var(--notch) at 0 var(--cut), transparent calc(var(--notch) - .5px), #000 var(--notch)) 0 0 / 51% 100% no-repeat,
                radial-gradient(circle var(--notch) at 100% var(--cut), transparent calc(var(--notch) - .5px), #000 var(--notch)) 100% 0 / 51% 100% no-repeat;
          mask: radial-gradient(circle var(--notch) at 0 var(--cut), transparent calc(var(--notch) - .5px), #000 var(--notch)) 0 0 / 51% 100% no-repeat,
                radial-gradient(circle var(--notch) at 100% var(--cut), transparent calc(var(--notch) - .5px), #000 var(--notch)) 100% 0 / 51% 100% no-repeat; }
.top10-ticket:hover .top10-tk { box-shadow: inset 0 0 0 2px var(--md-sys-color-primary); }
.top10-poster { flex: none; aspect-ratio: 2 / 3; border-radius: var(--md-sys-shape-corner-large) var(--md-sys-shape-corner-large) 0 0; }
.top10-poster .top10-ava { right: 12px; bottom: 14px; }
.top10-stub { position: relative; display: flex; flex: 1; flex-direction: column; gap: 2px; min-width: 0; padding: 14px 14px 12px; box-sizing: border-box; }
.top10-stub::before { content: ""; position: absolute; top: -1px; left: calc(var(--notch) + 6px); right: calc(var(--notch) + 6px);
  border-top: 2px dashed var(--md-sys-color-outline); }
.top10-no { display: flex; align-items: baseline; gap: 4px; margin-bottom: 6px; font: var(--md-sys-typescale-headline-large); font-weight: 700; line-height: 1;
  color: var(--md-sys-color-on-surface); font-variant-numeric: tabular-nums; }
.top10-no-k { font: var(--md-sys-typescale-title-medium); font-weight: 700; color: var(--md-sys-color-on-surface-variant); }
.top10-track > li:first-child :is(.top10-no, .top10-no-k) { color: var(--sp-brand-ink); }
.top10-ticket .top10-t { white-space: normal; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; margin-bottom: 2px; }
.top10-ticket .top10-mv { margin-top: auto; padding-top: 8px; }
@container top10 (max-width: 760px) {
  .top10--billets .top10-track { --shelf-w: 164px; }
  .top10-no { font: var(--md-sys-typescale-headline-medium); font-weight: 700; line-height: 1; }
}

/* Barres : la piste de la rangée (.shelf-track), une carte et sa barre par place. */
.top10--barres { --shelf-w: 216px; }
.top10-tile { display: flex; flex-direction: column; gap: 10px; width: 100%; }
.top10-tile .top10-img::before { content: ""; position: absolute; inset: 35% 0 0; border-radius: 0 0 var(--md-sys-shape-corner-medium) var(--md-sys-shape-corner-medium);
  background: linear-gradient(0deg, rgba(0, 0, 0, .8), rgba(0, 0, 0, 0)); }
.top10-rk { position: absolute; left: 8px; top: 8px; display: grid; place-items: center; min-width: 26px; height: 26px; padding: 0 8px; box-sizing: border-box;
  border-radius: var(--md-sys-shape-corner-full); background: rgba(0, 0, 0, .62); color: #fff;
  font: var(--md-sys-typescale-label-medium); font-weight: 700; font-variant-numeric: tabular-nums; }
.top10-tile .top10-t { position: absolute; left: 10px; right: 52px; bottom: 8px; color: #fff; white-space: normal;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; }
.top10-tile .top10-ava { width: 36px; height: 36px; }
.top10-bar { display: block; height: 8px; overflow: hidden; border-radius: var(--md-sys-shape-corner-full); background: var(--md-sys-color-surface-container-high); }
.top10-bar > i { display: block; width: calc(var(--w, 0) * 100%); height: 100%; border-radius: inherit; background: var(--sp-grad-brand-bar);
  opacity: var(--o, 1); transform-origin: left center; }

/* Trajectoire : le trait (SVG étiré sur la largeur, épaisseur fixe) passe au centre des colonnes. */
.top10-traj { --plot: 128px; --dot: 36px; position: relative; min-width: calc(var(--n, 10) * 112px); }
.top10-curve { position: absolute; left: 0; top: calc(var(--dot) / 2); width: 100%; height: calc(var(--plot) - var(--dot)); overflow: visible; pointer-events: none; }
.top10-path { fill: none; stroke: color-mix(in srgb, var(--md-sys-color-on-surface-variant) 60%, transparent); stroke-width: 2; stroke-dasharray: 4 6;
  stroke-linecap: round; vector-effect: non-scaling-stroke; }
.top10-draw { fill: none; stroke: white; stroke-width: 40; stroke-dasharray: 1 1; stroke-linejoin: round; }
.top10-cols { display: grid; grid-template-columns: repeat(var(--n, 10), minmax(0, 1fr)); margin: 0; padding: 0; list-style: none; }
.top10-cols > li { min-width: 0; }
.top10-col { display: flex; flex-direction: column; gap: 4px; width: 100%; height: 100%; padding: 0 6px 6px; box-sizing: border-box; }
.top10-plot { position: relative; display: block; height: var(--plot); margin-bottom: 10px; }
.top10-dot { position: absolute; left: calc(50% - var(--dot) / 2); top: calc(var(--y, 0) * (100% - var(--dot))); display: grid; place-items: center;
  width: var(--dot); height: var(--dot); border-radius: 50%; box-sizing: border-box;
  background: var(--md-sys-color-surface); box-shadow: inset 0 0 0 2px var(--md-sys-color-outline); color: var(--md-sys-color-on-surface);
  font: var(--md-sys-typescale-label-large); font-weight: 700; font-variant-numeric: tabular-nums; }
.top10-cols > li:first-child .top10-dot { background: var(--sp-grad-brand); box-shadow: none; color: var(--md-sys-color-on-primary); }
.top10-col:hover .top10-dot { box-shadow: inset 0 0 0 2px var(--md-sys-color-primary); }
.top10-col .top10-img { margin-bottom: 6px; }
.top10-col .top10-ava { right: -6px; bottom: -6px; width: 26px; height: 26px; border: 0; box-shadow: 0 0 0 2px var(--md-sys-color-surface); font: var(--md-sys-typescale-label-small); font-weight: 700; }
.top10-col .top10-t { white-space: normal; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; }
.top10-col .top10-mv { margin-top: 2px; }
@container top10 (max-width: 900px) { .top10-traj { --plot: 104px; --dot: 32px; } }

/* ── Comment ça marche (.howto) : trois étapes, une vraie séquence (d'où les numéros). ── */
.howto { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 16px; margin: 0; padding: 0; list-style: none; }
.howto-step { display: flex; flex-direction: column; gap: 10px; padding: 20px; border-radius: var(--md-sys-shape-corner-large);
  background: var(--md-sys-color-surface-container); box-shadow: inset 0 0 0 1px var(--md-sys-color-outline); }
.howto-top { display: flex; align-items: center; justify-content: space-between; }
.howto-n { display: grid; place-items: center; width: 40px; height: 40px; border-radius: 50%; background: var(--sp-brand-tint); color: var(--sp-brand-ink);
  font: var(--md-sys-typescale-title-medium); font-weight: 700; }
.howto-top svg { width: 24px; height: 24px; color: var(--md-sys-color-on-surface-variant); }
.howto-t { margin: 0; font: var(--md-sys-typescale-title-medium); font-weight: 700; color: var(--md-sys-color-on-surface); }
.howto-p { margin: 0; font: var(--md-sys-typescale-body-medium); color: var(--md-sys-color-on-surface-variant); }
/* Photos des chaînes empilées sur l'affiche (« Choisis avec qui la regarder ») : 28 px, anneau sombre. */
.wtile-img { position: relative; }
.wtile-avas { position: absolute; left: 8px; bottom: 8px; display: flex; }
.wtile-ava { display: grid; place-items: center; width: 28px; height: 28px; margin-left: -8px; border-radius: var(--md-sys-shape-corner-small); overflow: hidden;
  box-shadow: 0 0 0 2px rgba(0, 0, 0, .6); background: var(--sp-grad-brand); color: #fff; font: var(--md-sys-typescale-label-small); font-weight: 700; }
.wtile-ava:first-child { margin-left: 0; }
.wtile-ava img { width: 100%; height: 100%; object-fit: cover; }

/* ════════════════════════════════════════════════════════════════════
   MES ŒUVRES · CONCEPT « FICHE » (21/10/2026, À valider) : les briques que la maquette choisie
   par le porteur (concept 3 « Fiche », voulue telle quelle) demande et qui manquaient au DS. Le CSS
   est celui de la maquette, recopié tel quel. Documenté sur /design-system (Components, « Work
   row », « Episode grid », « New since last visit », « Reaction card · New mark », « Chip with
   count ») ; l'affiche « Dans tes œuvres » est rangée avec .wtile--pick, plus haut. La mise en page
   de la page (colonnes, fiche, vue Nouveautés) reste dans pages/favworks/favworks.css.
   ════════════════════════════════════════════════════════════════════ */

/* ── Ligne d'œuvre (.fi-row, 21/10/2026, À valider) : la colonne de Mes œuvres. Un lien (vrai href,
   ?oeuvre=…) en grille 40 · texte · fin, 76 de haut au moins, rayon 12, couche d'état au survol
   (écran à survol seulement). Vignette .wtile-img de 40 (2:3, rayon 8) ou .wtile-img--vide (icône 18) ;
   titre sur deux lignes au plus ; sous-titre d'une ligne (badge de nature .bdg--sm + « 12 réactions ·
   il y a 2 h »), coupé par « … » ; au bout, la cloche barrée (.fi-row-off, alertes coupées) puis la
   pastille des nouveautés (.tbar-dot statique, « 99+ » au-delà). Variante d'entrée .fi-row--news (60 de
   haut, pastille d'icône sparkles .fi-row-ic sur la teinte rose). Choisie : aria-current="page", fond
   --sp-brand-tint, titre en 700, texte secondaire relevé au cran on-surface-strong (4,5:1 tenu sur la
   teinte). Légende de liste .fi-cap (« Les plus actives d'abord »). Tabulation itinérante (une seule
   ligne à tabindex 0, flèches haut et bas, Début, Fin) : c'est le script de la page qui la tient. ── */
.fi-cap { margin: 16px 0 6px; padding: 0 8px; font: var(--md-sys-typescale-label-medium); color: var(--md-sys-color-on-surface-variant); }
.fi-row { position: relative; isolation: isolate; display: grid; grid-template-columns: 40px minmax(0, 1fr) auto; align-items: center; column-gap: 12px;
  min-height: 76px; padding: 8px; border-radius: var(--md-sys-shape-corner-medium); color: inherit; text-decoration: none; }
.fi-row::after { content: ""; position: absolute; inset: 0; border-radius: inherit; background: currentColor; opacity: 0; pointer-events: none; transition: opacity .15s ease; }
@media (hover: hover) and (pointer: fine) { .fi-row:hover::after { opacity: var(--md-sys-state-hover-opacity); } }
.fi-row:focus-visible { outline: 3px solid var(--md-sys-color-primary); outline-offset: -3px; }
/* Ligne choisie : fond teinté de rose ; sur cette teinte, le texte secondaire passe au cran « strong » (4,5:1 tenu). */
.fi-row[aria-current="page"] { background: var(--sp-brand-tint); --md-sys-color-on-surface-variant: var(--md-sys-color-on-surface-strong); }
.fi-row[aria-current="page"] .fi-row-t { font-weight: 700; }
.fi-row .wtile-img { width: 40px; border-radius: var(--md-sys-shape-corner-small); }
.fi-row .wtile-img--vide > svg { width: 18px; height: 18px; }
.fi-row-ic { display: grid; place-items: center; width: 40px; height: 40px; border-radius: var(--md-sys-shape-corner-small); background: var(--sp-brand-tint); color: var(--sp-brand-ink); }
.fi-row-ic svg { width: 20px; height: 20px; }
.fi-row--news { min-height: 60px; }
.fi-row-txt { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.fi-row-t { font: var(--md-sys-typescale-title-small); color: var(--md-sys-color-on-surface); display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; overflow-wrap: anywhere; }
.fi-row-sub { display: flex; align-items: center; gap: 6px; min-width: 0; font: var(--md-sys-typescale-body-small); color: var(--md-sys-color-on-surface-variant); white-space: nowrap; }
.fi-row-sub > span:last-child { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.fi-row-sub > .bdg { flex: none; font-weight: 600; }   /* le badge de nature de la maquette (.bdg--sm en 600), jamais écrasé */
.fi-row-end { display: flex; align-items: center; gap: 6px; }
.fi-row-end .tbar-dot { position: static; }
.fi-row-off { display: inline-flex; color: var(--md-sys-color-on-surface-variant); }
.fi-row-off svg { width: 18px; height: 18px; }
@media (prefers-reduced-motion: reduce) { .fi-row::after { transition: none; } }

/* ── Grille d'épisodes (.ex-seg.fi-eps, 21/10/2026, À valider) : le groupe connecté .ex-seg rangé en
   grille (cases de 56 au moins, écart 8), une case par épisode de la plage. Au moins une réaction :
   bouton normal ; pas encore de réaction : disabled, à l'opacité désactivée, sans couche de survol (les
   flèches la sautent) ; du nouveau : point rose .tbar-dot--plain en haut à droite (4 / 6) ; choisie :
   aria-pressed="true" (pastille inverse-surface du groupe). Une seule case à tabindex 0 ; flèches dans
   les deux sens (haut et bas = une rangée), Début, Fin ; Entrée ou Espace choisit. Légende .fi-legend
   (« Au moins une réaction », « Pas encore de réaction », « Du nouveau »), aria-hidden : chaque case dit
   son état dans son aria-label. ── */
.fi-eps { display: grid; grid-template-columns: repeat(auto-fill, minmax(56px, 1fr)); gap: 8px; }
.fi-eps button { min-width: 0; padding: 0 6px; font-variant-numeric: tabular-nums; }
.fi-eps button:disabled { opacity: var(--md-sys-state-disabled-opacity); cursor: default; }
.fi-eps button:disabled::after { display: none; }
.fi-eps button .tbar-dot--plain { position: absolute; top: 4px; right: 6px; }
.fi-legend { display: flex; flex-wrap: wrap; gap: 6px 16px; margin: 12px 0 0; font: var(--md-sys-typescale-label-medium); color: var(--md-sys-color-on-surface-variant); }
.fi-legend > span { display: inline-flex; align-items: center; gap: 6px; }
.fi-legend i { display: inline-block; width: 22px; height: 14px; border-radius: var(--md-sys-shape-corner-full); background: var(--md-sys-color-surface-container-high); box-shadow: inset 0 0 0 1px var(--md-sys-color-outline); }
.fi-legend i.off { opacity: var(--md-sys-state-disabled-opacity); }
.fi-legend i.new { width: 8px; height: 8px; background: var(--md-sys-color-primary); box-shadow: none; }

/* ── Marque du neuf (.fi-new, 21/10/2026, À valider) : « 4 nouvelles », « 4 nouvelles depuis ta dernière
   visite » ; label-medium 700 en rose lisible (--sp-brand-ink), dans une phrase ou une ligne d'infos. ── */
.fi-new { font: var(--md-sys-typescale-label-medium); font-weight: 700; color: var(--sp-brand-ink); }

/* ── Marque « Nouveau » de la carte de réaction (.rcard-new, 21/10/2026, À valider) : badge compact
   .bdg.bdg--sm.bdg--point en 600, en tête du bandeau du haut de la vignette (.rcard-top), quand la
   réaction est arrivée depuis la dernière visite (reaction-ui.js : r.isNew === true). ── */
.rcard-new { font-weight: 600; }

/* ── Nombre dans une puce (.chip .count, 21/10/2026, À valider) : « Séries 6 » ; le nombre au cran
   on-surface-strong, et sur la puce choisie la couleur de la puce à 80 %. Un nombre dans un h5 garde
   ses 6 px (« Chez tes créateurs 3 »). ── */
.chip .count { color: var(--md-sys-color-on-surface-strong); }
.chip--on .count { color: inherit; opacity: .8; }
h5 > .count { margin-left: 6px; }

/* ── Champs de recherche de Mes œuvres (colonne, premiers pas, fenêtre d'ajout) : sans la croix native du
   navigateur, comme la maquette (et comme la barre du haut, .tbar-search). ── */
:is(.fi-nav, .fi-first, .fi-add) .ex-search input::-webkit-search-cancel-button { -webkit-appearance: none; appearance: none; }

/* ── Filtre par plateforme (Accueil, 22/10/2026, À décider) : quatre ronds de 36 (.chip--plat, une puce ronde
   par plateforme prise en charge), le logo seul (20, rayon 4). Au repos, grisé (logo en niveaux de gris, estompé) ;
   choisi (aria-pressed=true, .chip--on) : fond inverse-surface, logo en couleur. Plusieurs peuvent être choisis. ── */
.chip--plat { width: 36px; padding: 0; justify-content: center; }
.chip--plat img { flex: none; width: 20px; height: 20px; border-radius: var(--md-sys-shape-corner-extra-small); transition: filter .18s ease, opacity .18s ease; }
.chip--plat:not(.chip--on) img { filter: grayscale(1); opacity: .55; }
@media (prefers-reduced-motion: reduce) { .chip--plat img { transition: none; } }

/* ── Carte de profil d'un créateur (.pcard), 22/10/2026, À décider ──
   Pop-up ouverte depuis le bouton à côté du nom sur la page de la chaîne. Habit « star card »
   (2026-10-23) : carton de 24 px, avatar CARRÉ aux bords arrondis à halo de projecteur ambré
   (dans la tête de la carte — le corps, lui, parle la langue du design system : titres de
   fiches en petites capitales de la marque, survols rosés), affiches préférées qui se
   soulèvent au survol. Deux habits, choisis par le créateur dans le Studio : « bannière »
   (une image ou un GIF en haut, 150 px) et « fond » (l'image sur toute la carte ; les boîtes
   de texte et de boutons passent en verre, dosé sur le fond). 6 œuvres préférées au plus
   (3 montrées, « Voir les N autres »). */
.pcard { --pcard-amber: var(--md-sys-color-primary); position: relative; isolation: isolate; width: 400px; max-width: 100%; max-height: min(86vh, 780px); display: flex; flex-direction: column;
  border-radius: 24px; background: var(--md-sys-color-surface); color: var(--md-sys-color-on-surface);
  overflow: hidden; box-shadow: 0 30px 80px -28px rgba(0, 0, 0, .6); }
.pcard-scroll { flex: 1; min-height: 0; overflow-y: auto; overscroll-behavior: contain; scrollbar-width: thin;
  scrollbar-color: color-mix(in srgb, var(--md-sys-color-on-surface) 25%, transparent) transparent; }
.pcard-close { position: absolute; top: 12px; right: 12px; z-index: 3; width: 40px; height: 40px; border-radius: var(--md-sys-shape-corner-full);
  background: color-mix(in srgb, var(--md-sys-color-scrim) 45%, transparent); color: #fff; backdrop-filter: blur(8px); }
.pcard-close:hover { background: color-mix(in srgb, var(--md-sys-color-scrim) 65%, transparent); }

/* Tête : la bannière (ou, en mode fond, un espace où l'image respire), l'avatar centré à cheval dessous. */
.pcard-head { position: relative; height: 150px; flex: none; }
.pcard-head img, .pcard-bg img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; display: block; }
.pcard-head img { border-radius: var(--md-sys-shape-corner-extra-large) var(--md-sys-shape-corner-extra-large) 0 0; image-rendering: auto; }
/* Un voile qui fond la bannière dans la carte, pour que le cadre de l'avatar se lise sur toute image. */
.pcard--banner .pcard-head::after { content: ""; position: absolute; inset: 55% 0 0; background: linear-gradient(to bottom, transparent, color-mix(in srgb, var(--md-sys-color-surface) 85%, transparent)); pointer-events: none; }
.pcard-ava { position: absolute; left: 50%; bottom: -48px; transform: translateX(-50%); z-index: 2; width: 96px; height: 96px; padding: 3px; box-sizing: border-box;
  border-radius: 24px; background: var(--md-sys-color-surface);
  /* Le halo de projecteur ambré (dans la TÊTE de la carte) : un trait ambré, une auréole
     douce, une ombre portée. Le corps de la carte, lui, parle la langue du design system. */
  border: 2px solid var(--pcard-amber, var(--md-sys-color-primary));
  box-shadow: 0 0 0 5px color-mix(in srgb, var(--pcard-amber, var(--md-sys-color-primary)) 16%, transparent),
              0 0 22px 2px color-mix(in srgb, var(--pcard-amber, var(--md-sys-color-primary)) 45%, transparent),
              0 14px 34px rgba(0, 0, 0, .35); }
.pcard-ava img, .pcard-ava .pcard-ini { width: 100%; height: 100%; border-radius: 18px; object-fit: cover; display: grid; place-items: center;
  background: var(--sp-grad-brand); color: #fff; font: var(--md-sys-typescale-headline-small); font-weight: 700; }

/* Identité, centrée sous l'avatar. */
.pcard-id { padding: 60px 24px 4px; text-align: center; }
.pcard-name { margin: 0; font: var(--md-sys-typescale-headline-small); font-weight: 800; letter-spacing: -0.015em; display: flex; justify-content: center; align-items: center; gap: 6px; }
.pcard-name .ic-verified { color: var(--md-sys-color-primary); }
.pcard-handle { margin: 4px 0 0; font: var(--md-sys-typescale-body-medium); color: var(--md-sys-color-on-surface-variant); }

/* Les boîtes-fiches : filet fin, rayon 16, titre en petites capitales ambrées. */
.pcard-body { display: flex; flex-direction: column; gap: 10px; padding: 16px 16px 16px; }
.pcard-box { border: 1px solid var(--md-sys-color-outline-variant); border-radius: 16px; background: var(--md-sys-color-surface-container); padding: 14px 16px; }
.pcard-box h4 { margin: 0 0 8px; font: var(--md-sys-typescale-label-medium); font-weight: 700; letter-spacing: .12em; text-transform: uppercase;
  color: color-mix(in srgb, var(--md-sys-color-primary) 78%, var(--md-sys-color-on-surface)); }
.pcard-bio { margin: 0; font: var(--md-sys-typescale-body-medium); line-height: 1.5; color: var(--md-sys-color-on-surface); overflow-wrap: anywhere; }
.pcard-works { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 10px; }
.pcard-works .wtile-t { font: var(--md-sys-typescale-label-medium); font-weight: 600; -webkit-line-clamp: 2; }
/* Les affiches préférées se soulèvent au survol, comme des jaquettes qu'on feuillette. */
.pcard-works .wtile-img { border-radius: 10px; transition: transform .18s ease, box-shadow .18s ease; }
.pcard-works a.wtile:hover .wtile-img { transform: translateY(-3px); box-shadow: 0 10px 22px -10px rgba(0, 0, 0, .55); }
.pcard-more { margin-top: 10px; }
.pcard-links { display: flex; flex-direction: column; margin: 0 -6px; }
.pcard-link { display: flex; align-items: center; gap: 10px; min-height: 44px; padding: 0 8px; border-radius: var(--md-sys-shape-corner-medium); color: inherit; text-decoration: none; }
.pcard-link:hover { background: color-mix(in srgb, var(--md-sys-color-primary) 8%, transparent); }
.pcard-link > svg:first-child { flex: none; width: 20px; height: 20px; }
.pcard-link b { flex: 1; white-space: nowrap; font: var(--md-sys-typescale-body-medium); font-weight: 600; }
.pcard-link span { display: inline-flex; align-items: center; gap: 4px; font: var(--md-sys-typescale-body-small); color: var(--md-sys-color-on-surface-variant); }
/* Le détail (« @pseudo », domaine, « Palier et plus ») = un seul bloc en ligne : le nom du palier (donnée) et « et plus » (traduit) restent séparés par une simple espace. */
/* Le libellé (« Discord de la chaîne ») ne passe jamais sur deux lignes : si la place manque (autre langue, long nom de palier), c'est le détail qui se coupe en « … ». */
.pcard-link > span { min-width: 0; }
.pcard-link .pcard-link-d { display: block; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pcard-link .pcard-link-d span { display: inline; }
.pcard-link span svg { flex: none; width: 14px; height: 14px; transition: transform .15s ease; }
/* La flèche du lien glisse vers le haut-droite au survol. */
.pcard-link:hover span svg { transform: translate(2px, -2px); }
.pcard-since b { display: block; font: var(--md-sys-typescale-title-medium); font-weight: 700; }
.pcard-since span { font: var(--md-sys-typescale-body-small); color: var(--md-sys-color-on-surface-variant); }

/* Pied, collé en bas : Recommander une œuvre, et le lien de la chaîne à copier. */
.pcard-foot { flex: none; display: flex; align-items: center; gap: 8px; padding: 12px 16px; border-top: 1px solid var(--md-sys-color-outline-variant); background: var(--md-sys-color-surface); }
.pcard-foot .cbtn { flex: 1; }

/* ── Mode « fond » : l'image sur toute la carte, les boîtes en verre dosé sur elle. ── */
.pcard--full .pcard-bg { position: absolute; inset: 0; z-index: -1; }
.pcard--full .pcard-bg::after { content: ""; position: absolute; inset: 0;
  background: linear-gradient(to bottom, color-mix(in srgb, var(--md-sys-color-scrim) 10%, transparent), color-mix(in srgb, var(--md-sys-color-scrim) 38%, transparent) 45%, color-mix(in srgb, var(--md-sys-color-scrim) 58%, transparent)); }
.pcard--full .pcard-head { height: 120px; }
.pcard--full .pcard-body { padding-top: 10px; }
.pcard--full .pcard-ava { background: color-mix(in srgb, var(--md-sys-color-surface) 70%, transparent); backdrop-filter: blur(10px); }
/* Le nom et l'arobase ne se posent jamais à nu sur l'image : une plaque de verre, où l'avatar vient s'asseoir
   (retour du porteur, 22/10/2026 : un texte nu devient invisible selon les couleurs de l'image). */
.pcard--full .pcard-id { margin: 0 16px; padding: 60px 16px 14px; border-radius: var(--md-sys-shape-corner-large); }
.pcard--full .pcard-id, .pcard--full .pcard-box, .pcard--full .pcard-foot {
  background: color-mix(in srgb, var(--md-sys-color-surface) 74%, transparent); backdrop-filter: blur(16px) saturate(140%);
  border: 1px solid color-mix(in srgb, var(--md-sys-color-on-surface) 10%, transparent); }
.pcard--full .pcard-foot { border-width: 1px 0 0; }
@media (prefers-reduced-transparency: reduce) {
  .pcard--full .pcard-box, .pcard--full .pcard-foot { background: var(--md-sys-color-surface); backdrop-filter: none; }
}
@media (max-width: 479px) { .pcard { width: 100%; max-height: 100%; border-radius: 0; } .pcard-head img { border-radius: 0; } }

/* Ajouts pour la vraie fenêtre (profile-card.js) : le voile commun .dlg-ov porte .dlg-ov--pcard ; sur téléphone
   (moins de 480 px) il n'a plus de marge et la carte prend tout l'écran. Les affiches au-delà de la troisième sont
   [hidden] jusqu'à « Voir les N autres » (le display:flex de .wtile battrait l'attribut). Le contenu qui défile
   reçoit le focus à l'ouverture (tabindex -1), sans anneau ; le bouton du lien reste à droite même seul. */
.pcard-scroll:focus { outline: none; }
.pcard-works .wtile[hidden] { display: none; }
.pcard-foot .ibtn { margin-left: auto; }
@media (max-width: 479px) { .dlg-ov--pcard { padding: 0; } .pcard { height: 100%; } }
/* Démo de l'atelier : les cartes côte à côte, à hauteur fixe pour voir le pied et le défilement
   (.ds-pcard-demo--libre : à la hauteur du contenu, pour les replis). */
.ds-pcard-demo { display: flex; flex-wrap: wrap; gap: 32px; align-items: flex-start; }
.ds-pcard-demo .pcard { height: 720px; max-height: none; }
.ds-pcard-demo--libre .pcard { height: auto; }
