:root{
  --ground:#F7F8F9; --surface:#FFFFFF; --surface-2:#EDF0F2; --surface-3:#E2E7EA;
  --ink:#111A1D; --ink-2:#3A4A50; --muted:#6B7C83;
  --rule:#D9E0E3; --rule-2:#BFC9CE;
  --accent:#0E5A63; --accent-2:#E3F0F1; --accent-ink:#0A4249;
  --v1-bg:#CDEBD6; --v1-ink:#14562C;
  --v2-bg:#D5E3F5; --v2-ink:#1B4A7A;
  --v3-bg:#FBEAB6; --v3-ink:#7C5A06;
  --v4-bg:#F8DBBB; --v4-ink:#8A4A08;
  --v5-bg:#F7CFD2; --v5-ink:#8A1420;
  --off:#F0F2F3; --off-ink:#94A2A8;
  --shadow:0 1px 2px rgba(17,26,29,.06), 0 10px 28px -20px rgba(17,26,29,.35);
}
@media (prefers-color-scheme:dark){:root:not([data-theme="light"]){
  --ground:#0C1114; --surface:#131A1E; --surface-2:#1A2429; --surface-3:#232F35;
  --ink:#E6ECEE; --ink-2:#B4C2C7; --muted:#7F9199;
  --rule:#253137; --rule-2:#354449;
  --accent:#5FB3BD; --accent-2:#122A2E; --accent-ink:#8FCED6;
  --v1-bg:#16351F; --v1-ink:#8FD9A6;
  --v2-bg:#13293F; --v2-ink:#9CC4EC;
  --v3-bg:#3A2E0C; --v3-ink:#E5C46A;
  --v4-bg:#3B2510; --v4-ink:#E8AF72;
  --v5-bg:#3A1418; --v5-ink:#EE9AA3;
  --off:#161D21; --off-ink:#55666D;
  --shadow:0 1px 2px rgba(0,0,0,.4), 0 10px 28px -20px rgba(0,0,0,.7);
}}
:root[data-theme="dark"]{
  --ground:#0C1114; --surface:#131A1E; --surface-2:#1A2429; --surface-3:#232F35;
  --ink:#E6ECEE; --ink-2:#B4C2C7; --muted:#7F9199;
  --rule:#253137; --rule-2:#354449;
  --accent:#5FB3BD; --accent-2:#122A2E; --accent-ink:#8FCED6;
  --v1-bg:#16351F; --v1-ink:#8FD9A6;
  --v2-bg:#13293F; --v2-ink:#9CC4EC;
  --v3-bg:#3A2E0C; --v3-ink:#E5C46A;
  --v4-bg:#3B2510; --v4-ink:#E8AF72;
  --v5-bg:#3A1418; --v5-ink:#EE9AA3;
  --off:#161D21; --off-ink:#55666D;
  --shadow:0 1px 2px rgba(0,0,0,.4), 0 10px 28px -20px rgba(0,0,0,.7);
}
*{box-sizing:border-box}
body{margin:0;background:var(--ground);color:var(--ink);
  font-family:"IBM Plex Sans",-apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif;font-size:14px;line-height:1.5;
  -webkit-font-smoothing:antialiased}
.mono{font-family:"IBM Plex Mono",ui-monospace,monospace;font-variant-numeric:tabular-nums}

/* ---- top bar ---- */
header{position:sticky;top:0;z-index:60;background:var(--surface);border-bottom:1px solid var(--rule);
  padding:12px 20px;display:flex;flex-wrap:wrap;gap:14px;align-items:center;box-shadow:var(--shadow)}
.brand{display:flex;flex-direction:column;gap:1px;min-width:0}
.brand h1{margin:0;font-size:16px;font-weight:600;letter-spacing:-.01em;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.brand span{font-size:11.5px;color:var(--muted);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.spacer{flex:1 1 auto}
.tabs{display:flex;gap:2px;background:var(--surface-2);padding:3px;border-radius:8px}
.tab{border:0;background:transparent;color:var(--ink-2);font:inherit;font-size:12.5px;font-weight:500;
  padding:6px 13px;border-radius:6px;cursor:pointer;white-space:nowrap}
.tab[aria-selected="true"]{background:var(--surface);color:var(--accent-ink);box-shadow:0 1px 2px rgba(0,0,0,.08)}
.tab:focus-visible{outline:2px solid var(--accent);outline-offset:1px}
button.act{border:1px solid var(--rule-2);background:var(--surface);color:var(--ink);font:inherit;font-size:12.5px;
  font-weight:500;padding:7px 13px;border-radius:7px;cursor:pointer;white-space:nowrap}
button.act:hover{background:var(--surface-2)}
button.act:focus-visible{outline:2px solid var(--accent);outline-offset:1px}
button.act.primary{background:var(--accent);border-color:var(--accent);color:#fff}
button.act.primary:hover{filter:brightness(1.08)}
button.act:disabled{opacity:.45;cursor:not-allowed}
button.tiny{font-size:11px;padding:3px 8px;border-radius:5px}
.status{font-size:11.5px;color:var(--muted);display:flex;align-items:center;gap:6px;white-space:nowrap}
.dot{width:7px;height:7px;border-radius:50%;background:var(--muted);flex:none}
.dot.dirty{background:#D98A0B}.dot.ok{background:#2E8B57}.dot.err{background:#C0392B}

main{padding:18px 20px 80px}
.vbar{display:flex;flex-wrap:wrap;gap:10px;align-items:center;background:var(--surface);
  border:1px solid var(--rule);border-radius:9px;padding:9px 13px;margin-bottom:16px;box-shadow:var(--shadow)}
.vbar .sep{width:1px;align-self:stretch;background:var(--rule-2);margin:0 3px}
.vbar .spacer{flex:1 1 auto}
.vbadge{display:inline-flex;align-items:center;gap:6px;font-size:11px;font-weight:700;letter-spacing:.05em;
  text-transform:uppercase;padding:4px 10px;border-radius:20px;white-space:nowrap}
.vbadge.draft{background:var(--v3-bg);color:var(--v3-ink)}
.vbadge.working{background:var(--v2-bg);color:var(--v2-ink)}
.vbadge.versioned{background:var(--v1-bg);color:var(--v1-ink)}
.vbadge .num{font-family:"IBM Plex Mono",monospace;letter-spacing:0}
.vlab{font-size:10.5px;font-weight:700;letter-spacing:.06em;text-transform:uppercase;color:var(--muted);white-space:nowrap}
select.vsel{border:1px solid var(--rule-2);background:var(--surface);color:inherit;font:inherit;font-size:12px;
  padding:5px 8px;border-radius:6px;max-width:320px}
select.vsel:focus-visible{outline:2px solid var(--accent);outline-offset:1px}
.vcount{font-size:11px;color:var(--muted);font-family:"IBM Plex Mono",monospace;white-space:nowrap}
.panel{display:none}.panel.on{display:block}

/* ---- summary strip ---- */
.strip{display:flex;flex-wrap:wrap;gap:10px;margin-bottom:16px}
.stat{background:var(--surface);border:1px solid var(--rule);border-radius:9px;padding:11px 15px;min-width:132px}
.stat dt{font-size:10.5px;text-transform:uppercase;letter-spacing:.08em;color:var(--muted);font-weight:600;margin-bottom:3px}
.stat dd{margin:0;font-size:19px;font-weight:600;letter-spacing:-.02em}
.stat dd small{font-size:12px;font-weight:400;color:var(--muted);letter-spacing:0}

/* ---- matrix ---- */
.scroll{overflow:auto;max-height:calc(100vh - 258px);border:1px solid var(--rule);border-radius:10px;background:var(--surface)}
/* Largeur strictement dictee par le contenu. Un min-width:100% etirerait la
   table sur un grand ecran, et l excedent partirait dans les colonnes libres,
   c est a dire l identite, qui deborderait alors de ses libelles. Le vide a
   droite d une table etroite est prefere a des colonnes gonflees. */
table{border-collapse:separate;border-spacing:0;width:max-content}
th,td{border-right:1px solid var(--rule);border-bottom:1px solid var(--rule);padding:0;text-align:center;
  font-size:12.5px;background:var(--surface)}
/* Plans de superposition du tableau, du plus bas au plus haut : cellules
   ordinaires, colonnes figees du corps, en-tetes qui defilent, en-tetes
   figes. Chaque cran porte une classe dans son selecteur, sinon les regles
   de ligne (thead tr.grp th) l'emportent en specificite sur .stick et les
   deux se retrouvent au meme plan, ou le dernier du DOM recouvre l'autre.
   Tout reste sous le bandeau de l'application, qui est a 60. */
thead th{position:sticky;background:var(--surface-2);font-weight:600;font-size:11px;z-index:20;color:var(--ink-2)}
thead tr.grp th{top:0;height:48px;z-index:30}
/* La hauteur declaree n'est qu'un plancher : une cellule dont le titre
   depasse etire la rangee entiere, et les reglages cales en bas suivent. */
thead tr.hdr th{top:48px;height:96px;z-index:20;vertical-align:top}
thead tr.grp th.bk{background:var(--accent);color:#fff;letter-spacing:.04em;text-transform:uppercase}
thead tr.grp th.ck{background:var(--accent-ink);color:#fff;letter-spacing:.04em;text-transform:uppercase}
thead tr.grp th.ik{background:var(--surface-3);color:var(--ink-2);letter-spacing:.04em;text-transform:uppercase}
.gh{display:flex;align-items:center;justify-content:center;gap:7px;padding:0 9px;height:100%}
/* min-width:0 n'est pas cosmetique : sans lui, un element de flex refuse de
   descendre sous la largeur de son plus long mot, et le nom d'un bloc replie
   elargit toute la colonne. C'est ce qui faisait diverger deux colonnes de
   meme classe, selon la longueur des noms au-dessus d'elles. */
.gh b{font-weight:600;font-size:10.5px;line-height:1.15;overflow:hidden;min-width:0;
  overflow-wrap:anywhere;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical}
.fold{border:1px solid rgba(255,255,255,.35);background:rgba(255,255,255,.12);color:inherit;font:inherit;
  font-size:10px;line-height:1;padding:2px 5px;border-radius:4px;cursor:pointer;flex:none}
.fold:hover{background:rgba(255,255,255,.24)}
th.ik .fold{border-color:var(--rule-2);background:var(--surface);color:var(--ink-2)}
th .lab{display:block;padding:7px 6px 4px;line-height:1.2;font-weight:600;font-size:10.5px;
  hyphens:auto;overflow-wrap:anywhere}
th.fcol{width:134px;min-width:134px;max-width:134px}
th.icol{width:164px;min-width:164px;max-width:164px}
/* La reserve du bas est prise en padding, pas en hauteur figee : le titre
   ne peut donc jamais couler sous les reglages, il pousse la rangee. */
th.fcol,th.icol{padding-bottom:48px}
/* Les reglages d'une colonne, poids puis etat, sont cales en bas de
   l'en-tete : le titre garde le haut et sa hauteur variable, la rangee de
   reglages reste alignee d'une colonne a l'autre. Le th est deja sticky,
   donc il sert de reference au positionnement absolu. */
.hfoot{position:absolute;left:0;right:0;bottom:0;display:flex;flex-direction:column;
  align-items:center;gap:3px;padding:0 4px 5px}

th.w{vertical-align:middle}
th.w .lab{font-size:10.5px;letter-spacing:.03em;text-transform:uppercase;color:var(--muted)}
.wnote{display:block;margin-top:3px;font-size:10.5px;font-weight:600;color:var(--ink-2);
  font-variant-numeric:tabular-nums}
.stick{position:sticky;left:0;z-index:12}
thead tr.hdr th.stick{z-index:25}
thead tr.grp th.stick{z-index:35}

/* Colonnes d'identite : largeur libre, dictee par le plus long contenu.
   Rien n'est tronque, et les decalages des colonnes figees sont releves
   apres coup par placeSticky(), faute de pouvoir les ecrire en dur. */
td.name{text-align:left;padding:7px 11px;background:var(--surface);min-width:186px;
  border-right:1px solid var(--rule-2)}
td.name b{display:block;font-weight:600;font-size:12.5px;line-height:1.3;
  white-space:nowrap;min-width:0;flex:1 1 auto}
.nmw{display:flex;align-items:center;gap:8px;min-width:0}
input.perim{width:13px;height:13px;margin:0;flex:none;accent-color:var(--accent);cursor:pointer}
input.perim:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
th.name{text-align:left;padding:6px 11px;min-width:186px;border-right:1px solid var(--rule-2)}
select.sortsel{width:100%;border:1px solid var(--rule-2);background:var(--surface);color:var(--ink);
  font:inherit;font-size:11px;font-weight:500;padding:3px 6px;border-radius:5px;cursor:pointer}
select.sortsel:focus-visible{outline:2px solid var(--accent);outline-offset:1px}
td.rk{width:32px;min-width:32px;color:var(--muted);font-weight:600;font-size:11.5px;background:var(--surface-2)}
td.ident{font-size:11px;color:var(--ink-2);padding:6px 9px;text-align:left;background:var(--surface-2);
  white-space:nowrap}
td.ident.cat{min-width:110px;font-weight:600}
td.ident.sub{min-width:140px}
th.cath{min-width:110px}
th.subh{min-width:140px}
/* teinte de categorie sur l identite et les colonnes de score.
   Ces memes cellules servent de colonnes figees : une teinte posee en
   background-color les rendrait translucides, et le tableau qui defile
   sous elles apparaitrait en transparence. L intensite voyage donc dans
   --tintA, et la teinte est peinte en calque sur un fond plein. */
tr[style*="--cat"] td.tint{--tintA:.11}
tr[style*="--cat"] td.tint.wsum,tr[style*="--cat"] td.tint.itot,tr[style*="--cat"] td.tint.tot{--tintA:.19}
@media (prefers-color-scheme:dark){:root:not([data-theme="light"]) tr[style*="--cat"] td.tint{--tintA:.20}}
:root[data-theme="dark"] tr[style*="--cat"] td.tint{--tintA:.20}
:root[data-theme="dark"] tr[style*="--cat"] td.tint.wsum,:root[data-theme="dark"] tr[style*="--cat"] td.tint.itot,:root[data-theme="dark"] tr[style*="--cat"] td.tint.tot{--tintA:.32}
tr[style*="--cat"] td.tint{background-color:var(--surface);
  background-image:linear-gradient(rgba(var(--cat),var(--tintA)),rgba(var(--cat),var(--tintA)))}
td.cdot{border-left:3px solid rgb(var(--cat))}
.swatch{width:14px;height:14px;border-radius:3px;border:1px solid var(--rule-2);flex:none;cursor:pointer;padding:0}
input.col{width:34px;height:24px;border:1px solid var(--rule-2);border-radius:5px;background:var(--surface);
  padding:1px;cursor:pointer;flex:none}
td.itot{background:var(--surface-3);font-weight:700;font-family:"IBM Plex Mono",monospace;
  font-variant-numeric:tabular-nums;padding:7px 9px;min-width:78px;border-left:1px solid var(--rule-2)}
/* Un bloc replié se lit sur deux colonnes empilées, l'en-tête de groupe et
   la colonne de score : les deux portent la même largeur, sinon la plus
   large des deux l'emporte et les blocs cessent d'être alignés. */
th.scol,th.scolw{width:150px;min-width:150px;max-width:150px}
th.solo .gh{padding:0 5px;gap:5px}
th.solo .gh b{-webkit-line-clamp:3}
th.itotc,th.itotw{width:118px;min-width:118px;max-width:118px}
th.itotc{border-left:1px solid var(--rule-2)}
.bar{display:flex;flex-wrap:wrap;gap:8px;align-items:center;margin-bottom:12px}
.bar .spacer{flex:1 1 auto}
select.cell{appearance:none;border:0;background:transparent;font:inherit;font-size:10.5px;font-weight:600;
  width:100%;padding:9px 4px;text-align:center;text-align-last:center;cursor:pointer;color:inherit}
select.cell:focus-visible{outline:2px solid var(--accent);outline-offset:-2px}
td.sc{padding:0}
td.sc.v0{background:var(--v1-bg);color:var(--v1-ink)}
td.sc.v1{background:var(--v2-bg);color:var(--v2-ink)}
td.sc.v2{background:var(--v3-bg);color:var(--v3-ink)}
td.sc.v3{background:var(--v4-bg);color:var(--v4-ink)}
td.sc.v4{background:var(--v5-bg);color:var(--v5-ink)}
.badge{display:inline-block;font-size:8.5px;font-weight:700;letter-spacing:.06em;text-transform:uppercase;
  padding:1px 5px;border-radius:3px;margin-top:2px}
.badge.bi{background:var(--surface-3);color:var(--muted)}
td.sum,td.tot{font-family:"IBM Plex Mono",monospace;font-variant-numeric:tabular-nums;padding:7px 9px;
  background:var(--surface-2);font-weight:500;min-width:60px}
td.wsum{background:var(--surface-3);font-weight:700}
td.tot{background:var(--accent-2);font-weight:700;color:var(--accent-ink);min-width:70px;
  position:sticky;right:70px;z-index:10;border-left:1px solid var(--rule-2)}
td.b100{background:var(--accent);color:#fff;font-weight:700;min-width:70px;width:70px;
  font-family:"IBM Plex Mono",monospace;font-variant-numeric:tabular-nums;padding:7px 9px;
  position:sticky;right:0;z-index:11}
/* Nuance rouge-vert posée en style inline par heatOn(). Les trois teintes sont
   claires dans les deux thèmes, l'encre reste donc sombre. */
td.heat{color:#111A1D;background-image:none}
td.inf{text-align:left;padding:6px 9px;font-size:11px;background:var(--surface)}
td.inf select,td.inf input{width:100%;border:1px solid transparent;background:transparent;color:inherit;
  font:inherit;font-size:11px;padding:3px 4px;border-radius:4px;cursor:pointer}
td.inf select:hover,td.inf input:hover{border-color:var(--rule-2)}
td.inf select:focus-visible,td.inf input:focus-visible{outline:2px solid var(--accent);outline-offset:-1px}
thead tr.hdr th.rtot{position:sticky;right:70px;z-index:25;border-left:1px solid var(--rule-2)}
thead tr.hdr th.rb100{position:sticky;right:0;z-index:26;width:70px;min-width:70px}
thead tr.grp th.rgrp{position:sticky;right:0;z-index:35}
th.off,td.off{background:var(--off) !important;color:var(--off-ink) !important}
td.off select{color:var(--off-ink)}
/* Meme raison : une cellule figee ne peut pas etre rendue translucide,
   sinon le tableau qui defile dessous transparait. Hors perimetre, les
   colonnes figees gardent donc un fond plein et c est leur texte qui palit. */
tr.tool-off td{opacity:.5}
tr.tool-off td.stick,tr.tool-off td.tot,tr.tool-off td.b100{opacity:1;
  color:color-mix(in srgb, currentColor 50%, transparent)}
/* Sur une cellule en nuance, l'encre à atténuer est la sombre, pas celle du
   thème : en sombre, hériter donnerait du clair sur fond clair. */
tr.tool-off td.heat{color:rgba(17,26,29,.5)}
tr.tool-off td.name b{text-decoration:line-through}
.chk{display:flex;align-items:center;justify-content:center;gap:4px;padding:2px 0 0;font-size:9.5px;
  color:var(--muted);letter-spacing:.03em;text-transform:uppercase;font-weight:600}
.chk input{margin:0;width:12px;height:12px;accent-color:var(--accent);cursor:pointer}
select.mode{width:100%;border:1px solid transparent;background:transparent;
  color:var(--muted);font:inherit;font-size:8.5px;padding:1px 2px;border-radius:4px;cursor:pointer;
  text-transform:uppercase;letter-spacing:.04em;font-weight:600;opacity:.55;transition:opacity .12s}
th:hover select.mode{opacity:1;border-color:var(--rule-2);background:var(--surface)}
select.mode:focus-visible{outline:2px solid var(--accent);outline-offset:1px;opacity:1}
th.off select.mode{opacity:1;border-color:var(--rule-2);background:var(--surface)}
.wt{width:44px;border:1px solid var(--rule-2);background:var(--surface);color:inherit;font:inherit;
  font-size:11px;font-family:"IBM Plex Mono",monospace;text-align:center;border-radius:4px;padding:2px 3px}
.wt:focus-visible{outline:2px solid var(--accent);outline-offset:1px}

/* ---- config ---- */
.cfg{display:flex;flex-direction:column;gap:16px;max-width:1080px}
.card{background:var(--surface);border:1px solid var(--rule);border-radius:10px;overflow:hidden}
.card > h2{margin:0;padding:12px 16px;font-size:13px;font-weight:600;background:var(--surface-2);
  border-bottom:1px solid var(--rule);display:flex;align-items:center;gap:10px}
.card > h2 .spacer{flex:1}
.card .body{padding:14px 16px;display:flex;flex-direction:column;gap:12px}
.hint{font-size:11.5px;color:var(--muted);margin:0;max-width:74ch}
.row{display:flex;gap:8px;align-items:center;flex-wrap:wrap}
.blk{border:1px solid var(--rule);border-radius:8px;overflow:hidden}
.blk > .bh{display:flex;gap:8px;align-items:center;padding:9px 11px;background:var(--surface-2);
  border-bottom:1px solid var(--rule);flex-wrap:wrap}
.blk .items{padding:9px 11px;display:flex;flex-direction:column;gap:6px}
.item{display:flex;gap:8px;align-items:center}
.item .grab{color:var(--muted);font-size:12px;cursor:default;user-select:none;width:14px;text-align:center}
input.txt,select.sel{border:1px solid var(--rule-2);background:var(--surface);color:inherit;font:inherit;
  font-size:12.5px;padding:5px 8px;border-radius:6px}
input.txt{flex:1 1 200px;min-width:0}
input.num{width:62px;flex:0 0 62px;text-align:center;font-family:"IBM Plex Mono",monospace}
label.inl{font-size:11px;color:var(--muted);text-transform:uppercase;letter-spacing:.05em;font-weight:600;
  display:flex;align-items:center;gap:5px}
label.inl input[type=checkbox]{width:13px;height:13px;accent-color:var(--accent);margin:0}
.del{border:1px solid var(--rule-2);background:var(--surface);color:var(--muted);font:inherit;font-size:11px;
  width:24px;height:24px;border-radius:5px;cursor:pointer;flex:none;line-height:1}
.del:hover{color:#C0392B;border-color:#C0392B}
.banner{padding:11px 15px;border-radius:8px;font-size:12.5px;margin-bottom:14px;display:none;
  border-left:3px solid var(--accent);background:var(--accent-2);color:var(--ink-2)}
.banner.on{display:block}
.banner.warn{border-left-color:#D98A0B;background:var(--v3-bg);color:var(--v3-ink)}
.legend{display:flex;flex-wrap:wrap;gap:10px 20px;align-items:stretch}
.lgroup{display:flex;flex-direction:column;align-items:flex-start;gap:6px}
.lgroup + .lgroup{border-left:1px solid var(--rule-2);padding-left:20px}
.lgpills{display:flex;flex-wrap:wrap;gap:6px}
.lgname{font-size:10px;font-weight:700;letter-spacing:.07em;text-transform:uppercase;color:var(--muted);
  white-space:nowrap}
.pill{font-size:10.5px;font-weight:600;padding:3px 9px;border-radius:20px;letter-spacing:.02em}
.pill.p0{background:var(--v1-bg);color:var(--v1-ink)}.pill.p1{background:var(--v2-bg);color:var(--v2-ink)}
.pill.p2{background:var(--v3-bg);color:var(--v3-ink)}.pill.p3{background:var(--v4-bg);color:var(--v4-ink)}
.pill.p4{background:var(--v5-bg);color:var(--v5-ink)}
@media (max-width:720px){
  header{padding:10px 12px} main{padding:14px 12px 70px}
  .stick.n2{position:static} .scroll{max-height:none}
}

/* ==================== écrans applicatifs ==================== */
.screen{max-width:520px;margin:8vh auto;padding:0 20px}
.screen.wide{max-width:920px}
.panelcard{background:var(--surface);border:1px solid var(--rule);border-radius:12px;
  padding:26px 28px;box-shadow:var(--shadow)}
.panelcard h1{margin:0 0 6px;font-size:20px;font-weight:600;letter-spacing:-.01em}
.panelcard p.lead{margin:0 0 20px;font-size:13.5px;color:var(--muted);line-height:1.55}
.field{display:flex;flex-direction:column;gap:6px;margin-bottom:14px}
.field label{font-size:11px;font-weight:700;letter-spacing:.06em;text-transform:uppercase;color:var(--muted)}
.field input,.field select{border:1px solid var(--rule-2);background:var(--surface);color:inherit;
  font:inherit;font-size:14px;padding:9px 11px;border-radius:8px}
.field input:focus-visible,.field select:focus-visible{outline:2px solid var(--accent);outline-offset:1px}
.btn{border:1px solid var(--accent);background:var(--accent);color:#fff;font:inherit;font-size:13.5px;
  font-weight:600;padding:10px 16px;border-radius:8px;cursor:pointer;width:100%}
.btn:hover{filter:brightness(1.08)}
.btn:disabled{opacity:.5;cursor:not-allowed}
.btn.ghost{background:transparent;color:var(--ink);border-color:var(--rule-2);font-weight:500}
.btn.ghost:hover{background:var(--surface-2);filter:none}
.msg{font-size:12.5px;padding:10px 13px;border-radius:8px;margin-bottom:14px;line-height:1.5}
.msg.ok{background:var(--v1-bg);color:var(--v1-ink)}
.msg.err{background:var(--v5-bg);color:var(--v5-ink)}
.msg.info{background:var(--accent-2);color:var(--accent-ink)}
.msg.warn{background:var(--v3-bg);color:var(--v3-ink)}
.glist{display:flex;flex-direction:column;gap:1px;background:var(--rule);border:1px solid var(--rule);
  border-radius:9px;overflow:hidden;margin-bottom:16px}
.grow{display:grid;grid-template-columns:1fr auto auto auto;gap:12px;align-items:center;
  background:var(--surface);padding:12px 15px;cursor:pointer;text-align:left;border:0;font:inherit;color:inherit;width:100%}
.grow:hover{background:var(--surface-2)}
.grow:focus-visible{outline:2px solid var(--accent);outline-offset:-2px}
.grow .gn{font-weight:600;font-size:13.5px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.grow .gm{font-size:11px;color:var(--muted);font-family:"IBM Plex Mono",monospace;white-space:nowrap}
/* Pastille de profil, la meme partout : liste des grilles, bandeau du compte
   et page des comptes. La teinte descend avec les droits. */
.grole{font-size:9.5px;font-weight:700;letter-spacing:.05em;text-transform:uppercase;
  padding:2px 7px;border-radius:20px;background:var(--surface-3);color:var(--muted);white-space:nowrap}
/* Rouge pour le statut transverse : il ne se confond avec aucun profil de
   grille. Les deux jetons de la palette suivent le thème, contrairement à
   un blanc posé sur une teinte fixe. */
.grole.r-super{background:var(--v5-bg);color:var(--v5-ink)}
.grole.r-owner{background:var(--accent);color:#fff}
.grole.r-admin{background:var(--accent-2);color:var(--accent-ink)}
.grole.r-editor{background:var(--v2-bg);color:var(--v2-ink)}
.grole.r-viewer{background:var(--surface-3);color:var(--muted)}

/* ---- page des comptes ---- */
.plist{display:flex;flex-direction:column;gap:1px;background:var(--rule);
  border:1px solid var(--rule);border-radius:8px;overflow:hidden}
.prow{display:grid;grid-template-columns:1fr auto auto;gap:12px;align-items:center;
  background:var(--surface);padding:10px 13px;font-size:12.5px}
.prow.add{border:1px solid var(--rule);border-radius:8px;padding:11px 13px}
.prow.susp .pmail{text-decoration:line-through;color:var(--muted)}
.prow .pmail{font-weight:600;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.prow .vmeta{color:var(--muted);font-size:11px;min-height:15px}
.prow input,.prow select{border:1px solid var(--rule-2);background:var(--surface);color:inherit;
  font:inherit;font-size:12.5px;padding:7px 9px;border-radius:7px}
.prow input:focus-visible,.prow select:focus-visible{outline:2px solid var(--accent);outline-offset:1px}
.pacts{display:flex;gap:6px}
.act.danger{color:var(--v5-ink);border-color:var(--v5-bg)}
.act.danger:hover:not(:disabled){background:var(--v5-bg)}
.empty{padding:26px;text-align:center;color:var(--muted);font-size:13px;background:var(--surface)}
.modal{position:fixed;inset:0;background:rgba(10,16,20,.55);display:flex;align-items:center;
  justify-content:center;padding:20px;z-index:200}
.modal .box{background:var(--surface);border:1px solid var(--rule);border-radius:12px;
  max-width:680px;width:100%;max-height:82vh;overflow:auto;box-shadow:0 20px 60px -20px rgba(0,0,0,.5)}
.modal .box > header{padding:16px 20px;border-bottom:1px solid var(--rule);display:flex;align-items:center;gap:12px}
.modal .box > header h2{margin:0;font-size:15px;font-weight:600}
.modal .box > .body{padding:18px 20px;display:flex;flex-direction:column;gap:14px}
.modal .box > footer{padding:14px 20px;border-top:1px solid var(--rule);display:flex;gap:8px;justify-content:flex-end}
.vlist{display:flex;flex-direction:column;gap:1px;background:var(--rule);border:1px solid var(--rule);border-radius:8px;overflow:hidden}
.vrow{display:grid;grid-template-columns:40px 1fr auto;gap:11px;align-items:center;
  background:var(--surface);padding:9px 12px;font-size:12.5px}
.vrow.cur{background:var(--accent-2)}
.vrow.snap .vn{color:var(--muted)}
.vrow .vn{font-family:"IBM Plex Mono",monospace;font-weight:700;color:var(--accent-ink);text-align:center}
.vrow .vmeta{color:var(--muted);font-size:11px}
/* Les cartes de la page des versions gardent des lignes d'actions aérées. */
#ver .card .body > .row{gap:10px;align-items:center;flex-wrap:wrap}
#ver .vbadge{flex:none}
.userbar{display:flex;align-items:center;gap:8px;font-size:11.5px;color:var(--muted)}
.gauge{font-family:"IBM Plex Mono",monospace;font-size:10.5px;color:var(--muted);white-space:nowrap}
.gauge b{color:var(--ink)}
