
  :root{
    --paper:#EFECF4;
    --card:#FFFFFF;
    --ink:#1E1A2B;
    --muted:#6E6880;
    --line:#DDD7E9;
    --violet:#5330E8;
    --violet-soft:#EAE3FF;
    --gold:#B9820A;
    --radius:14px;
    /* Variables introduites pour le mode nuit : partout où une couleur était
       écrite en dur et supposait un fond clair. */
    --actif-bg:#1E1A2B;
    --actif-ink:#FFFFFF;
    --det-bg:#F7F5FC;
    --det-ink:#3B3550;
    --chip-film-bg:#FBEFD6;
    --chip-live-bg:#DFF3E6;
    --chip-live-ink:#1F6B3B;
    --erreur:#8A2E2E;
    /* Degré d'envie : du chaud au froid, pour que l'échelle se lise à la
       couleur avant de se lire au mot. Rouge = j'ai hâte, ambre = bientôt,
       bleu = un jour. Trois teintes franchement distinctes, sinon la
       distinction d'un coup d'œil ne marche pas. */
    --hype-bg:#FCE4E0;   --hype-ink:#A8291C;
    --soon-bg:#FBEFD6;   --soon-ink:#8A6100;
    --oneday-bg:#E3EDF9; --oneday-ink:#2F5C8A;
    /* Paliers de la tier list : le dégradé rouge → vert des tier lists, qui
       se lit comme une échelle avant même qu'on lise la lettre. Une seule
       encre pour les cinq — ces fonds sont assez clairs pour la porter. */
    --t-S:#FF7F7F;
    --t-A:#FFBF7F;
    --t-B:#FFDF7F;
    --t-C:#F2F27A;
    --t-D:#BFEB8A;
    --tier-ink:#1E1A2B;
    color-scheme:light;
  }

  /* Mode nuit. Le choix explicite l'emporte ; sans choix, on suit le système. */
  :root[data-theme="nuit"]{
    --paper:#15131C;
    --card:#1E1B28;
    --ink:#E8E4F2;
    --muted:#9A93AC;
    --line:#302B3F;
    --violet:#9F86FF;
    --violet-soft:#2A2340;
    --gold:#D9A63A;
    --actif-bg:#9F86FF;
    --actif-ink:#15131C;
    --det-bg:#241F33;
    --det-ink:#CFC8E0;
    --chip-film-bg:#3A2E12;
    --chip-live-bg:#16301F;
    --chip-live-ink:#7FD3A0;
    --erreur:#E58A8A;
    /* Mêmes teintes inversées : fond sombre, encre claire. Reprendre les
       couleurs du mode jour telles quelles donnerait des pastilles
       fluorescentes sur fond noir. */
    --hype-bg:#3D1F1A;   --hype-ink:#FF9E8F;
    --soon-bg:#3A2E12;   --soon-ink:#E0AE45;
    --oneday-bg:#18293B; --oneday-ink:#8FBFEC;
    /* Mêmes teintes assombries : les pastels du mode jour deviennent cinq
       bandes fluorescentes sur fond noir. L'encre passe en clair, sans quoi
       ces fonds plus sombres ne portent plus de texte foncé. */
    --t-S:#A8443F;
    --t-A:#A06B33;
    --t-B:#8F7B2C;
    --t-C:#77802E;
    --t-D:#4E7B3C;
    --tier-ink:#F6F3FF;
    color-scheme:dark;
  }
  *{box-sizing:border-box}

  /* Police de marque. Servie depuis public/fonts/ plutôt que depuis Google
     Fonts, où elle existe pourtant : sur un homelab sans accès internet, la
     police distante ne serait jamais rendue, alors que le fichier local
     s'affiche toujours. `local()` en premier évite le téléchargement quand
     elle est installée sur la machine.

     Le .woff2 est cherché en premier bien qu'il n'existe pas encore : le
     jour où tu déposes la version convertie — environ deux fois plus légère
     — elle est prise sans rien changer ici. */
  @font-face{
    font-family:"Cinzel Decorative";
    src:local("Cinzel Decorative Bold"),
        local("CinzelDecorative-Bold"),
        url("/fonts/CinzelDecorative-Bold.woff2") format("woff2"),
        url("/fonts/CinzelDecorative-Bold.ttf")   format("truetype");
    /* Déclarer 700 est indispensable : sans cette ligne la fonte est
       enregistrée comme graisse normale, et .marque la demandant en 700, le
       navigateur épaissirait artificiellement une police déjà grasse. */
    font-weight:700;
    font-display:swap;
  }

  /* L'attribut hidden masque via la regle [hidden]{display:none} de la feuille
     du navigateur, qu'une simple regle d'auteur suffit a ecraser : .login pose
     display:grid, ce qui annulait hidden et laissait l'ecran de connexion,
     en position:fixed inset:0 z-index:10, recouvrir toute l'application.
     Cette declaration retablit la priorite. */
  [hidden]{display:none!important}
  html,body{margin:0;padding:0}
  body{
    background:var(--paper);
    color:var(--ink);
    font-family:'Public Sans',system-ui,-apple-system,'Segoe UI',Roboto,sans-serif;
    font-size:15px;
    line-height:1.5;
    -webkit-font-smoothing:antialiased;
  }
  .wrap{max-width:1120px;margin:0 auto;padding:22px 16px 80px}

  /* ---------- en-tête ---------- */
  header .eyebrow{
    font-family:'IBM Plex Mono',ui-monospace,'SFMono-Regular',Menlo,monospace;
    font-size:11px;letter-spacing:.14em;text-transform:uppercase;
    color:var(--violet);margin:0 0 6px;
  }
  h1{
    font-family:'Bricolage Grotesque','Trebuchet MS',system-ui,sans-serif;
    font-weight:800;font-size:clamp(28px,7vw,44px);
    line-height:1.02;letter-spacing:-.02em;margin:0 0 8px;
  }
  h1 em{font-style:normal;color:var(--violet)}
  .lede{margin:0 0 18px;color:var(--muted);max-width:52ch}

  /* ---------- marque ---------- */
  .marque{
    font-family:"Cinzel Decorative","Bricolage Grotesque","Trebuchet MS",system-ui,sans-serif;
    font-weight:700;font-size:clamp(26px,6vw,40px);line-height:1;
    letter-spacing:.01em;margin:0;color:var(--ink);
  }
  /* « Anime » à la couleur du site, « kun » à l'encre courante — donc noir
     en mode jour et clair en mode nuit, sans règle supplémentaire. Sur
     l'écran de connexion, .marque-sm colore déjà tout en violet : la nuance
     y disparaît d'elle-même, ce qui est voulu. */
  .marque-accent{color:var(--violet)}
  .marque-sm{font-size:26px;margin:0 0 16px;color:var(--violet)}

  /* ---------- progression : un segment par titre ---------- */
  .progress{
    background:var(--card);border:1px solid var(--line);border-radius:var(--radius);
    padding:14px 16px;margin-bottom:14px;
  }
  .progress-top{display:flex;align-items:baseline;justify-content:space-between;gap:12px;margin-bottom:10px}
  .progress-count{font-family:'Bricolage Grotesque','Trebuchet MS',system-ui,sans-serif;font-weight:700;font-size:19px}
  .progress-count b{color:var(--violet)}
  .reset{
    background:none;border:0;padding:4px 0;color:var(--muted);
    font-family:'IBM Plex Mono',ui-monospace,'SFMono-Regular',Menlo,monospace;font-size:11.5px;letter-spacing:.04em;
    text-transform:uppercase;cursor:pointer;text-decoration:underline;text-underline-offset:3px;
  }
  .reset:hover{color:var(--ink)}
  .strip{display:flex;gap:3px}
  .strip span{
    flex:1;height:9px;border-radius:2px;background:var(--violet-soft);
    transition:background .18s ease,transform .18s ease;
  }
  .strip span.on{background:var(--violet);transform:scaleY(1.35)}

  /* ---------- barre de contrôles ---------- */
  .controls{display:flex;flex-wrap:wrap;gap:8px;margin-bottom:16px}
  .seg{display:flex;flex-wrap:wrap;background:var(--card);border:1px solid var(--line);border-radius:999px;padding:3px;gap:2px}
  .seg button{
    border:0;background:none;cursor:pointer;border-radius:999px;
    padding:7px 13px;font-family:'Public Sans',system-ui,sans-serif;font-size:13.5px;font-weight:600;color:var(--muted);
  }
  .seg button[aria-pressed="true"]{background:var(--actif-bg);color:var(--actif-ink)}
  .field{
    flex:1;min-width:150px;display:flex;align-items:center;gap:8px;
    background:var(--card);border:1px solid var(--line);border-radius:999px;padding:0 14px;
  }
  .field svg{flex:none;opacity:.45}
  .field input,.field select{
    border:0;outline:none;background:none;width:100%;padding:10px 0;
    font-family:'Public Sans',system-ui,sans-serif;font-size:14px;color:var(--ink);
  }
  select.pill{
    appearance:none;background:var(--card);border:1px solid var(--line);border-radius:999px;
    padding:10px 34px 10px 14px;font-family:'Public Sans',system-ui,sans-serif;font-size:14px;color:var(--ink);
    cursor:pointer;
    background-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='10' height='6' fill='none'><path d='M1 1l4 4 4-4' stroke='%236E6880' stroke-width='1.6'/></svg>");
    background-repeat:no-repeat;background-position:right 14px center;
  }
  /* Sens du tri : la fleche est un pseudo-element, elle survit donc aux
     reecritures de textContent faites par le script. */
  button.sens{
    appearance:none;background:var(--card);border:1px solid var(--line);border-radius:999px;
    padding:10px 14px;font-family:'Public Sans',system-ui,sans-serif;font-size:14px;
    color:var(--ink);cursor:pointer;display:inline-flex;align-items:center;gap:7px;
  }
  button.sens::before{content:"↓";font-weight:700;color:var(--violet);font-size:15px}
  button.sens[data-sens="asc"]::before{content:"↑"}
  button.sens:hover{border-color:var(--violet)}

  /* Filtre à cocher, distinct du groupe .seg : celui-ci se cumule avec le
     statut sélectionné au lieu de le remplacer, et la case le dit. */
  button.coche{
    appearance:none;background:var(--card);border:1px solid var(--line);border-radius:999px;
    padding:9px 15px 9px 11px;font-family:'Public Sans',system-ui,sans-serif;font-size:13.5px;
    font-weight:600;color:var(--muted);cursor:pointer;
    display:inline-flex;align-items:center;gap:8px;
  }
  /* La coche est toujours là, simplement invisible tant que le filtre est
     inactif : sans cela le bouton change de largeur à chaque clic. */
  button.coche::before{
    content:"✓";flex:none;width:16px;height:16px;border-radius:5px;
    border:1.5px solid var(--line);display:grid;place-items:center;
    font-size:11px;line-height:1;color:transparent;
  }
  button.coche:hover{border-color:var(--violet);color:var(--ink)}
  button.coche[aria-pressed="true"]{border-color:var(--violet);color:var(--violet)}
  button.coche[aria-pressed="true"]::before{
    background:var(--violet);border-color:var(--violet);color:var(--actif-ink);
  }

  /* Bouton de synchronisation : c'est une action, pas un lien discret. */
  .btn-sync{
    display:inline-flex;align-items:center;gap:8px;flex:none;
    background:var(--violet);color:#fff;border:0;border-radius:999px;
    padding:9px 17px;font-family:'Public Sans',system-ui,sans-serif;
    font-size:13.5px;font-weight:600;cursor:pointer;letter-spacing:0;
    text-transform:none;transition:background .15s ease;
  }
  .btn-sync::before{content:"⟳";display:inline-block;font-size:16px;line-height:1}
  .btn-sync:hover{filter:brightness(1.15)}
  .btn-sync:disabled{background:var(--muted);cursor:progress}
  .btn-sync:disabled::before{animation:tourne 1.1s linear infinite}
  @keyframes tourne{to{transform:rotate(360deg)}}

  :focus-visible{outline:2px solid var(--violet);outline-offset:2px}

  /* ---------- tableau ---------- */
  .head{display:none}
  .row{
    background:var(--card);border:1px solid var(--line);border-radius:var(--radius);
    padding:14px;margin-bottom:10px;
    /* minmax(0,1fr) et non 1fr : sans cela la colonne refuse de descendre
       sous la largeur minimale de son contenu (un titre japonais, une URL,
       une liste de tags), la fiche s'élargit au-delà de l'écran et la page
       se met à défiler latéralement. */
    display:grid;grid-template-columns:auto minmax(0,1fr);gap:4px 12px;align-items:start;
    transition:opacity .2s ease;
  }
  .row > .title,.row > .cell,.row > details{min-width:0}
  /* Le panneau de détails occupe toute la largeur de la fiche : sous la
     jaquette il ne reste qu'une colonne étroite, illisible sur téléphone. */
  .row > details{grid-column:1/-1}
  /* Vu = terminé, pas rayé de la liste : le titre reste lisible tel quel.
     L'opacité suffit à distinguer une fiche finie d'une fiche en attente,
     et ces titres servent maintenant de matière à la tier list. */
  .row.seen{opacity:.5}

  /* Meme gabarit pour toutes les vignettes quelle que soit la taille fournie
     par AniList : object-fit:cover recadre au lieu de deformer. */
  /* La jaquette et sa pastille forment une seule case de la grille.
     justify-self:start la fait se régler sur la largeur de l'image plutôt
     que sur celle de la colonne : la pastille reste ainsi cadrée dessous. */
  .jaquette{display:grid;gap:5px;justify-self:start}
  .vignette{
    width:64px;height:92px;object-fit:cover;border-radius:8px;
    background:var(--violet-soft);display:block;flex:none;
  }
  /* Sortie de moins de deux mois — voir estRecent() dans app.js. */
  .neuf{
    font-family:'IBM Plex Mono',ui-monospace,'SFMono-Regular',Menlo,monospace;
    font-size:9.5px;font-weight:600;letter-spacing:.08em;text-transform:uppercase;
    text-align:center;border-radius:5px;padding:3px 4px;cursor:help;
    /* Le couple violet / actif-ink est le seul qui reste lisible dans les
       deux thèmes : en mode nuit le violet s'éclaircit et l'encre fonce. */
    background:var(--violet);color:var(--actif-ink);
  }
  /* Gris pointillé : AniList n'a pas fourni d'image (ou la synchro n'est pas
     passée). Rouge pointillé : l'URL existe mais le navigateur ne l'atteint
     pas — problème de réseau, pas de données. */
  .vignette.vide{border:1px dashed var(--line);background:var(--paper)}
  .vignette.echec{
    border:1px dashed #8A2E2E;background:#FBEFEF;
    object-fit:contain;
  }

  .statuts .galbtn{
    margin-left:auto;color:var(--violet);
    background:var(--violet-soft);border-color:transparent;
  }
  .statuts .galbtn:hover{background:var(--violet);color:#fff}

  .syncbtns{display:flex;gap:8px;align-items:center;flex:none}
  .btn-resume{
    background:var(--card);color:var(--violet);border:1px solid var(--violet-soft);
    border-radius:999px;padding:9px 15px;cursor:pointer;flex:none;
    font-family:'Public Sans',system-ui,sans-serif;font-size:13.5px;font-weight:600;
    letter-spacing:0;text-transform:none;
  }
  .btn-resume:hover{background:var(--violet-soft)}

  /* ---------- fenêtre d'options de synchronisation ---------- */
  .dialsync{
    padding:16px 18px;overflow:auto;
    font-family:'Public Sans',system-ui,sans-serif;font-size:14px;color:var(--ink);
  }
  .dialsync fieldset{
    border:1px solid var(--line);border-radius:10px;padding:12px 14px;margin:0 0 14px;
  }
  .dialsync legend{
    font-family:'IBM Plex Mono',ui-monospace,monospace;font-size:10.5px;
    letter-spacing:.1em;text-transform:uppercase;color:var(--muted);padding:0 6px;
  }
  .dialsync label{display:flex;align-items:center;gap:8px;margin:6px 0;cursor:pointer}
  .dialsync .aide{margin:0 0 10px;color:var(--muted);font-size:12.5px}

  .dialsync .raccourcis{display:flex;gap:8px;flex-wrap:wrap;margin-bottom:10px}
  .dialsync .raccourcis button{
    border:1px solid var(--line);background:var(--card);border-radius:999px;cursor:pointer;
    padding:5px 12px;font-family:'Public Sans',system-ui,sans-serif;font-size:12.5px;
    font-weight:600;color:var(--muted);
  }
  .dialsync .raccourcis button:hover{border-color:var(--violet);color:var(--violet)}

  /* Les années tiennent sur une grille : 17 cases alignées restent lisibles. */
  .dialsync .annees{
    display:grid;gap:2px 10px;
    grid-template-columns:repeat(auto-fill,minmax(84px,1fr));
  }
  .dialsync .annees label{
    margin:0;font-family:'IBM Plex Mono',ui-monospace,monospace;font-size:13px;
  }

  .dialsync .curseur{display:flex;align-items:center;gap:10px;flex-wrap:wrap}
  .dialsync .curseur input[type=range]{flex:1;min-width:140px;accent-color:var(--violet)}
  .dialsync .curseur output{
    font-family:'IBM Plex Mono',ui-monospace,monospace;font-weight:600;color:var(--violet);
  }

  .dialsync .estim{
    margin:0 0 14px;padding:9px 12px;background:var(--violet-soft);border-radius:9px;
    font-family:'IBM Plex Mono',ui-monospace,monospace;font-size:12px;color:var(--violet);
  }
  .dialsync .actions{display:flex;justify-content:flex-end;gap:8px}
  .dialsync .actions button{
    border-radius:999px;padding:10px 18px;cursor:pointer;
    font-family:'Public Sans',system-ui,sans-serif;font-size:14px;font-weight:600;
  }
  .dialsync .annuler{border:1px solid var(--line);background:var(--card);color:var(--muted)}
  .dialsync .annuler:hover{color:var(--ink)}
  .dialsync .lancer{border:0;background:var(--violet);color:#fff}
  .dialsync .lancer:hover{filter:brightness(1.15)}

  /* ---------- resume de synchronisation ---------- */
  .resume{
    padding:16px 18px;overflow:auto;color:var(--ink);
    font-family:'Public Sans',system-ui,sans-serif;font-size:14px;line-height:1.55;
  }
  .resume h4{
    font-family:'Bricolage Grotesque','Trebuchet MS',system-ui,sans-serif;
    font-size:15px;margin:18px 0 6px;
  }
  .resume h4 em{font-style:normal;color:var(--muted);font-weight:500}
  .resume ul{margin:0;padding-left:20px}
  .resume li{margin-bottom:5px}
  .resume li em{font-style:normal;color:var(--gold)}
  .resume .chapeau{margin:0 0 6px;color:var(--muted);font-size:13px}
  .resume .rien{margin:8px 0 0;color:var(--muted)}

  /* ---------- galerie ---------- */
  .galerie{
    position:fixed;inset:0;z-index:50;display:grid;place-items:center;
    background:rgba(30,26,43,.72);padding:20px;
    /* 100dvh et non la hauteur héritée de inset:0 : sur téléphone la barre
       d'adresse rogne le bas de l'écran, et le bouton de fermeture passait
       sous elle. Les navigateurs qui ignorent dvh gardent inset:0. */
    height:100dvh;
  }
  .galbox{
    background:var(--card);border-radius:var(--radius);width:100%;max-width:1100px;
    /* Bornée par la zone disponible plutôt que par 86vh seul : sinon la
       fenêtre dépasse le cadre et déborde de l'écran. */
    max-height:min(86vh,100%);
    display:flex;flex-direction:column;overflow:hidden;
  }
  .galtop{
    display:flex;align-items:center;justify-content:space-between;gap:12px;
    padding:13px 16px;border-bottom:1px solid var(--line);
    font-family:'Bricolage Grotesque','Trebuchet MS',system-ui,sans-serif;font-size:17px;
  }
  .galtop strong{min-width:0;overflow-wrap:break-word}
  .galclose{
    border:0;background:none;font-size:26px;line-height:1;cursor:pointer;
    color:var(--muted);flex:none;border-radius:999px;
    /* Cible tactile confortable : 4 px de rembourrage se ratent au doigt. */
    width:40px;height:40px;display:grid;place-items:center;padding:0;
  }
  .galclose:hover{color:var(--ink);background:var(--violet-soft)}
  .galgrid{
    display:grid;gap:10px;padding:16px;overflow:auto;
    grid-template-columns:repeat(auto-fill,minmax(210px,1fr));
  }
  /* Le geste de défilement reste dans la modale au lieu d'entraîner la page. */
  .galgrid,.resume,.usersbox,.dialsync{overscroll-behavior:contain}

  /* Page figée tant qu'une modale est ouverte : sans cela le doigt fait
     glisser le fond et la fenêtre, en position fixe, part de travers. */
  body.modale-ouverte{overflow:hidden}
  html:has(body.modale-ouverte){overflow:hidden}
  .galgrid img{
    width:100%;aspect-ratio:2/3;object-fit:cover;border-radius:10px;
    background:var(--violet-soft);display:block;
  }

  /* ---------- tier list ---------- */

  .tierbox{
    padding:14px 16px 18px;overflow:auto;overscroll-behavior:contain;
    color:var(--ink);font-family:'Public Sans',system-ui,sans-serif;font-size:14px;
  }
  .tierbox .tier-aide,.tierbox .tier-rien{margin:0;color:var(--muted);font-size:13px}
  /* La consigne et l'export sur une même ligne, l'export poussé à droite.
     `align-items:center` plutôt que `baseline` : le bouton et une consigne
     qui passe sur deux lignes n'ont pas de ligne de base commune. */
  .tier-barre{
    display:flex;align-items:center;justify-content:space-between;gap:12px;
    flex-wrap:wrap;margin-bottom:12px;
  }
  .tier-export{
    flex:none;cursor:pointer;border-radius:999px;padding:7px 14px;
    background:none;border:1px solid var(--violet);color:var(--violet);
    font-family:'Public Sans',system-ui,sans-serif;font-size:13px;font-weight:600;
  }
  .tier-export:hover:not(:disabled){background:var(--violet-soft)}
  /* Rien à classer, rien à exporter : le bouton reste en place — le faire
     disparaître donnerait l'impression que l'export n'existe pas. */
  .tier-export:disabled{border-color:var(--line);color:var(--muted);cursor:not-allowed}

  .tier-lignes{display:grid;gap:8px}
  /* Étiquette à largeur fixe et zone élastique : les cinq rangs s'alignent
     quel qu'en soit le remplissage, ce qui est tout l'intérêt d'une tier
     list — on compare des longueurs de rangée d'un coup d'œil. */
  .tier-ligne{
    display:grid;grid-template-columns:64px minmax(0,1fr);gap:8px;align-items:stretch;
    border:2px solid transparent;border-radius:12px;
    /* Le rang entier est une cible de dépôt : on vise la bande, pas l'espace
       entre deux jaquettes. */
    cursor:pointer;
  }
  /* Survol pendant un glisser : le liseré dit où la tuile va atterrir. */
  .tier-ligne.survol{border-color:var(--violet)}

  .tier-lab{
    display:grid;place-content:center;gap:2px;justify-items:center;
    border-radius:10px;padding:8px 4px;background:var(--violet-soft);color:var(--ink);
    font-family:'Bricolage Grotesque','Trebuchet MS',system-ui,sans-serif;
    font-weight:800;font-size:26px;line-height:1;text-align:center;
    /* Le rang garde sa hauteur même vide : une rangée qui disparaît quand on
       la vide donne l'impression d'avoir perdu le palier. */
    min-height:74px;
    /* Hérité par le libellé : dans une colonne de 64 px, « classés » ne doit
       pas déborder sur la zone de dépôt. */
    overflow-wrap:anywhere;
  }
  .tier-lab .tier-nb{
    font-family:'IBM Plex Mono',ui-monospace,'SFMono-Regular',Menlo,monospace;
    font-size:11px;font-weight:600;opacity:.75;
  }
  .t-S{background:var(--t-S);color:var(--tier-ink)}
  .t-A{background:var(--t-A);color:var(--tier-ink)}
  .t-B{background:var(--t-B);color:var(--tier-ink)}
  .t-C{background:var(--t-C);color:var(--tier-ink)}
  .t-D{background:var(--t-D);color:var(--tier-ink)}
  /* Le bac des titres pas encore jugés n'est pas un palier : ni couleur de
     rang, ni grosse lettre — il ne doit pas se lire comme un « E ». */
  .tier-ligne.bac{margin-top:6px}
  .tier-ligne.bac .tier-lab{
    font-size:12px;font-weight:600;line-height:1.25;
    font-family:'Public Sans',system-ui,sans-serif;color:var(--muted);
    background:none;border:1px dashed var(--line);
  }

  .tier-zone{
    display:flex;flex-wrap:wrap;gap:6px;align-content:flex-start;
    background:var(--det-bg);border-radius:10px;padding:6px;min-height:74px;
  }
  .tier-tuile{
    display:grid;gap:3px;justify-items:center;width:60px;padding:0;
    border:2px solid transparent;border-radius:8px;background:none;
    cursor:grab;color:var(--ink);font-family:inherit;
  }
  .tier-tuile:active{cursor:grabbing}
  .tier-tuile img,.tier-tuile .tier-jaq-vide{
    width:56px;height:80px;object-fit:cover;border-radius:6px;
    background:var(--violet-soft);display:block;
  }
  .tier-titre{
    font-size:10px;line-height:1.2;color:var(--muted);text-align:center;
    /* Deux lignes puis coupe : les titres longs sont fréquents, et une tuile
       qui grandit avec son titre casse l'alignement de la rangée. Le titre
       entier reste dans l'infobulle. */
    display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;
    overflow:hidden;overflow-wrap:anywhere;
  }
  .tier-tuile:hover{border-color:var(--violet-soft)}
  /* Tuile en attente de destination (chemin tactile) : elle doit rester
     repérable après le défilement vers un autre rang, d'où le fond plein en
     plus du liseré. */
  .tier-tuile[aria-pressed="true"]{border-color:var(--violet);background:var(--violet-soft)}
  .tier-tuile[aria-pressed="true"] .tier-titre{color:var(--violet)}
  /* Pendant le glisser : l'original s'efface, l'aperçu suit le pointeur. */
  .tier-tuile.porte{opacity:.4}

  .title h3{
    font-family:'Bricolage Grotesque','Trebuchet MS',system-ui,sans-serif;font-weight:700;font-size:17px;
    letter-spacing:-.01em;margin:0 0 2px;line-height:1.2;
    /* Un titre d'un seul tenant, sans espace, ne doit pas pouvoir élargir
       la fiche au-delà de l'écran. */
    overflow-wrap:break-word;
  }
  .tag{
    font-family:'IBM Plex Mono',ui-monospace,'SFMono-Regular',Menlo,monospace;font-size:10.5px;font-weight:600;
    background:var(--violet-soft);color:var(--violet);border-radius:5px;padding:2px 6px;
    /* margin-left réduit à 2px : le gabarit pose désormais une vraie espace
       avant chaque pastille (voir pastilles() dans app.js), qui fournit le
       point de coupure manquant et occupe déjà quelques pixels. */
    vertical-align:middle;margin-left:2px;letter-spacing:.03em;
    white-space:nowrap;
  }
  .tag.film{
    background:var(--chip-film-bg);color:var(--gold);
    box-shadow:inset 0 0 0 1px rgba(185,130,10,.35);
  }
  .row.withfilms{border-left:3px solid var(--gold)}
  details{margin-top:7px}
  summary{
    display:inline-flex;align-items:center;gap:5px;cursor:pointer;list-style:none;
    font-family:'IBM Plex Mono',ui-monospace,'SFMono-Regular',Menlo,monospace;font-size:11px;letter-spacing:.06em;
    text-transform:uppercase;color:var(--violet);padding:2px 0;
  }
  summary::-webkit-details-marker{display:none}
  summary::before{content:"+";font-size:13px;line-height:1}
  details[open] summary::before{content:"−"}
  .det{
    margin-top:6px;padding:10px 12px;background:var(--det-bg);border-radius:10px;
    font-size:13.5px;line-height:1.55;color:var(--det-ink);
    /* Filet de sécurité : un titre alternatif ou un lien sans espace ne doit
       pas pouvoir pousser la fiche hors de l'écran. */
    min-width:0;overflow-wrap:break-word;
  }
  .det p{margin:0}
  /* En pile sous 900 px : les paquets se comportent comme de simples blocs
     et gardent les marges internes d'origine. Le passage en colonnes se
     fait dans la requête « grand écran ». */
  .det-bloc{min-width:0}

  /* ---------- panneau de détails ---------- */
  .det h5{
    font-family:'IBM Plex Mono',ui-monospace,monospace;font-size:10px;letter-spacing:.12em;
    text-transform:uppercase;color:var(--muted);margin:16px 0 8px;font-weight:600;
  }
  .fiche{display:grid;grid-template-columns:auto minmax(0,1fr);gap:4px 12px;margin:12px 0 0}
  .fiche dt{
    font-family:'IBM Plex Mono',ui-monospace,monospace;font-size:10px;letter-spacing:.1em;
    text-transform:uppercase;color:var(--muted);padding-top:2px;
  }
  .fiche dd{margin:0}
  .fiche a{color:var(--violet)}
  .fiche .muted{color:var(--muted);font-size:12px}

  /* Bande-annonce : vignette 16/9 avec pictogramme de lecture superposé. */
  .bande{
    position:relative;display:block;margin-top:14px;width:100%;max-width:320px;
    border-radius:10px;overflow:hidden;text-decoration:none;
    background:var(--violet-soft);
  }
  .bande img,.bande .sans{display:block;width:100%;aspect-ratio:16/9;object-fit:cover}
  .bande .jouer{
    position:absolute;inset:0;display:grid;place-items:center;
    color:#fff;font-size:34px;text-shadow:0 2px 12px rgba(0,0,0,.6);
    background:linear-gradient(transparent 35%,rgba(0,0,0,.45));
  }
  .bande .txt{
    position:absolute;left:10px;bottom:8px;color:#fff;font-size:12.5px;font-weight:600;
    text-shadow:0 1px 6px rgba(0,0,0,.8);
  }
  .bande:hover .jouer{background:linear-gradient(transparent 20%,rgba(0,0,0,.6))}

  .tags{display:flex;flex-wrap:wrap;gap:5px;margin-top:12px}
  .etq{
    background:var(--card);border:1px solid var(--line);border-radius:999px;
    padding:3px 9px;font-size:11.5px;color:var(--muted);cursor:help;
  }

  /* Histogramme des notes : des barres en flux, aucune bibliothèque. */
  .histo{
    display:flex;align-items:flex-end;gap:3px;height:56px;margin-top:16px;
    padding-top:4px;
  }
  .histo span{flex:1;display:flex;flex-direction:column;justify-content:flex-end;height:100%;gap:3px}
  .histo i{display:block;background:var(--violet-soft);border-radius:3px 3px 0 0;min-height:2px}
  .histo span:nth-child(n+8) i{background:var(--violet)}
  .histo b{
    font-family:'IBM Plex Mono',ui-monospace,monospace;font-size:9px;font-weight:500;
    color:var(--muted);text-align:center;
  }
  .histo-note{margin:4px 0 0!important;font-size:11px;color:var(--muted)}

  .recos{display:flex;gap:10px;overflow-x:auto;padding-bottom:4px}
  .reco{
    flex:none;width:84px;text-decoration:none;color:var(--ink);
    display:flex;flex-direction:column;gap:5px;
  }
  .reco img,.reco .vide{
    width:84px;height:120px;object-fit:cover;border-radius:8px;
    background:var(--violet-soft);display:block;
  }
  .reco span{font-size:11.5px;line-height:1.3}
  .reco:hover span{color:var(--violet)}
  .filmnote{margin-top:8px!important;padding-top:8px;border-top:1px solid var(--line);color:var(--gold)}
  .syn{margin:4px 0 0;color:var(--muted);font-size:13.5px;line-height:1.45}

  .cell{grid-column:2/3;display:flex;gap:8px;align-items:baseline;font-size:13.5px;margin-top:6px}
  .k{
    font-family:'IBM Plex Mono',ui-monospace,'SFMono-Regular',Menlo,monospace;font-size:10.5px;letter-spacing:.1em;text-transform:uppercase;
    color:var(--muted);flex:none;min-width:78px;
  }
  .v{font-weight:500}
  .plat{font-size:13px;line-height:1.35}

  /* Un terme par ligne sur grand écran : les colonnes Style et Plateforme
     sont étroites et coupaient les termes en plein milieu. La hauteur ne
     coûte rien, la cellule du titre étant toujours la plus haute. */
  .liste span{display:block}
  .v em{font-style:normal;color:var(--muted);font-family:'IBM Plex Mono',ui-monospace,'SFMono-Regular',Menlo,monospace;font-size:12.5px}
  .num{font-family:'IBM Plex Mono',ui-monospace,'SFMono-Regular',Menlo,monospace;font-weight:600}

  /* note : 5 crans, remplissage proportionnel */
  .rate{display:flex;align-items:center;gap:8px}
  /* Dix crans depuis le passage de la note sur 10. Le fond et le remplissage
     partagent le même masque, les segments restent donc alignés. */
  .bars{
    position:relative;width:70px;height:11px;background:var(--violet-soft);
    -webkit-mask:repeating-linear-gradient(90deg,#000 0 5px,transparent 5px 7px);
    mask:repeating-linear-gradient(90deg,#000 0 5px,transparent 5px 7px);
  }
  .bars b{position:absolute;inset:0 auto 0 0;height:100%;background:var(--gold)}
  .rate .num{color:var(--ink)}

  .nojs{
    background:var(--chip-film-bg);border:1px solid rgba(185,130,10,.35);color:#6B4B00;
    border-radius:var(--radius);padding:12px 14px;margin:0 0 14px;font-size:13.5px;
  }
  .empty{
    background:var(--card);border:1px dashed var(--line);border-radius:var(--radius);
    padding:30px 20px;text-align:center;color:var(--muted);
  }
  .empty strong{display:block;color:var(--ink);font-family:'Bricolage Grotesque','Trebuchet MS',system-ui,sans-serif;margin-bottom:4px}

  footer{margin-top:22px;color:var(--muted);font-size:12.5px;line-height:1.6}
  footer code{font-family:'IBM Plex Mono',ui-monospace,'SFMono-Regular',Menlo,monospace;font-size:12px}

  /* ---------- vue tableau sur grand écran ---------- */
  @media (min-width:900px){
    .head{
      display:grid;grid-template-columns:70px minmax(0,2fr) minmax(0,.8fr) minmax(0,1fr) minmax(0,1fr) 108px 62px;
      gap:14px;padding:0 16px 8px;align-items:end;
    }
    .head button{
      background:none;border:0;padding:0;cursor:pointer;text-align:left;
      font-family:'IBM Plex Mono',ui-monospace,'SFMono-Regular',Menlo,monospace;font-size:10.5px;letter-spacing:.1em;
      text-transform:uppercase;color:var(--muted);
    }
    .head button[data-active="1"]{color:var(--violet)}
    .row{
      grid-template-columns:70px minmax(0,2fr) minmax(0,.8fr) minmax(0,1fr) minmax(0,1fr) 108px 62px;
      gap:14px;align-items:start;padding:16px;margin-bottom:8px;
    }
    /* Sur grand écran le panneau part sous le titre et court jusqu'au bord
       droit : les colonnes Style, Plateforme, Note… sont vides sous la
       première ligne, autant s'en servir. */
    .row > details{grid-column:2/-1;margin-top:0}

    /* Le contenu se range en colonnes plutôt qu'en un long ruban : récit à
       gauche, fiche technique au milieu, chiffres à droite, et les
       recommandations sur toute la largeur en bas. auto-fit décide du
       nombre de colonnes selon la place, et ne laisse pas de trou quand
       une série n'a ni tags, ni notes, ni synopsis. */
    .det-grid{
      display:grid;align-items:start;gap:4px 26px;
      grid-template-columns:repeat(auto-fit,minmax(250px,1fr));
    }
    /* La première marge haute de chaque colonne ferait décrocher les
       colonnes voisines les unes des autres. */
    .det-recit > :first-child,
    .det-fiche > :first-child,
    .det-chiffres > :first-child{margin-top:0}
    .det-recos{grid-column:1/-1;margin-top:6px}
    .cell{grid-column:auto;display:block;margin-top:0;font-size:13.5px}
    .k{display:none}
    .sortable-mobile{display:none}
  }
  @media (prefers-reduced-motion:reduce){*{transition:none!important;animation:none!important}}

  /* ---------- ajustements sous 900 px ---------- */
  @media (max-width:899px){
    .wrap{padding:16px 12px 60px}

    /* Sept éléments dans la barre du haut — titre, trois raccourcis, la tier
       list, deux menus : sur 360 px il faut resserrer, sinon chacun prend
       sa ligne. */
    .who{gap:6px}
    .btn-vue{padding:6px 11px;font-size:12.5px;gap:6px}
    .btn-menu,.btn-tier{padding:6px 12px;font-size:12.5px}

    /* Tier list au doigt : l'étiquette se resserre et les jaquettes
       rétrécissent, pour garder au moins quatre tuiles par rangée sur
       360 px — en dessous, comparer deux rangs n'a plus de sens. */
    .tierbox{padding:12px}
    .tier-ligne{grid-template-columns:46px minmax(0,1fr);gap:6px}
    .tier-lab{font-size:21px;min-height:64px;padding:6px 2px}
    .tier-ligne.bac .tier-lab{font-size:10.5px}
    .tier-zone{min-height:64px;gap:5px;padding:5px}
    .tier-tuile{width:52px}
    .tier-tuile img,.tier-tuile .tier-jaq-vide{width:48px;height:69px}

    /* Le compteur s'affichait en corps de titre et occupait trois lignes. */
    .progress-count{font-size:13.5px;font-weight:600;line-height:1.45}
    .progress-count b{font-size:17px}
    .progress-top{align-items:flex-start;gap:10px}
    .reset{white-space:nowrap;font-size:10px}

    /* C'est cette ligne qui débordait horizontalement : le texte et les deux
       boutons ne tenaient pas côte à côte, et rien ne les autorisait à
       passer à la ligne. */
    .syncline{flex-direction:column;align-items:stretch;gap:9px}
    .syncbtns{width:100%;flex-wrap:wrap}
    .syncbtns .btn-sync,.syncbtns .btn-resume{flex:1 1 auto;justify-content:center;text-align:center}

    /* Six contrôles empilés repoussaient la liste hors de l'écran. */
    .controls{gap:6px}
    .controls .field{flex:1 1 100%}
    .controls select.pill{flex:1 1 calc(50% - 3px);min-width:0}
    .controls button.sens{flex:1 1 calc(50% - 3px);justify-content:center}
    .controls .seg{flex:1 1 100%;justify-content:center}
    .controls button.coche{flex:1 1 100%;justify-content:center}

    /* Fiches plus denses : la moitié de la hauteur venait des marges. */
    .row{padding:12px;gap:3px 10px}
    .vignette{width:76px;height:110px}
    .title h3{font-size:16px}
    .syn{font-size:13px}
    .cell{margin-top:4px;font-size:13px;gap:6px}
    .k{min-width:62px;font-size:9.5px;letter-spacing:.07em}
    /* Quatre statuts, le bouton Images et les trois labels tenaient sur
       trois rangées de pastilles. En resserrant, les quatre statuts tiennent
       sur une ligne et il n'en reste que deux. */
    .statuts{gap:4px}
    .statuts button{padding:4px 10px;font-size:12px}
    /* Sur mobile, coller « Images » à droite créait un vide disgracieux. */
    .statuts .galbtn{margin-left:0}
    .priorites button{padding:3px 9px;font-size:9.5px;letter-spacing:.04em}

    /* En pile, chaque ligne supplémentaire allonge vraiment la fiche : les
       termes coulent les uns après les autres, séparés par un point médian.

       Ils étaient en white-space:nowrap pour ne pas être coupés en deux,
       mais un terme plus large que la colonne — « Science-Fiction &
       Fantastique », « Animation Digital Network » — n'avait alors plus
       aucun point de coupure et débordait du cadre. On rend donc la
       coupure possible : aux espaces d'abord, à l'intérieur d'un mot
       seulement s'il est à lui seul trop long. */
    .liste span{display:inline;white-space:normal}
    .liste{overflow-wrap:break-word}
    .liste span + span::before{content:" · ";color:var(--muted)}

    /* .v est une case de flexbox : sans min-width:0 elle refuse de descendre
       sous la largeur de son plus long contenu et repousse le texte hors de
       la fiche, quel que soit le réglage de coupure ci-dessus. */
    .cell .v{min-width:0}

    /* Le panneau de détails repasse sous la jaquette, sur toute la largeur :
       il gagne les 86 px que lui prenait la colonne de l'image. */
    .row > details{margin-top:10px}
    .det{padding:12px;font-size:13.5px}
    .det h5{margin-top:14px}
    .recos{gap:8px}

    /* Modales en plein écran : centrer une boîte flottante dans un écran de
       téléphone laissait la barre de titre — et sa croix — hors de portée. */
    .galerie{padding:0;place-items:stretch}
    .galbox{max-width:none;max-height:none;height:100%;border-radius:0}
    .galtop{
      position:sticky;top:0;z-index:1;background:var(--card);
      padding:8px 8px 8px 14px;font-size:15px;
    }
    .galgrid{
      padding:12px;gap:8px;
      grid-template-columns:repeat(auto-fill,minmax(120px,1fr));
    }
    .resume,.usersbox,.dialsync{padding:14px}

    /* Filet : plus rien ne peut provoquer de défilement horizontal. */
    body{overflow-x:hidden}
  }

  /* Sur les écrans les plus étroits, les intitulés de la fiche mangent la
     moitié de la largeur : on les passe au-dessus de leur valeur. */
  @media (max-width:560px){
    .fiche{grid-template-columns:minmax(0,1fr);gap:0}
    .fiche dt{margin-top:9px}
    .fiche dt:first-child{margin-top:0}
  }

  /* ---------- écran de connexion ---------- */
  .login{
    position:fixed;inset:0;display:grid;place-items:center;padding:24px;
    background:var(--paper);z-index:10;
  }
  .login-box{
    width:100%;max-width:340px;background:var(--card);border:1px solid var(--line);
    border-radius:var(--radius);padding:24px;
  }
  .login-box h1{font-size:26px;margin-bottom:18px}
  .lfield{display:block;margin-bottom:14px}
  .lfield span{
    display:block;font-family:'IBM Plex Mono',ui-monospace,'SFMono-Regular',Menlo,monospace;font-size:10.5px;letter-spacing:.1em;
    text-transform:uppercase;color:var(--muted);margin-bottom:5px;
  }
  .lfield input{
    width:100%;padding:11px 13px;border:1px solid var(--line);border-radius:10px;
    background:var(--paper);font-family:'Public Sans',system-ui,sans-serif;font-size:15px;color:var(--ink);
  }
  .lbtn{
    width:100%;padding:12px;border:0;border-radius:10px;background:var(--actif-bg);color:var(--actif-ink);
    font-family:'Public Sans',system-ui,sans-serif;font-size:15px;font-weight:600;cursor:pointer;
  }
  .lbtn:hover{background:var(--violet)}
  .lerr{color:var(--erreur);font-size:13.5px;margin:0 0 12px}

  /* ---------- barre du haut ---------- */
  .topbar{display:flex;justify-content:space-between;align-items:center;gap:12px;flex-wrap:wrap;margin-bottom:10px}
  .who{display:flex;align-items:center;gap:8px;flex-wrap:wrap}

  /* Les seuls boutons pleins de la barre du haut : ce sont les actions qu'on
     vient chercher, les deux autres éléments ouvrent des menus. */
  .btn-vue{
    display:inline-flex;align-items:center;gap:7px;cursor:pointer;
    background:var(--violet);border:1px solid var(--violet);border-radius:999px;
    padding:7px 14px;font-family:'Public Sans',system-ui,sans-serif;
    font-size:13.5px;font-weight:600;
    /* Le couple violet / actif-ink est le seul lisible dans les deux thèmes :
       en mode nuit le violet s'éclaircit et l'encre fonce. Du blanc en dur
       serait illisible la nuit. */
    color:var(--actif-ink);
  }
  .btn-vue:hover{filter:brightness(1.12)}
  /* Le compteur reprend la couleur des cartes : pastille claire sur bouton
     violet le jour, sombre la nuit, lisible dans les deux cas. */
  .vue-nb{
    background:var(--card);color:var(--violet);border-radius:999px;padding:1px 7px;
    font-family:'IBM Plex Mono',ui-monospace,'SFMono-Regular',Menlo,monospace;
    font-size:11.5px;font-weight:600;
  }
  /* Ni pastille vide avant le chargement, ni « 0 » sur une liste vide. */
  .vue-nb:empty{display:none}
  /* Vue déjà affichée : un liseré, sans changer la couleur du bouton. */
  .btn-vue[data-actif="1"]{box-shadow:0 0 0 2px var(--violet-soft)}

  /* Ouvre un panneau au lieu de changer la vue : creux comme les menus, mais
     cerclé de violet — c'est une destination, pas un tiroir de réglages. */
  .btn-tier{
    display:inline-flex;align-items:center;cursor:pointer;
    background:none;border:1px solid var(--violet);border-radius:999px;padding:7px 14px;
    color:var(--violet);font-family:'Public Sans',system-ui,sans-serif;
    font-size:13.5px;font-weight:600;
  }
  .btn-tier:hover{background:var(--violet-soft)}

  /* ---------- menus déroulants de la barre du haut ---------- */
  .menu{position:relative}
  .btn-menu{
    display:inline-flex;align-items:center;gap:7px;cursor:pointer;
    background:none;border:1px solid var(--line);border-radius:999px;padding:7px 14px;
    color:var(--ink);font-family:'Public Sans',system-ui,sans-serif;
    font-size:13.5px;font-weight:600;
  }
  .btn-menu::after{content:"▾";color:var(--muted);font-size:11px;line-height:1}
  .btn-menu:hover{border-color:var(--violet)}
  .btn-menu[aria-expanded="true"]{border-color:var(--violet);color:var(--violet)}
  .menu-panneau{
    position:absolute;right:0;top:calc(100% + 6px);z-index:30;min-width:190px;
    background:var(--card);border:1px solid var(--line);border-radius:12px;padding:5px;
    box-shadow:0 12px 30px rgba(0,0,0,.18);
  }
  .menu-panneau button{
    display:block;width:100%;text-align:left;border:0;background:none;cursor:pointer;
    padding:9px 12px;border-radius:8px;color:var(--ink);
    font-family:'Public Sans',system-ui,sans-serif;font-size:13.5px;
  }
  .menu-panneau button:hover{background:var(--violet-soft);color:var(--violet)}

  /* ---------- panneau des comptes ---------- */
  .usersbox{
    padding:16px 18px;overflow:auto;color:var(--ink);
    font-family:'Public Sans',system-ui,sans-serif;font-size:14px;
  }
  .tusers{width:100%;border-collapse:collapse;margin-bottom:6px}
  .tusers th{
    text-align:left;padding:0 10px 7px 0;color:var(--muted);font-weight:600;
    font-family:'IBM Plex Mono',ui-monospace,monospace;font-size:10.5px;
    letter-spacing:.1em;text-transform:uppercase;
  }
  .tusers td{padding:8px 10px 8px 0;border-top:1px solid var(--line);vertical-align:middle}
  .tusers .mono{font-family:'IBM Plex Mono',ui-monospace,monospace;font-weight:600}
  .tusers .actes{display:flex;gap:6px;flex-wrap:wrap;justify-content:flex-end}
  .tusers .actes button{
    border:1px solid var(--line);background:var(--card);border-radius:999px;cursor:pointer;
    padding:4px 11px;font-family:'Public Sans',system-ui,sans-serif;font-size:12px;
    font-weight:600;color:var(--muted);
  }
  .tusers .actes button:hover{border-color:var(--violet);color:var(--violet)}
  .tusers .actes .danger:hover{border-color:var(--erreur);color:var(--erreur)}

  .usersbox h4{
    font-family:'Bricolage Grotesque','Trebuchet MS',system-ui,sans-serif;
    font-size:15px;margin:20px 0 8px;
  }
  .usersbox .ajout{display:flex;flex-wrap:wrap;gap:8px;align-items:center}
  .usersbox .ajout input[type=text],
  .usersbox .ajout input[type=password],
  .usersbox .ajout input:not([type]){
    flex:1;min-width:130px;padding:9px 12px;border:1px solid var(--line);border-radius:9px;
    background:var(--paper);color:var(--ink);
    font-family:'Public Sans',system-ui,sans-serif;font-size:13.5px;
  }
  .usersbox .ajout label{display:flex;align-items:center;gap:7px;color:var(--muted);font-size:13px}
  .usersbox .ajout #nAjouter{
    border:0;background:var(--violet);color:#fff;border-radius:999px;cursor:pointer;
    padding:9px 18px;font-family:'Public Sans',system-ui,sans-serif;font-size:13.5px;font-weight:600;
  }
  .usersbox .ajout #nAjouter:hover{filter:brightness(1.15)}
  .usersbox .msg{margin:12px 0 0;color:var(--muted);font-size:13px;min-height:1.2em}
  .usersbox .msg.erreur{color:var(--erreur)}
  /* .chapeau et .rien n'existaient que sous .resume : le panneau des
     doublons réutilise le gabarit .usersbox, il lui faut les mêmes. */
  .usersbox .chapeau{margin:0 0 14px;color:var(--muted);font-size:13px;line-height:1.5}
  .usersbox .chapeau em{font-style:normal;color:var(--ink);font-weight:600}
  .usersbox .rien{margin:0;color:var(--muted)}
  .usersbox h4{
    font-family:'Bricolage Grotesque','Trebuchet MS',system-ui,sans-serif;
    font-size:15px;margin:20px 0 8px;
  }
  .usersbox h4 em{font-style:normal;color:var(--muted);font-weight:500}

  /* ---------- doublons TMDB ---------- */
  .dbl{
    border:1px solid var(--line);border-radius:10px;padding:10px 12px;margin-bottom:8px;
    background:var(--det-bg);
  }
  .dbl-tete{display:flex;align-items:center;justify-content:space-between;gap:12px;flex-wrap:wrap}
  .dbl .mono{font-family:'IBM Plex Mono',ui-monospace,monospace;font-size:13px;overflow-wrap:anywhere}
  .dbl-actes{display:flex;gap:6px;flex-wrap:wrap}
  .dbl-choix{display:flex;align-items:center;gap:8px;cursor:pointer;min-width:0}
  .dbl-choix input{accent-color:var(--violet);flex:none;width:16px;height:16px}
  /* Une fiche décochée ne participe pas à la fusion : elle s'efface sans
     disparaître, pour qu'on voie ce qu'on a écarté. */
  .dbl:has(input:not(:checked)){opacity:.5}
  .dbl-tete button{
    flex:none;border:1px solid var(--line);background:var(--card);border-radius:999px;cursor:pointer;
    padding:5px 13px;font-family:'Public Sans',system-ui,sans-serif;font-size:12.5px;
    font-weight:600;color:var(--muted);
  }
  /* Deux issues opposées, deux couleurs : réunir est constructif, détacher
     laisse une fiche orpheline le temps d'une synchro. */
  .dbl-tete button[data-act="fusionner"]:hover{border-color:var(--violet);color:var(--violet)}
  .dbl-tete button[data-act="detacher"]:hover{border-color:var(--erreur);color:var(--erreur)}
  .dbl-tete button:disabled{opacity:.5;cursor:progress}
  .usersbox .chapeau code{
    font-family:'IBM Plex Mono',ui-monospace,monospace;font-size:12px;color:var(--ink);
  }
  .dbl .fiche{margin:8px 0 0}
  /* Une saison par ligne : c'est la colonne qu'on lit pour trancher. */
  .dbl-part{display:block}

  /* ---------- statuts par ligne ---------- */
  .statuts{display:flex;flex-wrap:wrap;gap:4px;margin-top:8px}
  .statuts button{
    border:1px solid var(--line);background:var(--card);border-radius:999px;cursor:pointer;
    padding:4px 10px;font-family:'Public Sans',system-ui,sans-serif;font-size:12px;
    font-weight:600;color:var(--muted);
  }
  .statuts button[aria-pressed="true"]{background:var(--violet);border-color:var(--violet);color:var(--actif-ink)}
  .statuts .st-ignore[aria-pressed="true"]{
    background:var(--muted);border-color:var(--muted);color:var(--card);
  }
  /* ---------- degré d'envie (watchlist) ---------- */

  /* Une rangée à part sous les statuts, et non des boutons de plus dans la
     même : ce sont deux questions distinctes — où j'en suis, et à quel point
     j'ai hâte — et les mélanger inviterait à cliquer l'un pour l'autre.

     Un seul contrôle segmenté plutôt que trois pastilles indépendantes : sur
     téléphone, trois bordures et trois écarts de plus donnaient une troisième
     rangée d'objets flottants. Ici l'ensemble se lit comme un objet, et
     occupe une largeur nettement moindre à contenu égal. */
  .priorites{
    display:inline-flex;margin-top:6px;
    background:var(--paper);border:1px solid var(--line);border-radius:999px;padding:2px;
  }
  .priorites button{
    border:0;background:none;border-radius:999px;cursor:pointer;
    padding:3px 10px;font-family:'IBM Plex Mono',ui-monospace,'SFMono-Regular',Menlo,monospace;
    font-size:10px;font-weight:600;letter-spacing:.06em;text-transform:uppercase;
    color:var(--muted);white-space:nowrap;
  }
  .priorites button:hover{color:var(--ink)}

  /* Le code couleur. Il vaut pour le label posé sur une fiche comme pour le
     filtre de la barre de contrôles : même valeur, même teinte, partout. */
  .pr-hype[aria-pressed="true"]{background:var(--hype-bg);color:var(--hype-ink)}
  .pr-soon[aria-pressed="true"]{background:var(--soon-bg);color:var(--soon-ink)}
  .pr-oneday[aria-pressed="true"]{background:var(--oneday-bg);color:var(--oneday-ink)}
  /* Le groupe de filtres est un .seg, dont la règle générique peindrait le
     bouton actif en --actif-bg : il faut la reprendre pour que les trois
     teintes gagnent. */
  .seg-prio button[aria-pressed="true"].pr-hype{background:var(--hype-bg);color:var(--hype-ink)}
  .seg-prio button[aria-pressed="true"].pr-soon{background:var(--soon-bg);color:var(--soon-ink)}
  .seg-prio button[aria-pressed="true"].pr-oneday{background:var(--oneday-bg);color:var(--oneday-ink)}

  .row.ignoree{opacity:.4}
  .row.ignoree .title h3{text-decoration:none}

  .tag.live{background:var(--chip-live-bg);color:var(--chip-live-ink);box-shadow:inset 0 0 0 1px rgba(31,107,59,.25)}
  /* Pas d'offre française : discret, parce que c'est le cas de 4 fiches
     sur 10 — un signal criard sur autant de lignes ne signale plus rien. */
  .tag.vostfr{background:transparent;color:var(--muted);box-shadow:inset 0 0 0 1px var(--line);cursor:help}
  /* Deux fiches pour une même entrée TMDB : là, c'est une anomalie à
     traiter, elle a droit au rouge. */
  .tag.doublon{
    background:transparent;color:var(--erreur);cursor:help;
    box-shadow:inset 0 0 0 1px currentColor;
  }
  .tag.todo{background:#F2EEF9;color:var(--muted);box-shadow:inset 0 0 0 1px var(--line)}
  .tag.doute{background:var(--chip-film-bg);color:var(--gold);box-shadow:inset 0 0 0 1px rgba(185,130,10,.35)}
  .strip span.encours{background:#B9A6F5}

  .syncline{
    display:flex;justify-content:space-between;align-items:center;gap:10px;
    margin:10px 0 0;padding-top:10px;border-top:1px solid var(--line);
    font-family:'IBM Plex Mono',ui-monospace,'SFMono-Regular',Menlo,monospace;font-size:11px;letter-spacing:.04em;color:var(--muted);
  }
