:root{
  --ground:#EEF1EC; --surface:#FFFFFF; --surface-2:#F7F9F6;
  --ink:#1A211C; --muted:#69756D; --line:#D8DED6;
  --accent:#0E6B58; --accent-soft:#DCEBE5; --on-accent:#FFFFFF;
  --malus:#A3432A; --brass:#9A7B1F;
  --b1:#C3CCC5; --b2:#9DB6AB; --b3:#6BA290; --b4:#2E8571; --b5:#0E6B58;
  --shadow:0 1px 2px rgba(26,33,28,.06), 0 8px 24px -12px rgba(26,33,28,.18);
}
@media (prefers-color-scheme: dark){
  :root:not([data-theme="light"]){
    --ground:#11150F; --surface:#181D18; --surface-2:#1F2520;
    --ink:#E6EBE4; --muted:#95A198; --line:#2C332C;
    --accent:#59C3A5; --accent-soft:#1E3830; --on-accent:#0B1410;
    --malus:#E08163; --brass:#D6B75A;
    --b1:#333B35; --b2:#42604F; --b3:#3D8570; --b4:#48AC8F; --b5:#59C3A5;
    --shadow:0 1px 2px rgba(0,0,0,.4), 0 8px 24px -12px rgba(0,0,0,.6);
  }
}
:root[data-theme="dark"]{
  --ground:#11150F; --surface:#181D18; --surface-2:#1F2520;
  --ink:#E6EBE4; --muted:#95A198; --line:#2C332C;
  --accent:#59C3A5; --accent-soft:#1E3830; --on-accent:#0B1410;
  --malus:#E08163; --brass:#D6B75A;
  --b1:#333B35; --b2:#42604F; --b3:#3D8570; --b4:#48AC8F; --b5:#59C3A5;
  --shadow:0 1px 2px rgba(0,0,0,.4), 0 8px 24px -12px rgba(0,0,0,.6);
}
*{box-sizing:border-box}
body{
  background:var(--ground); color:var(--ink);
  font-family:"IBM Plex Sans",system-ui,-apple-system,"Segoe UI",sans-serif;
  font-size:15px; line-height:1.5; margin:0;
}
.wrap{max-width:1180px; margin:0 auto; padding-inline:20px; padding-block:28px 64px}
h1,h2,h3{font-family:"Fraunces","Iowan Old Style",Georgia,serif; margin:0; text-wrap:balance; font-weight:600}
h1{font-size:30px; letter-spacing:-.01em}
h2{font-size:19px}
.lede{color:var(--muted); max-width:62ch; margin:6px 0 0}
header.top{display:flex; flex-wrap:wrap; gap:16px; align-items:flex-end; justify-content:space-between; margin-bottom:26px}
.progress{display:flex; gap:20px; align-items:center}
.pstat{text-align:right}
.pstat b{font-family:"IBM Plex Mono",monospace; font-size:22px; font-weight:500; display:block; line-height:1.1; font-variant-numeric:tabular-nums}
.pstat span{font-size:11px; text-transform:uppercase; letter-spacing:.09em; color:var(--muted)}
.cols{display:grid; grid-template-columns:minmax(0,1.45fr) minmax(0,1fr); gap:22px; align-items:stretch}
@media (max-width:860px){ .cols{grid-template-columns:1fr} }
.card{background:var(--surface); border:1px solid var(--line); border-radius:10px; padding:20px}
.card + .card{margin-top:18px}
.eyebrow{font-size:11px; text-transform:uppercase; letter-spacing:.1em; color:var(--muted); font-weight:600}
.field{display:flex; flex-direction:column; gap:9px}
.field + .field{margin-top:22px}
.fhead{display:flex; align-items:baseline; justify-content:space-between; gap:12px; flex-wrap:wrap}
.fhead h2{font-size:17px}
.hint{font-size:12.5px; color:var(--muted)}
input[type=text],input[type=number],input[type=url],select{
  font:inherit; color:var(--ink); background:var(--surface-2);
  border:1px solid var(--line); border-radius:7px; padding:9px 11px; width:100%;
}
input:focus-visible,select:focus-visible,button:focus-visible{outline:2px solid var(--accent); outline-offset:2px}
.envie{display:flex; flex-direction:column; gap:6px}
.envie button{
  font:inherit; text-align:left; cursor:pointer; background:var(--surface-2);
  border:1px solid var(--line); border-radius:8px; padding:10px 13px; color:var(--ink);
  display:flex; align-items:baseline; justify-content:space-between; gap:14px;
  transition:border-color .12s, background .12s;
}
.envie button:hover{border-color:var(--accent)}
.envie button strong{font-size:14px; font-weight:600; flex:none}
.envie button em{font-style:normal; font-size:12px; color:var(--muted); text-align:right}
@media (max-width:420px){
  .envie button{flex-direction:column; align-items:flex-start; gap:2px}
  .envie button em{text-align:left}
}
.envie button[aria-pressed=true]{background:var(--accent-soft); border-color:var(--accent)}
.envie button[aria-pressed=true] em{color:var(--ink); opacity:.75}
.scale{display:flex; gap:6px}
.scale button{
  flex:1 1 0; min-width:0; font:500 15px "IBM Plex Mono",monospace; cursor:pointer; color:var(--ink);
  background:var(--surface-2); border:1px solid var(--line); border-radius:7px; padding:10px 0;
  transition:border-color .12s, background .12s;
}
.scale button:hover{border-color:var(--accent)}
.scale button[aria-pressed=true]{background:var(--accent); border-color:var(--accent); color:var(--on-accent)}
.nudgewrap{display:flex; flex-direction:column}
.nudge{width:100%; accent-color:var(--accent); margin:0}
.nudgeax{display:flex; justify-content:space-between; font-size:10px; color:var(--muted); font-family:"IBM Plex Mono",monospace; margin-top:1px}
.check{display:flex; gap:9px; align-items:center; cursor:pointer; background:var(--surface-2); border:1px solid var(--line); border-radius:7px; padding:9px 12px; font-size:13.5px}
.check input{accent-color:var(--accent); width:17px; height:17px; margin:0; flex:none}
.check:hover{border-color:var(--accent)}
.check:has(input:checked){background:var(--accent-soft); border-color:var(--accent)}
.suggested{margin:0 0 18px; font-size:13px; color:var(--ink); background:var(--accent-soft);
           border:1px dashed var(--accent); border-radius:7px; padding:9px 12px}
.anchor{
  font-size:13px; color:var(--muted); background:var(--surface-2); border-left:2px solid var(--accent);
  padding:8px 11px; border-radius:0 6px 6px 0; min-height:38px;
}
.anchor b{color:var(--ink); font-weight:600}
.critique{
  margin-top:10px; padding:12px 14px; background:var(--surface-2); border-left:2px solid var(--accent);
  border-radius:0 7px 7px 0; font-size:13.5px; line-height:1.6; white-space:pre-wrap;
}
/* Image + colonnes du catalogue (auteur, année, lien…) — tout ce que la base
   de données connaît sur l'œuvre, affiché sans savoir ce que chaque champ
   représente. */
.entryinfo{display:flex; gap:14px; align-items:flex-start; margin-top:12px}
.entryimg{width:64px; height:64px; object-fit:cover; border-radius:8px; flex:none; background:var(--surface-2)}
.entryimg-placeholder{
  display:flex; align-items:center; justify-content:center; font-size:24px;
  border:1px dashed var(--line);
}
.entrymeta{display:flex; flex-direction:column; gap:5px; flex:1; min-width:0; padding-top:2px}
.metarow{display:flex; justify-content:space-between; align-items:baseline; gap:10px; font-size:13px}
.metarow span{color:var(--muted); flex:none}
.metarow b{font-weight:500; text-align:right; overflow:hidden; text-overflow:ellipsis; white-space:nowrap}
.metarow a{color:var(--accent)}
/* Ajustements : une liste de réglages, libellé à gauche, contrôle et valeur à droite */
.adj{display:flex; flex-direction:column; margin-top:6px}
.adjrow{display:grid; grid-template-columns:minmax(0,1fr) minmax(0,260px); gap:10px 20px;
        align-items:center; padding:15px 0; border-top:1px solid var(--line)}
.adjrow:first-child{border-top:0}
.adjlabel{display:flex; flex-direction:column; gap:3px; min-width:0}
.adjlabel b{font-weight:600; font-size:14.5px}
.adjctl{display:flex; align-items:center; gap:12px; min-width:0}
.adjctl .check span{white-space:nowrap}
.adjctl > .scale, .adjctl > .nudgewrap{flex:1; min-width:0}
.adjctl .check{flex:1}
/* largeur figée : sans ça, la valeur qui passe de « 0 » à « −0,25 » rétrécit le contrôle voisin */
.adjval{font:500 13px "IBM Plex Mono",monospace; font-style:normal; color:var(--muted);
        width:46px; text-align:right; font-variant-numeric:tabular-nums; flex:0 0 46px}
.adjval.on{color:var(--malus)}
.adjval.up{color:var(--accent)}
.adjctl .scale button{font-size:12.5px; font-family:"IBM Plex Sans",sans-serif; padding:8px 4px}
@media (max-width:760px){
  .adjrow{grid-template-columns:1fr}
  .adjctl{margin-top:2px}
}
.scoresticky{position:sticky; top:calc(env(safe-area-inset-top, 0px) + 72px); display:flex; flex-direction:column; gap:12px}
@media (max-width:860px){ .scoresticky{position:static} }
.bignum{display:flex; align-items:baseline; gap:10px; margin:2px 0 4px; flex-wrap:wrap}
.bignum b{font-family:"Fraunces",Georgia,serif; font-size:66px; font-weight:700; line-height:.95; letter-spacing:-.02em; font-variant-numeric:tabular-nums}
.bignum span{color:var(--muted); font-size:15px}
/* Échelle secondaire (Letterboxd…) : un discret repère à côté de la note,
   pas une deuxième grosse note — sans ça elle hérite de `.bignum b`. */
.bignum .lb{
  display:inline-flex; align-items:center; gap:6px; margin-left:2px;
  background:var(--surface-2); border:1px solid var(--line); border-radius:20px; padding:5px 11px 5px 9px;
}
.bignum .lb i{font-style:normal; font-size:12px; color:var(--muted)}
.bignum .lb b{font-family:"IBM Plex Mono",monospace; font-size:13px; font-weight:600; letter-spacing:0; line-height:1; color:var(--ink)}
.qtext{margin:0; font-size:14.5px; line-height:1.45}
.qnote{margin:0}
.opts{display:flex; flex-direction:column; gap:6px}
.opts button{
  font:inherit; font-size:13.5px; text-align:left; cursor:pointer; color:var(--ink);
  background:var(--surface-2); border:1px solid var(--line); border-radius:7px; padding:9px 12px;
  transition:border-color .12s, background .12s;
}
.opts button:hover{border-color:var(--accent)}
.opts button[aria-pressed=true]{background:var(--accent-soft); border-color:var(--accent); font-weight:500}
.contrib{display:flex; flex-direction:column; gap:7px; border-top:1px solid var(--line);
         margin-top:16px; padding-top:14px}
.crow{display:grid; grid-template-columns:104px 1fr 34px; gap:10px; align-items:center; font-size:12.5px}
.crow span:first-child{color:var(--muted)}
.cbar{background:var(--surface-2); border-radius:3px; height:6px; overflow:hidden; display:block}
.cbar i{display:block; height:100%; background:var(--accent); border-radius:3px; transition:width .18s ease}
.crow b{font-family:"IBM Plex Mono",monospace; font-weight:500; text-align:right;
        font-variant-numeric:tabular-nums; color:var(--muted)}
.hint.strong{color:var(--accent); font-weight:500}
.bands{margin:18px 0 6px}
.bandbar{display:flex; height:11px; border-radius:6px; overflow:hidden; border:1px solid var(--line); position:relative}
.bandbar div{height:100%; flex:1 1 0}
.bandbar u{position:absolute; top:0; height:100%; box-shadow:inset 0 0 0 2px var(--ink); border-radius:3px; transition:left .18s ease, width .18s ease}
.histo{display:flex; align-items:flex-end; gap:2px; height:96px; margin-top:6px}
.histo span{flex:1; background:var(--accent); border-radius:4px 4px 0 0; min-height:2px; position:relative}
.histo span.zero{background:var(--line); border-radius:2px}
.histo span.hinge{background:var(--brass)}
.histoax{display:flex; gap:2px; margin-top:6px; font-size:10px; color:var(--muted); font-family:"IBM Plex Mono",monospace}
.histoax span{flex:1; text-align:center}
.histoax span.mark{color:var(--ink); font-weight:500}
.bandlabels{display:flex; margin-top:5px; font-size:10px; color:var(--muted);
            font-family:"IBM Plex Mono",monospace; font-variant-numeric:tabular-nums}
.bandlabels span{flex:1 1 0}
.marker{position:relative; height:16px}
.marker i{
  position:absolute; top:0; width:2px; height:13px; background:var(--ink); border-radius:1px;
  transform:translateX(-1px); transition:left .18s ease;
}
.marker i::after{content:""; position:absolute; top:11px; left:-3px; width:8px; height:8px; background:var(--ink); border-radius:50%}
.breakdown{border-top:1px solid var(--line); margin-top:16px; padding-top:14px; display:flex; flex-direction:column; gap:7px}
.brow{display:flex; justify-content:space-between; font-size:13px; gap:12px}
.brow span{color:var(--muted)}
.brow b{font-family:"IBM Plex Mono",monospace; font-weight:500; font-variant-numeric:tabular-nums}
.brow.neg b{color:var(--malus)}
.actions{display:flex; gap:8px; margin-top:16px}
button.primary{
  font:600 14px "IBM Plex Sans",sans-serif; cursor:pointer; flex:1;
  background:var(--accent); color:var(--on-accent); border:1px solid var(--accent);
  border-radius:7px; padding:11px 14px;
}
button.primary:hover{filter:brightness(1.08)}
button.ghost{
  font:500 14px "IBM Plex Sans",sans-serif; cursor:pointer; color:var(--ink);
  background:transparent; border:1px solid var(--line); border-radius:7px; padding:11px 14px;
}
button.ghost:hover{border-color:var(--accent)}
details{margin-top:18px; border-top:1px solid var(--line); padding-top:14px}
summary{cursor:pointer; font-size:13px; color:var(--muted); font-weight:500}
summary::marker{color:var(--muted)}
.wrow{display:grid; grid-template-columns:150px 1fr 46px; gap:10px; align-items:center; margin-top:11px; font-size:13px}
.wrow input[type=range]{width:100%; accent-color:var(--accent)}
.wrow output{font-family:"IBM Plex Mono",monospace; text-align:right; color:var(--muted); font-variant-numeric:tabular-nums}
table{width:100%; border-collapse:collapse; font-size:13.5px}
th{text-align:left; font-size:10.5px; text-transform:uppercase; letter-spacing:.08em; color:var(--muted); font-weight:600; padding:0 10px 8px; border-bottom:1px solid var(--line)}
.sortbtn{
  font:inherit; text-transform:inherit; letter-spacing:inherit; color:inherit; font-weight:inherit;
  background:none; border:0; padding:0; cursor:pointer; white-space:nowrap;
}
.sortbtn:hover{color:var(--ink)}
td{padding:8px 10px; border-bottom:1px solid var(--line)}
td.num{font-family:"IBM Plex Mono",monospace; font-variant-numeric:tabular-nums; text-align:right}
td.new{font-weight:600}
.tablewrap{overflow-x:auto; margin-top:12px}
.pager{display:flex; align-items:center; justify-content:center; gap:16px; margin-top:14px}
.pager .hint{font-variant-numeric:tabular-nums}
button:disabled{opacity:.4; cursor:default}
button.ghost:disabled:hover{border-color:var(--line)}
tbody tr:hover{background:var(--surface-2); cursor:pointer}
.empty{color:var(--muted); font-size:13.5px; padding:14px 0}
textarea{
  width:100%; font:12px/1.5 "IBM Plex Mono",monospace; color:var(--ink); background:var(--surface-2);
  border:1px solid var(--line); border-radius:7px; padding:10px; min-height:110px; margin-top:10px;
}
.rowbtns{display:flex; gap:8px; flex-wrap:wrap; margin-top:12px}
.linkbtn{font:inherit; background:none; border:0; padding:0; color:var(--accent); cursor:pointer; text-decoration:underline}
.navbtns{display:flex; gap:14px; align-items:center; justify-content:space-between; flex-wrap:wrap; margin-top:12px}
.quiet{
  font:400 13px "IBM Plex Sans",sans-serif; cursor:pointer; color:var(--muted);
  background:none; border:0; border-bottom:1px solid var(--line); padding:0 0 2px;
}
.quiet:hover{color:var(--ink); border-bottom-color:var(--muted)}
td.del{width:1%; white-space:nowrap; padding:4px 10px 4px 0; text-align:right}
.delbtn{font:400 16px/1 "IBM Plex Sans",sans-serif; background:none; border:0; cursor:pointer;
        color:var(--muted); padding:8px 10px; border-radius:6px}
.delbtn:hover{color:var(--malus); background:var(--surface-2)}
/* Actions de ligne de la base de données (archiver/désarchiver/supprimer) —
   même gabarit que .delbtn, .delbtn en plus quand l'action est destructive. */
.rowaction{font:400 15px/1 "IBM Plex Sans",sans-serif; background:none; border:0; cursor:pointer;
        color:var(--muted); padding:8px 10px; border-radius:6px}
.rowaction:hover{color:var(--ink); background:var(--surface-2)}
.rowaction.delbtn:hover{color:var(--malus); background:var(--surface-2)}
button.primary.addbtn{flex:none}
.sr{position:absolute; width:1px; height:1px; overflow:hidden; clip:rect(0 0 0 0); white-space:nowrap}
@media (prefers-reduced-motion:reduce){ *{transition:none!important} }

.r{text-align:right}

/* ---------- navigation du serveur (hub, éditeur/vitrine, connexion) ---------- */

.tvnav{
  display:flex; align-items:center; gap:18px; flex-wrap:wrap; min-height:58px; box-sizing:border-box;
  padding:10px 20px; border-bottom:1px solid var(--line); background:var(--surface);
  font-size:13px; position:sticky; top:0; z-index:30;
  box-shadow:0 6px 18px -14px rgba(26,33,28,.22);
}
/* Recherche globale, partagée par le bandeau des pages et le hub. */
.tvsearch{position:relative; width:100%; max-width:340px}
.tvnav .tvsearch{flex:1 1 220px}
.tvsearch input{
  font:inherit; font-size:13px; color:var(--ink); background:var(--surface-2);
  border:1px solid var(--line); border-radius:8px; padding:7px 12px; width:100%;
}
.tvsearchresults{
  position:absolute; top:calc(100% + 6px); left:0; right:0; z-index:40; max-height:340px; overflow-y:auto;
  background:var(--surface); border:1px solid var(--line); border-radius:10px; padding:6px;
  box-shadow:var(--shadow);
}
.tvsearchresults a{
  display:flex; align-items:center; gap:10px; padding:10px 12px; border-radius:7px;
  color:var(--ink); text-decoration:none; font-size:13.5px;
}
.tvsearchresults a span:nth-child(2){flex:1; min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap}
.tvsearchresults a:hover{background:var(--surface-2)}
.tvsearchicon{font-size:15px; line-height:1}
/* Bouton icône seul (retour hub, déconnexion, thème…) : une seule règle pour
   que taille, centrage et hover restent identiques partout — avant, chacun
   avait sa propre variante (l'un centré en flex, l'autre au jugé via le
   padding), d'où des icônes mal centrées et des tailles qui ne correspondaient
   pas tout à fait. */
.iconbtn{
  display:flex; align-items:center; justify-content:center;
  width:30px; height:30px; border-radius:7px; font-size:15px; line-height:1;
  color:var(--muted); background:none; border:0; padding:0; cursor:pointer; text-decoration:none;
  transition:background .12s, color .12s;
}
.iconbtn:hover{background:var(--surface-2); color:var(--ink)}

.scrolltop{
  position:fixed; right:20px; bottom:20px; z-index:40;
  width:44px; height:44px; border-radius:50%;
  display:flex; align-items:center; justify-content:center;
  background:var(--surface); border:1px solid var(--line); color:var(--ink);
  font-size:18px; cursor:pointer; box-shadow:0 2px 10px rgba(0,0,0,.25);
  transition:background .12s, border-color .12s, transform .12s;
}
.scrolltop:hover{border-color:var(--accent); transform:translateY(-2px)}

.tvbrand{display:flex; align-items:center; gap:10px; min-width:0}
.tvbrandtext{
  display:flex; align-items:center; gap:7px; color:var(--ink);
  font-family:"Fraunces",Georgia,serif; font-weight:600; font-size:15px; padding:6px 9px;
}
.tvbrandlink{
  display:flex; align-items:center; gap:7px; color:var(--ink); background:none; border:0; padding:6px 9px;
  font:inherit; font-family:"Fraunces",Georgia,serif; font-weight:600; font-size:15px; min-width:0; cursor:pointer;
  border-radius:7px; transition:background .12s;
}
.tvbrandlink:hover{background:var(--surface-2)}
.tvbrandicon{font-size:18px; line-height:1}
img.tvbrandicon{width:18px; height:18px; border-radius:4px; display:block}
.tvcaret{color:var(--muted); flex:none; transition:transform .15s}
.tvbrandlink[aria-expanded=true] .tvcaret{transform:rotate(180deg)}
/* Positionnement d'un menu déroulant dans la nav — partagé par le sélecteur
   de média et le menu du compte. */
.tvdrop{position:relative}
.tvmenu{
  position:absolute; top:calc(100% + 8px); right:0; min-width:210px; z-index:40;
  background:var(--surface); border:1px solid var(--line); border-radius:10px; padding:6px;
  box-shadow:var(--shadow); display:flex; flex-direction:column; gap:1px;
}
.tvdrop.tvswitch .tvmenu{left:0; right:auto}
.tvmenu a, .tvmenu button{
  display:flex; align-items:center; gap:10px; padding:10px 12px; border-radius:7px;
  color:var(--ink); text-decoration:none; font:inherit; font-size:13.5px; background:none; border:0;
  cursor:pointer; width:100%; text-align:left;
}
.tvmenu a:hover, .tvmenu button:hover{background:var(--surface-2)}
.tvright{display:flex; align-items:center; gap:10px; margin-left:auto}
.tvlinks{display:flex; align-items:center; gap:4px}
/* Pas de padding ici : chaque lien de la nav (liens, connexion, menus
   déroulants) fixe déjà le sien — une règle générique ici l'écrasait
   silencieusement dès que la spécificité était à égalité (mêmes points,
   ordre de déclaration défavorable), d'où des paddings qui ne semblaient
   « jamais s'appliquer ». */
.tvnav a{color:var(--muted); text-decoration:none}
.tvnav a:hover{color:var(--ink)}
.tvlinks a{padding:7px 12px; border-radius:7px}
.tvlinks a:hover{background:var(--surface-2); color:var(--ink)}
.tvnav a.on{color:var(--accent); font-weight:600}
.tvlinks a.on{background:var(--accent-soft)}
.tvlinks a.on:hover{background:var(--accent-soft)}
.tvsep{color:var(--line)}
.tvlogin{
  font:500 12.5px "IBM Plex Sans",sans-serif; color:var(--muted);
  border:1px solid var(--line); border-radius:7px; padding:7px 12px;
}
.tvlogin:hover{border-color:var(--accent); color:var(--ink)}
.tvlogout:hover{color:var(--malus)}
@media (max-width:640px){
  .tvbrand,.tvsearch,.tvright{width:100%; max-width:none}
  .tvright{justify-content:space-between; margin-left:0}
}

.legacybanner{
  margin:0 0 18px; padding:10px 13px; background:var(--accent-soft);
  border:1px dashed var(--accent); border-radius:7px;
}

/* ---------- hub : six panneaux plein écran, un par média ---------- */

/* Le hub réutilise .tvnav (même en-tête que les autres pages) au-dessus —
   min-height retire sa hauteur pour que les panneaux remplissent quand même
   le reste de l'écran, sans dépendre d'une valeur exacte au pixel près. */
.hubpage{min-height:calc(100vh - 59px); display:flex; flex-direction:column}

.hubrow{flex:1; display:flex; align-items:stretch; min-height:0}
.hubpanel{
  flex:1 1 0; min-width:0; display:flex; flex-direction:column; justify-content:space-between;
  gap:22px; padding:34px 22px 24px; text-decoration:none; color:inherit;
  border-left:1px solid var(--line); background:var(--surface); position:relative;
  transition:background .18s;
}
.hubrow .hubpanel:first-child{border-left:0}
.hubpanel::before{
  content:""; position:absolute; inset:0; opacity:0; pointer-events:none;
  background:radial-gradient(ellipse 220px 160px at 50% 30%, var(--accent-soft), transparent);
  transition:opacity .2s;
}
.hubpanel:hover{background:var(--surface-2)}
.hubpanel:hover::before{opacity:1}
/* Pas de centrage vertical du bloc : la tagline fait 2 à 4 lignes selon le
   média, et un bloc centré comme un tout fait flotter l'icône et le titre à
   des hauteurs différentes d'un panneau à l'autre. Ancré en haut à la place. */
.hubpanel-body{display:flex; flex-direction:column; align-items:center; text-align:center; gap:10px; margin-top:6px; position:relative}
.hubring{position:relative; width:80px; height:80px; display:flex; align-items:center; justify-content:center; flex:none}
.hubring svg{position:absolute; inset:0; transform:rotate(-90deg); transition:transform .2s}
.hubpanel:hover .hubring svg{transform:rotate(-90deg) scale(1.06)}
.hubring-bg{fill:none; stroke:var(--line); stroke-width:3}
.hubring-fg{fill:none; stroke:var(--accent); stroke-width:3; stroke-linecap:round; transition:stroke-dashoffset .3s ease}
.hubpanel-icon{font-size:34px; line-height:1; position:relative}
.hubpanel h2{font-size:17px}
.hubpanel .hint{font-size:12px; line-height:1.5}
.hubpanel-foot{display:flex; flex-direction:column; gap:16px; position:relative}
.hubpanel-foot .hubstat{text-align:center; line-height:1.2}
.hubpanel-foot .hubstat b{font-family:"IBM Plex Mono",monospace; font-size:20px; font-variant-numeric:tabular-nums}
.hubpanel-foot .hubstat span{display:block; font-size:10px; color:var(--muted); text-transform:uppercase; letter-spacing:.06em}
.hubpanel-soon{opacity:.5; cursor:default}
.hubpanel-soon:hover{background:var(--surface)}
.hubpanel-soon:hover::before{opacity:0}
/* Les trois actions ont la même apparence — seule Vitrine, le point d'entrée
   standard, porte un léger accent ; ce n'est pas une hiérarchie d'importance
   entre Éditeur et Base de données. */
.hubactions{display:flex; flex-direction:column; gap:8px}
.hubactions span{
  text-align:center; border-radius:7px; padding:9px 10px;
  font:500 12.5px "IBM Plex Sans",sans-serif; cursor:pointer; color:var(--muted);
  border:1px solid var(--line); transition:background .12s, border-color .12s, color .12s;
}
.hubactions span:hover{color:var(--ink); border-color:var(--accent); background:var(--surface)}
.hubactions span.accent{color:var(--accent); border-color:var(--accent-soft); background:var(--accent-soft)}
.hubactions span.accent:hover{border-color:var(--accent)}
@media (max-width:960px){
  .hubrow{flex-direction:column}
  .hubpanel{border-left:0; border-top:1px solid var(--line); padding:26px 24px; flex-direction:row; align-items:center; text-align:left; gap:20px}
  .hubrow .hubpanel:first-child{border-top:0}
  .hubpanel-body{flex-direction:row; text-align:left; align-items:center; margin:0; flex:1; min-width:0}
  .hubring{width:56px; height:56px}
  .hubpanel-icon{font-size:24px}
  .hubpanel-foot{flex:0 0 auto; width:200px}
}
@media (max-width:560px){
  .hubpanel{flex-direction:column; align-items:stretch; text-align:center}
  .hubpanel-body{flex-direction:column; text-align:center}
  .hubpanel-foot{width:auto}
}

/* ---------- base de données (catalogue) ---------- */

a.ghost, label.ghost{
  font:500 14px "IBM Plex Sans",sans-serif; cursor:pointer; color:var(--ink);
  background:transparent; border:1px solid var(--line); border-radius:7px; padding:11px 14px;
  text-decoration:none; display:inline-flex; align-items:center; gap:6px;
}
a.ghost:hover, label.ghost:hover{border-color:var(--accent)}
.dbform{display:grid; grid-template-columns:repeat(auto-fit,minmax(160px,1fr)); gap:12px}
.dbform .field{gap:6px; margin-top:0}
.dbform .field + .field{margin-top:0}
.dbform input{margin:0}
.thumbcell{width:40px; padding-right:0}
.thumb{width:32px; height:32px; object-fit:cover; border-radius:6px; display:block}
.thumb-placeholder{
  display:flex; align-items:center; justify-content:center; background:var(--surface-2);
  border:1px dashed var(--line); color:var(--muted); font-size:14px;
}

/* ---------- popup générique (formulaire d'ajout/édition…) ---------- */

.modal-overlay{
  position:fixed; inset:0; background:rgba(15,18,15,.5); display:flex;
  align-items:flex-start; justify-content:center; z-index:100; padding:8vh 20px 40px; overflow-y:auto;
}
.modal{
  background:var(--surface); border:1px solid var(--line); border-radius:12px; max-width:560px; width:100%;
  padding:24px; box-shadow:var(--shadow); position:relative;
}
.modal-close{position:absolute; top:14px; right:14px; font-size:13px}

button.danger{
  font:500 13.5px "IBM Plex Sans",sans-serif; cursor:pointer; color:var(--malus);
  background:transparent; border:1px solid var(--line); border-radius:7px; padding:10px 14px;
  width:100%;
}
button.danger:hover{border-color:var(--malus); background:var(--surface-2)}

/* ---------- connexion ---------- */

.loginwrap{
  min-height:100vh; display:flex; flex-direction:column; align-items:center; justify-content:center; gap:22px; padding:20px;
  background:radial-gradient(ellipse 700px 400px at 50% -10%, var(--accent-soft), transparent), var(--ground);
}
.loginbrand{
  display:flex; align-items:center; gap:8px; font-family:"Fraunces",Georgia,serif; font-weight:600;
  font-size:16px; color:var(--muted);
}
.loginform{width:100%; max-width:360px; display:flex; flex-direction:column; box-shadow:var(--shadow)}
.loginh1{font-size:24px}
.loginerr{color:var(--malus); margin-top:10px}

/* ---------- vitrine : statistiques, lignes cliquables, détail dépliable ---------- */

.stattiles{display:grid; grid-template-columns:repeat(auto-fit,minmax(120px,1fr)); gap:12px; margin-top:2px}
.stattile{
  display:flex; flex-direction:column; gap:4px; background:var(--surface-2); border:1px solid var(--line);
  border-radius:9px; padding:12px 14px; font:inherit; text-align:left; cursor:default;
}
.stattile b{font-family:"IBM Plex Mono",monospace; font-size:19px; font-variant-numeric:tabular-nums; font-weight:500}
.stattile span{font-size:11px; color:var(--muted); overflow:hidden; text-overflow:ellipsis; white-space:nowrap}
.stattile-jump{cursor:pointer; color:inherit; transition:border-color .12s, background .12s}
.stattile-jump:hover{border-color:var(--accent); background:var(--accent-soft)}

tr.rowclick:hover{background:var(--surface-2); cursor:pointer}
tr.detailrow td{background:var(--surface-2); border-bottom:1px solid var(--line)}
tr.detailrow .contrib{border-top:0}
.detailbody{display:flex; gap:16px; align-items:flex-start}
.detailimg{width:88px; height:88px; object-fit:cover; border-radius:8px; flex:none}

/* ---------- vitrine : podium des 5 mieux notés ---------- */

.podium{margin-top:4px}
.podiumtop{display:flex; align-items:flex-end; justify-content:center; gap:14px; flex-wrap:wrap}
.podiumspot{
  display:flex; flex-direction:column; align-items:center; gap:6px; font:inherit; text-align:center;
  background:var(--surface-2); border:1px solid var(--line); border-radius:10px 10px 4px 4px; cursor:pointer;
  width:128px; position:relative; padding:22px 14px 16px; color:inherit;
  transition:border-color .12s, background .12s;
}
.podiumspot:hover{border-color:var(--accent); background:var(--surface)}
.podium-1{order:2; padding-top:26px; padding-bottom:28px; background:var(--accent-soft); border-color:var(--accent)}
.podium-2{order:1; padding-bottom:18px}
.podium-3{order:3; padding-bottom:8px}
.podiumrank{
  position:absolute; top:-11px; left:50%; transform:translateX(-50%);
  width:22px; height:22px; border-radius:50%; background:var(--ink); color:var(--surface);
  display:flex; align-items:center; justify-content:center; font:600 12px "IBM Plex Mono",monospace; flex:none;
}
.podium-1 .podiumrank{background:var(--brass); color:var(--ink)}
.podiumspot img{width:56px; height:56px; object-fit:cover; border-radius:8px}
.podiumicon{font-size:36px; line-height:1}
.podiumicon-placeholder{
  width:56px; height:56px; display:flex; align-items:center; justify-content:center;
  font-size:22px; border-radius:8px; background:var(--surface-2); border:1px dashed var(--line); color:var(--muted);
}
.podiumnote{font-family:"IBM Plex Mono",monospace; font-size:18px; font-variant-numeric:tabular-nums}
.podiumname{
  font-size:12px; line-height:1.35; overflow:hidden; text-overflow:ellipsis;
  display:-webkit-box; -webkit-line-clamp:2; -webkit-box-orient:vertical;
}
.podiumrest{display:flex; flex-direction:column; gap:1px; margin-top:20px; border-top:1px solid var(--line); padding-top:10px}
.podiumrow{
  display:flex; align-items:center; gap:12px; padding:9px 8px; border:0; background:none; cursor:pointer;
  font:inherit; font-size:13.5px; color:var(--ink); text-align:left; border-radius:7px; width:100%;
}
.podiumrow:hover{background:var(--surface-2)}
.podiumrow b:first-child{color:var(--muted); font-family:"IBM Plex Mono",monospace; width:16px; flex:none}
.podiumrow span{flex:1; min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap}
.podiumrow b.num{font-family:"IBM Plex Mono",monospace; font-variant-numeric:tabular-nums}
