/* =====================================================================
   FORMAFORCE Studio — design system (marque : indigo #3a4895 · or #fabb22)

   TROIS COUCHES, dans cet ordre :

     1. PRIMITIVES — les gammes brutes. Elles ne dépendent PAS du thème :
        l'indigo 600 vaut #3a4895 en clair comme en sombre. Tous les noms
        historiques (--n800, --i600, --a400, --r-lg, --sh…) sont conservés
        tels quels : près de 400 déclarations de ce fichier et 379 styles
        en ligne des écrans les référencent, et ils doivent continuer de
        résoudre à l'identique.

     2. SÉMANTIQUES — la couche qui BASCULE. Un rôle, pas une couleur :
        --surface, --text, --border, --accent, --ok-fg… C'est la seule
        couche redéfinie en mode sombre. Règle : aucune règle de composant
        ne devrait utiliser une primitive pour une couleur ; si un rôle
        manque, on l'ajoute ici plutôt que de piocher dans la gamme.

     3. COMPOSANT — quelques réglages propres à un composant qui ne se
        déduisent d'aucun rôle général (--nav-*, --toast-bg). Volontairement
        limité : moins de quinze jetons.

   Pourquoi ne pas simplement INVERSER la gamme des gris en sombre ? Parce
   qu'une même primitive y sert deux rôles opposés : --i900 est à la fois
   la couleur des titres (donc sombre en clair, claire en sombre) et le
   fond du bandeau de notification et de la colonne de navigation (sombre
   dans les deux thèmes). Inverser la gamme aurait éclairci le second en
   même temps que le premier. D'où le passage par des rôles.
   ===================================================================== */
:root{
  color-scheme: light;

  /* ---------- 1. PRIMITIVES (indépendantes du thème) ---------- */
  --i900:#141a38;--i800:#1a2147;--i700:#2b3675;--i600:#3a4895;--i500:#5563b0;--i400:#7d8ad4;--i200:#c3cbef;--i100:#e2e6f7;--i50:#f2f4fc;
  --a500:#e8a30a;--a400:#fabb22;--a300:#ffcf5b;--a50:#fff8e8;
  --n900:#171a21;--n800:#2b2f3b;--n700:#3d4250;--n600:#606676;--n500:#828a9c;--n400:#aab0c0;--n300:#c9cedb;--n200:#e3e6ef;--n100:#edeef4;--n50:#f6f7fb;--white:#fff;
  --green:#1f9d55;--green-bg:#e7f6ee;--orange:#d9920b;--orange-bg:#fdf3da;--red:#d64545;--red-bg:#fbe7e7;--blue:#2f6fed;--blue-bg:#e8f0fe;--na:#9aa0af;--na-bg:#eef0f4;
  --r-sm:6px;--r:10px;--r-lg:14px;--r-xl:18px;
  --gutter:1.6rem;--sb:236px;

  /* ---------- 2. SÉMANTIQUES — mode clair ---------- */
  /* Surfaces */
  --surface:#f6f7fb;            /* fond de page */
  --surface-raised:#fff;        /* carte, tableau, fenêtre, champ */
  --surface-sunken:#f6f7fb;     /* en-tête de tableau, bloc de code */
  --surface-inset:#edeef4;      /* petit contrôle en creux : segment, puce copiable */
  --surface-hover:#f2f4fc;      /* survol de ligne */
  /* Lignes */
  --border:#e3e6ef;             /* contour de carte */
  --border-strong:#c9cedb;      /* contour de champ */
  --border-subtle:#edeef4;      /* séparateur de cellule */
  /* Texte */
  --text:#2b2f3b;
  --text-strong:#141a38;        /* titres, valeurs de KPI, titres de ligne */
  --text-muted:#606676;
  --text-faint:#828a9c;
  /* Marque */
  --accent:#3a4895;
  --accent-hover:#2b3675;
  --accent-fg:#fff;             /* texte SUR l'accent */
  --accent-soft-bg:#f2f4fc;
  --accent-soft-fg:#2b3675;
  --accent-soft-border:#e2e6f7;
  --gold:#fabb22;
  --gold-hover:#e8a30a;
  --gold-fg:#141a38;            /* texte SUR l'or — reste sombre dans les deux thèmes */
  --gold-soft-bg:#fff8e8;
  --gold-soft-fg:#e8a30a;
  --nav-alerte:#ffcf5b;         /* or clair : lisible sur la colonne sombre */
  --gold-soft-border:#f4e2b0;

  /* États. Deux niveaux volontairement distincts :
     --ok-fg est une couleur de TEXTE sur teinte, plus sombre que --ok, qui
     est une couleur d'aplat. Les confondre fait tomber le contraste sous le
     seuil lisible : --orange (#d9920b) sur --warn-bg (#fdf3da) est illisible,
     là où --warn-fg (#7a5c00) passe. */
  --ok:#1f9d55;      --ok-fg:#0f7b3d;     --ok-bg:#e4f6ea;     --ok-border:#bfe6cf;
  --warn:#d9920b;    --warn-fg:#7a5c00;   --warn-bg:#fff3cd;   --warn-border:#f2d98c;
  --danger:#d64545;  --danger-fg:#b3261e; --danger-bg:#fdecea; --danger-border:#f5c2c0;
  --info:#2f6fed;    --info-fg:#1d4ed8;   --info-bg:#e8f0fe;   --info-border:#c7dbfd;
  --na-fg:#9aa0af;   --na-soft-bg:#eef0f4;

  /* Chrome */
  --focus:#5563b0;                 /* couleur de l'anneau de focus */
  --focus-soft:#3a489522;          /* halo diffus autour d'un champ actif */
  --scrim:rgba(26,33,71,.45);      /* voile derrière une fenêtre modale */
  --sh-sm:0 1px 2px #1a214710;
  --sh:0 4px 16px -6px #1a21471f;
  --sh-lg:0 18px 46px -14px #1a214733;
  --sh-modal:0 18px 50px rgba(26,33,71,.28);
  --skel-a:#edeef4;                /* bandes du squelette de chargement */
  --skel-b:#e3e6ef;

  /* ---------- 3. COMPOSANT ---------- */
  --nav-bg-from:#1a2147;
  --nav-bg-to:#141a38;
  --nav-fg:#d7dcf3;
  --nav-fg-strong:#fff;
  --nav-fg-muted:#aeb6e4;
  --nav-hover:#ffffff14;
  --nav-border:#ffffff1a;
  --nav-bar-bg:#ffffff22;
  --nav-active-bg:#3a4895;
  --nav-logo-bg:#fff;              /* plaque blanche sous le logo, dans les deux thèmes */
  --toast-bg:#141a38;
  --toast-fg:#fff;
  --doc-bg:#fff;                   /* aperçu d'article : le site est en clair, l'aperçu aussi */
}

/* =====================================================================
   MODE SOMBRE

   ⚠ MIROIR — les deux blocs qui suivent doivent rester IDENTIQUES.
   CSS ne sait pas réunir un sélecteur et une media query en une seule
   règle ; il en faut donc deux :
     • la première suit le réglage du système d'exploitation, sauf si
       l'utilisateur a explicitement demandé le mode clair ;
     • la seconde s'applique quand il a explicitement demandé le sombre.
   Toute modification de l'une doit être répercutée dans l'autre.

   `color-scheme:dark` n'est PAS cosmétique : sans lui, le sélecteur natif
   de <input type="datetime-local"> (fenêtre de planification) et de
   <input type="date"> (Annuaires) reste blanc sur blanc et devient
   inutilisable. Il pilote aussi la barre de défilement et les cases à
   cocher natives.

   Deux valeurs sont re-dérivées et non inversées :
     • les ombres — une ombre bleutée est invisible sur fond sombre ;
       l'élévation passe par une bordure plus claire ;
     • l'indigo — #3a4895 sur #14161c tombe sous 3:1. L'accent va donc vers
       le CLAIR (--i400) en sombre, à rebours de l'intuition.
   ===================================================================== */
@media (prefers-color-scheme: dark){
  :root:not([data-theme="light"]){
    color-scheme: dark;
    --surface:#14161c; --surface-raised:#1b1f27; --surface-sunken:#111319; --surface-hover:#232936; --surface-inset:#232833;
    --border:#2a2f3a; --border-strong:#3a4150; --border-subtle:#232833;
    --text:#dfe3ea; --text-strong:#f3f6fa; --text-muted:#9aa3b2; --text-faint:#868f9e;
    --accent:#7d8ad4; --accent-hover:#98a3e2; --accent-fg:#141a38; --accent-soft-bg:#1e2440; --accent-soft-fg:#aeb8ea; --accent-soft-border:#2f3960;
    --gold:#fabb22; --gold-hover:#ffcf5b; --gold-fg:#141a38;
    --gold-soft-bg:#2a2110; --gold-soft-fg:#f0c04a; --gold-soft-border:#4a3a14; --nav-alerte:#ffcf5b;
    --ok:#34d07a;     --ok-fg:#4ade80;     --ok-bg:#12291c;     --ok-border:#1f5133;
    --warn:#e0a52a;   --warn-fg:#f5c451;   --warn-bg:#2a2110;   --warn-border:#54401a;
    --danger:#e06a6a; --danger-fg:#f88a8a; --danger-bg:#2c1618; --danger-border:#5a2a2c;
    --info:#5b8dfa;   --info-fg:#8fb2fb;   --info-bg:#161f36;   --info-border:#2b3d63;
    --na-fg:#8b93a2;  --na-soft-bg:#232833;
    --focus:#98a3e2; --focus-soft:#7d8ad433; --scrim:rgba(0,0,0,.62);
    --sh-sm:0 1px 2px #00000059; --sh:0 4px 14px -6px #00000073; --sh-lg:0 18px 40px -14px #00000091;
    --sh-modal:0 18px 50px rgba(0,0,0,.6);
    --skel-a:#232833; --skel-b:#2c323f;
    --nav-bg-from:#171b28; --nav-bg-to:#0f1219;
    --nav-fg:#c3cad9; --nav-fg-strong:#fff; --nav-fg-muted:#8c95ad;
    --nav-hover:#ffffff12; --nav-border:#ffffff14; --nav-bar-bg:#ffffff1c;
    --nav-active-bg:#3a4895; --nav-logo-bg:#fff;
    --toast-bg:#2a3050; --toast-fg:#f3f6fa;
  }
}
/* MIROIR — identique au bloc ci-dessus. Voir l'avertissement. */
:root[data-theme="dark"]{
  color-scheme: dark;
  --surface:#14161c; --surface-raised:#1b1f27; --surface-sunken:#111319; --surface-hover:#232936; --surface-inset:#232833;
  --border:#2a2f3a; --border-strong:#3a4150; --border-subtle:#232833;
  --text:#dfe3ea; --text-strong:#f3f6fa; --text-muted:#9aa3b2; --text-faint:#868f9e;
  --accent:#7d8ad4; --accent-hover:#98a3e2; --accent-fg:#141a38; --accent-soft-bg:#1e2440; --accent-soft-fg:#aeb8ea; --accent-soft-border:#2f3960;
  --gold:#fabb22; --gold-hover:#ffcf5b; --gold-fg:#141a38;
  --gold-soft-bg:#2a2110; --gold-soft-fg:#f0c04a; --gold-soft-border:#4a3a14; --nav-alerte:#ffcf5b;
  --ok:#34d07a;     --ok-fg:#4ade80;     --ok-bg:#12291c;     --ok-border:#1f5133;
  --warn:#e0a52a;   --warn-fg:#f5c451;   --warn-bg:#2a2110;   --warn-border:#54401a;
  --danger:#e06a6a; --danger-fg:#f88a8a; --danger-bg:#2c1618; --danger-border:#5a2a2c;
  --info:#5b8dfa;   --info-fg:#8fb2fb;   --info-bg:#161f36;   --info-border:#2b3d63;
  --na-fg:#8b93a2;  --na-soft-bg:#232833;
  --focus:#98a3e2; --focus-soft:#7d8ad433; --scrim:rgba(0,0,0,.62);
  --sh-sm:0 1px 2px #00000059; --sh:0 4px 14px -6px #00000073; --sh-lg:0 18px 40px -14px #00000091;
  --sh-modal:0 18px 50px rgba(0,0,0,.6);
  --skel-a:#232833; --skel-b:#2c323f;
  --nav-bg-from:#171b28; --nav-bg-to:#0f1219;
  --nav-fg:#c3cad9; --nav-fg-strong:#fff; --nav-fg-muted:#8c95ad;
  --nav-hover:#ffffff12; --nav-border:#ffffff14; --nav-bar-bg:#ffffff1c;
  --nav-active-bg:#3a4895; --nav-logo-bg:#fff;
  --toast-bg:#2a3050; --toast-fg:#f3f6fa;
}
*{box-sizing:border-box}
html,body{margin:0}
body{font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif;color:var(--text);background:var(--surface);font-size:14px;line-height:1.5;-webkit-font-smoothing:antialiased}
#root{display:flex;min-height:100vh}
a{color:var(--accent);text-decoration:none}
a:hover{text-decoration:underline}
::selection{background:var(--a300)}
::-webkit-scrollbar{width:11px;height:11px}
::-webkit-scrollbar-thumb{background:var(--border-strong);border-radius:99px;border:3px solid var(--surface)}

/* ---------- Sidebar ---------- */
.side{width:var(--sb);flex-shrink:0;background:linear-gradient(180deg,var(--nav-bg-from),var(--nav-bg-to));color:var(--nav-fg-strong);display:flex;flex-direction:column;padding:1rem .75rem;gap:.15rem;position:sticky;top:0;height:100vh}
.brand{padding:.7rem .55rem 1.1rem;display:flex;flex-direction:column;align-items:flex-start;gap:.5rem}
.brand .logo{width:100%;max-width:180px;height:auto;display:block;background:var(--nav-logo-bg);border-radius:9px;padding:.5rem .6rem;box-shadow:var(--sh-sm)}
.brand small{display:block;font-weight:600;color:var(--nav-fg-muted);font-size:.72rem;letter-spacing:.02em;padding-left:.15rem}
.nav{background:none;border:0;color:var(--nav-fg);text-align:left;padding:.56rem .65rem;border-radius:9px;cursor:pointer;font-size:.9rem;display:flex;align-items:center;gap:.6rem;transition:background .12s,color .12s}
.nav .ic{font-size:1rem;width:1.25rem;text-align:center;opacity:.9}
.nav:hover{background:var(--nav-hover);color:var(--nav-fg-strong)}
.nav.active{background:var(--nav-active-bg);color:var(--nav-fg-strong);font-weight:600;box-shadow:var(--sh-sm)}
.navs{display:flex;flex-direction:column;gap:.15rem}
.side .foot{margin-top:auto;padding:.7rem .65rem 0;border-top:1px solid var(--nav-border);font-size:.72rem;color:var(--nav-fg-muted)}
.side .foot .bar{height:6px;border-radius:99px;background:var(--nav-bar-bg);margin:.35rem 0;overflow:hidden}
.side .foot .bar > i{display:block;height:100%;background:var(--gold);border-radius:99px}
.side .foot .kill{color:var(--nav-alerte);font-weight:700;margin-top:.3rem}

/* ---------- Main ---------- */
.main{flex:1;min-width:0;padding:1.5rem var(--gutter) 3rem;overflow:auto;max-height:100vh}
.page-head{display:flex;align-items:center;gap:.6rem;margin:.1rem 0 1.2rem}
h1{font-size:1.45rem;font-weight:750;letter-spacing:-.02em;margin:0;color:var(--text-strong)}
h2{font-size:1rem;font-weight:700;margin:0 0 .7rem;color:var(--text-strong)}
.sub{color:var(--text-muted);font-size:.86rem;margin:.15rem 0 0}
.row{display:flex;gap:.6rem;align-items:center;flex-wrap:wrap}
.spacer{flex:1}
.muted{color:var(--text-muted);font-size:.84rem}
.hint{color:var(--text-faint);font-size:.76rem;margin:.15rem 0 .2rem}
code{font-family:ui-monospace,Menlo,Consolas,monospace;font-size:.82em;background:var(--accent-soft-bg);padding:.1rem .35rem;border-radius:5px;color:var(--accent-soft-fg)}

/* ---------- Buttons ---------- */
.btn{background:var(--accent);color:var(--accent-fg);border:0;border-radius:9px;padding:.52rem .95rem;font-weight:600;cursor:pointer;font-size:.86rem;display:inline-flex;align-items:center;gap:.4rem;transition:background .12s,transform .04s,box-shadow .12s;box-shadow:var(--sh-sm)}
.btn:hover{background:var(--accent-hover)}
.btn:active{transform:translateY(1px)}
.btn.gold{background:var(--gold);color:var(--gold-fg)}
.btn.gold:hover{background:var(--gold-hover)}
.btn.ghost{background:var(--surface-raised);color:var(--accent);border:1px solid var(--border-strong);box-shadow:none}
.btn.ghost:hover{background:var(--accent-soft-bg);border-color:var(--accent-soft-border)}
.btn.danger{background:var(--surface-raised);color:var(--danger-fg);border:1px solid var(--border-strong);box-shadow:none}
.btn.danger:hover{background:var(--danger-bg);border-color:var(--danger-border)}
.btn.sm{padding:.32rem .62rem;font-size:.78rem;border-radius:7px}
.btn:disabled{opacity:.5;cursor:not-allowed;transform:none}

/* ---------- Cards & tiles ---------- */
.card{background:var(--surface-raised);border:1px solid var(--border);border-radius:var(--r-lg);padding:1.15rem 1.25rem;margin-bottom:1.1rem;box-shadow:var(--sh-sm)}
.card > h2:first-child{margin-top:0}
.grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(320px,1fr));gap:1rem}
.kpis{display:grid;grid-template-columns:repeat(auto-fit,minmax(150px,1fr));gap:.8rem;margin-bottom:1.15rem}
.kpi{background:var(--surface-raised);border:1px solid var(--border);border-radius:var(--r);padding:.85rem 1rem;box-shadow:var(--sh-sm);position:relative;overflow:hidden}
.kpi::before{content:"";position:absolute;left:0;top:0;bottom:0;width:4px;background:var(--accent)}
.kpi.g::before{background:var(--ok)}.kpi.o::before{background:var(--warn)}.kpi.b::before{background:var(--info)}.kpi.a::before{background:var(--gold)}
.kpi .v{font-size:1.6rem;font-weight:800;letter-spacing:-.02em;color:var(--text-strong);line-height:1.1}
.kpi .l{font-size:.74rem;color:var(--text-muted);text-transform:uppercase;letter-spacing:.04em;margin-top:.15rem}

/* ---------- Forms ---------- */
label{display:block;font-size:.8rem;font-weight:600;color:var(--text);margin:.75rem 0 .28rem}
input,textarea,select{width:100%;padding:.52rem .65rem;border:1px solid var(--border-strong);border-radius:9px;font:inherit;font-size:.86rem;background:var(--surface-raised);color:var(--text);transition:border-color .12s,box-shadow .12s}
input:focus,textarea:focus,select:focus{outline:0;border-color:var(--focus);box-shadow:0 0 0 3px var(--focus-soft)}
input[type=time],input[type=number]{max-width:170px}
input[type=checkbox]{width:auto}
textarea{min-height:110px;line-height:1.5}
textarea.code{font-family:ui-monospace,Menlo,Consolas,monospace;font-size:.8rem}
.field{margin-bottom:.35rem}
.field .cnt{float:right;font-weight:500;color:var(--text-faint);font-size:.72rem}
.field .cnt.over{color:var(--danger-fg)}
.two{display:grid;grid-template-columns:1fr 1fr;gap:.3rem 1rem}
.three{display:grid;grid-template-columns:1fr 1fr 1fr;gap:.3rem 1rem}
@media(max-width:720px){.two,.three{grid-template-columns:1fr}}

/* Interrupteur (toggle) */
.switch{display:inline-flex;align-items:center;gap:.55rem;cursor:pointer;margin:.5rem 0;font-size:.85rem;color:var(--text);font-weight:500}
.switch input{position:absolute;opacity:0;pointer-events:none}
.switch .track{width:38px;height:22px;border-radius:99px;background:var(--border-strong);position:relative;transition:background .15s;flex-shrink:0}
.switch .track::after{content:"";position:absolute;top:2px;left:2px;width:18px;height:18px;border-radius:50%;background:var(--surface-raised);box-shadow:var(--sh-sm);transition:transform .15s}
.switch input:checked + .track{background:var(--ok)}
.switch input:checked + .track::after{transform:translateX(16px)}

/* Segmented control */
.seg{display:inline-flex;background:var(--surface-inset);border-radius:9px;padding:3px;gap:2px}
.seg button{border:0;background:none;padding:.4rem .8rem;border-radius:7px;font-size:.82rem;font-weight:600;color:var(--text-muted);cursor:pointer;display:inline-flex;align-items:center;gap:.35rem}
.seg button.on{background:var(--surface-raised);color:var(--accent-soft-fg);box-shadow:var(--sh-sm)}

/* ---------- Filtres ---------- */
.filters{display:flex;gap:.6rem;flex-wrap:wrap;align-items:center;margin-bottom:1rem}
.filters .search{flex:1;min-width:200px;max-width:none}
.filters select{width:auto;min-width:130px}
.count{color:var(--text-faint);font-size:.8rem;white-space:nowrap}

/* ---------- Table ---------- */
.tablewrap{overflow-x:auto;border-radius:var(--r);border:1px solid var(--border)}
table{width:100%;border-collapse:collapse;font-size:.85rem;background:var(--surface-raised)}
thead th{position:sticky;top:0;background:var(--surface-sunken);z-index:1}
th,td{text-align:left;padding:.62rem .7rem;border-bottom:1px solid var(--border-subtle);vertical-align:middle}
th{font-size:.68rem;text-transform:uppercase;letter-spacing:.05em;color:var(--text-muted);font-weight:700}
tbody tr:hover{background:var(--surface-hover)}
tbody tr:last-child td{border-bottom:0}
.t-title{font-weight:650;color:var(--text-strong)}
.t-sub{font-size:.73rem;color:var(--text-faint);margin-top:.1rem;display:flex;gap:.4rem;align-items:center;flex-wrap:wrap}
.acts{display:flex;gap:.35rem;flex-wrap:wrap;justify-content:flex-end}

/* ---------- Badges / chips / pills ---------- */
.chip{display:inline-flex;align-items:center;gap:.3rem;padding:.14rem .5rem;border-radius:999px;font-size:.74rem;font-weight:700;white-space:nowrap}
.chip.good{background:var(--ok-bg);color:var(--ok-fg)}
.chip.ok{background:var(--warn-bg);color:var(--warn-fg)}
.chip.bad{background:var(--danger-bg);color:var(--danger-fg)}
.chip.na{background:var(--na-soft-bg);color:var(--na-fg)}
.chip .n{font-variant-numeric:tabular-nums;opacity:.85}
.pill{display:inline-block;padding:.14rem .5rem;border-radius:6px;font-size:.72rem;font-weight:700;background:var(--na-soft-bg);color:var(--text-muted)}
.pill.local{background:var(--na-soft-bg);color:var(--text-muted)}
.pill.draft_wp{background:var(--info-bg);color:var(--info-fg)}
.pill.published{background:var(--ok-bg);color:var(--ok-fg)}
.pill.scheduled{background:var(--gold-soft-bg);color:var(--gold-soft-fg)}
.pill.trash{background:var(--danger-bg);color:var(--danger-fg)}
.pill.error{background:var(--danger-bg);color:var(--danger-fg)}
.tag{display:inline-block;padding:.08rem .45rem;border-radius:5px;font-size:.7rem;font-weight:600;background:var(--accent-soft-bg);color:var(--accent-soft-fg)}
.src{font-size:.68rem;color:var(--text-faint);border:1px solid var(--border);border-radius:5px;padding:.02rem .35rem}
.ok-dot{color:var(--ok-fg)}.bad-dot{color:var(--danger-fg)}.warn-dot{color:var(--warn-fg)}

/* ---------- Liste d'évaluations Yoast ---------- */
.assess{display:flex;flex-direction:column;gap:.3rem;margin-top:.5rem}
.assess .a{display:flex;gap:.55rem;align-items:flex-start;padding:.4rem .6rem;border-radius:8px;background:var(--surface-sunken);border-left:3px solid var(--na-fg);font-size:.82rem}
.assess .a.good{border-color:var(--ok)}.assess .a.ok{border-color:var(--warn)}.assess .a.bad{border-color:var(--danger)}
.assess .a .b{width:8px;height:8px;border-radius:50%;margin-top:.35rem;flex-shrink:0;background:var(--na-fg)}
.assess .a.good .b{background:var(--ok)}.assess .a.ok .b{background:var(--warn)}.assess .a.bad .b{background:var(--danger)}
.scoreline{display:flex;gap:1.2rem;align-items:center;margin:.3rem 0 .2rem}
.gauge{font-size:1.7rem;font-weight:800;letter-spacing:-.02em;line-height:1}
.gauge small{font-size:.7rem;font-weight:600;color:var(--text-faint);display:block;text-transform:uppercase;letter-spacing:.04em}
.gauge.good{color:var(--ok-fg)}.gauge.ok{color:var(--warn-fg)}.gauge.bad{color:var(--danger-fg)}.gauge.na{color:var(--na-fg)}

/* ---------- Divers ---------- */
.mono{font-family:ui-monospace,Menlo,Consolas,monospace;font-size:.79rem;white-space:pre-wrap;background:var(--surface-sunken);border:1px solid var(--border-subtle);border-radius:8px;padding:.8rem;max-height:65vh;overflow:auto}
iframe.preview{width:100%;height:64vh;border:1px solid var(--border);border-radius:10px;background:var(--doc-bg)}
.split{display:grid;grid-template-columns:minmax(0,1fr) 360px;gap:1.1rem;align-items:start}
.split .side-col{position:sticky;top:1rem}
@media(max-width:1050px){.split{grid-template-columns:1fr}.split .side-col{position:static}}
.empty{padding:2.2rem 1rem;text-align:center;color:var(--text-faint)}
.empty .big{font-size:1.7rem;margin-bottom:.4rem}
.toast{position:fixed;right:1.1rem;bottom:1.1rem;background:var(--toast-bg);color:var(--toast-fg);padding:.75rem 1.05rem;border-radius:11px;font-size:.85rem;max-width:380px;box-shadow:var(--sh-lg);z-index:50;display:flex;gap:.5rem;align-items:center}
.toast.err{background:var(--danger)}
.progress{background:var(--accent-soft-bg);border:1px solid var(--accent-soft-border);color:var(--accent-soft-fg);border-radius:10px;padding:.55rem .9rem;font-size:.84rem;margin-bottom:1rem;font-weight:600}
.log-row{display:grid;grid-template-columns:130px 60px 1fr;gap:.5rem;padding:.28rem .4rem;border-bottom:1px solid var(--border-subtle);font-size:.8rem;align-items:baseline}
.log-row .lv{font-weight:700;font-size:.68rem;text-transform:uppercase}
.log-row .lv.info{color:var(--info-fg)}.log-row .lv.warn{color:var(--warn-fg)}.log-row .lv.error{color:var(--danger-fg)}
.log-row .ts{color:var(--text-faint);font-family:ui-monospace,Menlo,Consolas,monospace;font-size:.72rem}

/* --- Fenêtre de dialogue (choix de date) --- */
.ff-modal{position:fixed;inset:0;background:var(--scrim);display:flex;align-items:center;justify-content:center;z-index:50;padding:1rem}
.ff-modal-box{background:var(--surface-raised);border-radius:12px;padding:1.5rem 1.6rem;width:min(460px,100%);box-shadow:var(--sh-modal)}
.ff-modal-box h2{font-size:1.05rem;margin-bottom:.4rem}
/* Aperçu d'image : la boîte standard (460 px) est trop étroite pour juger d'un visuel. */
.ff-modal-box.img{width:min(980px,100%);padding:1rem}
.ff-modal-box.img img{width:100%;height:auto;display:block;border-radius:8px;background:var(--surface-inset)}
.ff-modal-box.img .meta{display:flex;justify-content:space-between;align-items:flex-start;gap:1rem;margin-top:.7rem;font-size:.82rem;color:var(--text-faint)}
.ff-modal-box.img .meta .t{color:var(--text);font-weight:600;font-size:.9rem}
.ff-modal-box.img .chemin{font-family:ui-monospace,Menlo,Consolas,monospace;font-size:.7rem;word-break:break-all;color:var(--text-faint);margin-top:.15rem}
.imgcell{cursor:zoom-in}
.ff-modal-box input[type=datetime-local]{width:100%;font-size:1rem;padding:.6rem .7rem}
@media(max-width:600px){.ff-modal-box{padding:1.1rem}}

/* --- Aperçu d'un article ---
   On juge une mise en page à sa largeur réelle : le corps d'article fait
   1090 px sur le site. La fenêtre lui laisse la place, sinon l'aperçu
   afficherait la version « écran étroit » et on relirait autre chose que
   ce qui sera publié. */
.ff-modal-box.doc{width:min(1240px,100%);height:min(92vh,100%);padding:.7rem .8rem;
  display:flex;flex-direction:column;gap:.55rem}
.ff-modal-box.doc .apercu-head{display:flex;align-items:flex-start;gap:.6rem;flex-wrap:wrap}
.ff-modal-box.doc .apercu-head .t{font-weight:600;font-size:.95rem;line-height:1.3;
  overflow:hidden;text-overflow:ellipsis;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical}
.ff-modal-box.doc .apercu-head .s{display:flex;align-items:center;gap:.4rem;flex-wrap:wrap;
  margin-top:.15rem;font-size:.73rem;color:var(--text-faint)}
.ff-modal-box.doc .apercu-head .s>span:first-child{font-family:ui-monospace,Menlo,Consolas,monospace}
.ff-modal-box.doc .apercu-head .s .mc{color:var(--accent-soft-fg);font-weight:600}
.ff-modal-box.doc .apercu-actes{display:flex;align-items:center;gap:.35rem;flex-wrap:wrap;margin-left:auto}
/* Le document lui-même : il occupe tout ce qui reste sous l'en-tête.
   min-height:0 est indispensable — sans lui, un enfant en flex:1 refuse de
   rétrécir sous sa hauteur intrinsèque et le cadre déborde de la fenêtre. */
.apercu-doc{flex:1;min-height:0;width:100%;border:1px solid var(--border);
  border-radius:9px;background:var(--doc-bg);display:block}
@media(max-width:700px){
  .ff-modal-box.doc{height:100%;padding:.55rem}
  .ff-modal-box.doc .apercu-actes{margin-left:0}
}

/* Galerie d'images — grille responsive, lisible sur téléphone comme sur écran large */
.grid-img { display:grid; gap:.9rem; grid-template-columns:repeat(auto-fill,minmax(190px,1fr)); }
.vign { border:1px solid var(--border); border-radius:8px; padding:.5rem; background:var(--surface-raised); }
.vign .nom { font-size:.74rem; font-weight:600; margin-top:.35rem; overflow:hidden;
             text-overflow:ellipsis; white-space:nowrap; }
.vign select, .vign button { width:100%; }

/* Terme de recherche cliquable : on doit VOIR que c'est copiable. */
.copiable { font:inherit; font-size:.8rem; text-align:left; width:100%; cursor:pointer;
            background:var(--surface-inset); border:1px dashed var(--border); border-radius:5px;
            padding:.3rem .5rem; color:inherit; transition:background .12s,border-color .12s; }
.copiable:hover { background:var(--gold-soft-bg); border-color:var(--gold-soft-fg); }
.copiable:active { transform:translateY(1px); }

/* Termes séparés et replis, sous la requête principale. Plus discrets
   qu'elle : ce sont des secours, pas le premier réflexe. */
.termes { display:flex; flex-wrap:wrap; align-items:center; gap:.25rem; margin-top:.3rem; }
.termes-label { font-size:.66rem; text-transform:uppercase; letter-spacing:.04em; color:var(--text-faint); }
.terme { font:inherit; font-size:.7rem; font-weight:600; cursor:pointer; color:var(--accent-soft-fg);
         background:var(--accent-soft-bg); border:1px solid transparent; border-radius:5px;
         padding:.1rem .4rem; transition:background .12s,border-color .12s; }
.terme:hover { background:var(--gold-soft-bg); border-color:var(--gold-soft-fg); }
.terme:active { transform:translateY(1px); }
.terme.repli { background:var(--surface-inset); color:var(--text-muted); font-weight:500; }


/* =====================================================================
   ACCESSIBILITÉ — anneaux de focus

   Il n'existait AUCUNE règle de focus dans ce fichier : la seule mention
   était `outline:0` sur les champs de formulaire, qui SUPPRIME l'anneau
   par défaut du navigateur. Au clavier, on ne voyait donc pas où l'on
   était — sur une application qui sert à publier, c'est disqualifiant.

   :focus-visible et non :focus — le navigateur ne montre l'anneau que
   lorsque la navigation est effectivement au clavier, jamais après un
   clic à la souris. On ne perd donc rien du dessin actuel.
   ===================================================================== */
:where(a,button,input,select,textarea,summary,[tabindex]):focus-visible{
  outline:2px solid var(--focus);
  outline-offset:2px;
  border-radius:var(--r-sm);
}
/* Les champs ont déjà un halo au focus : on garde l'anneau mais sans
   décalage, pour qu'il épouse la bordure au lieu de la doubler. */
input:focus-visible,textarea:focus-visible,select:focus-visible{outline-offset:0}
/* Dans la colonne de navigation, l'anneau indigo serait invisible sur le
   fond sombre : on l'éclaircit. */
.side :focus-visible{outline-color:var(--nav-fg-strong)}

/* =====================================================================
   CLASSES DES PHASES SUIVANTES

   Livrées ICI, avant leur utilisation par les écrans. `styles.css` est
   servi directement depuis le disque alors que `bundle.js` doit être
   recompilé : les deux se déploient donc indépendamment. Une classe
   employée dans le JSX avant que le CSS ne soit en ligne s'afficherait
   sans style — d'où l'ordre CSS d'abord, JSX ensuite.
   ===================================================================== */

/* ---------- Squelettes de chargement ----------
   Le tableau de bord initialise sa liste à [] : « en cours de chargement »
   et « aucun résultat » étaient indiscernables, et l'état vide servait de
   témoin de chargement. */
.skel{background:linear-gradient(90deg,var(--skel-a) 25%,var(--skel-b) 37%,var(--skel-a) 63%);
  background-size:400% 100%;animation:skel 1.4s ease infinite;border-radius:var(--r-sm)}
@keyframes skel{0%{background-position:100% 50%}100%{background-position:0 50%}}
.skel-line{height:.8rem;margin:.35rem 0}
.skel-cell{height:1rem}
@media (prefers-reduced-motion: reduce){.skel{animation:none}}

/* ---------- Pile de notifications ----------
   `.toast` garde son dessin ; c'est le CONTENEUR qui devient la pile.
   Voir aussi la règle mobile plus bas, retargetée de .toast vers .toasts. */
.toasts{position:fixed;right:1.1rem;bottom:1.1rem;z-index:60;
  display:flex;flex-direction:column-reverse;gap:.5rem;max-width:380px;pointer-events:none}
.toasts .toast{position:static;right:auto;bottom:auto;max-width:none;pointer-events:auto}
.toast-close{background:none;border:0;color:inherit;opacity:.65;cursor:pointer;
  font-size:1rem;line-height:1;padding:.1rem .2rem;margin-left:auto;flex-shrink:0}
.toast-close:hover{opacity:1}
.toast .n{font-variant-numeric:tabular-nums;opacity:.75;font-size:.78rem}

/* ---------- Menu débordant (⋯) ----------
   Rendu dans document.body via un portail : `.tablewrap` est en
   overflow-x:auto et sept instances ajoutent un maxHeight, ce qui
   rognerait un panneau positionné dans la cellule.
   z-index 40 : au-dessus du tableau, sous les fenêtres modales (50) et
   sous les notifications (60). */
.menu{position:fixed;z-index:40;min-width:210px;padding:.3rem;
  background:var(--surface-raised);border:1px solid var(--border);
  border-radius:var(--r);box-shadow:var(--sh-lg)}
.menu-item{display:flex;align-items:center;gap:.55rem;width:100%;
  background:none;border:0;text-align:left;cursor:pointer;color:var(--text);
  padding:.45rem .55rem;border-radius:var(--r-sm);font:inherit;font-size:.84rem}
.menu-item:hover,.menu-item:focus-visible{background:var(--surface-hover)}
.menu-item[disabled]{opacity:.45;cursor:not-allowed}
.menu-item.danger{color:var(--danger-fg)}
.menu-item.danger:hover,.menu-item.danger:focus-visible{background:var(--danger-bg)}
.menu-sep{height:1px;background:var(--border);margin:.3rem .2rem}

/* ---------- Icônes en trait ----------
   flex-shrink:0 est indispensable : sans lui les icônes s'écrasent dans
   `.acts`, qui est en flex-wrap. */
.ic-svg{flex-shrink:0;vertical-align:-.125em}

/* ---------- Variantes de carte et d'en-tête ---------- */
.card.flush{padding:0;overflow:hidden}
.card.bandeau{display:flex;align-items:center;gap:.7rem;flex-wrap:wrap;padding:.55rem .9rem}
.card-head{display:flex;align-items:baseline;gap:.6rem;flex-wrap:wrap;margin-bottom:.5rem}
.card-head h2{font-size:.95rem;margin:0}
.card-head .sub{font-size:.78rem;margin:.25rem 0 0}
.ff-modal-actes{display:flex;justify-content:flex-end;gap:.5rem;margin-top:1rem}
.btn.choix{text-align:left;padding:.9rem 1rem;display:block;width:100%}
.btn.choix .aide{display:block;opacity:.85;font-weight:400;margin-top:.15rem}

/* ---------- Échelle typographique ----------
   Dérivée des 29 tailles réellement employées dans les écrans, regroupées
   en huit paliers sous contrainte de 0,04 rem d'écart maximum : la
   migration des styles en ligne doit être invisible à l'œil.
   ⚠ `body` est à 14 px mais `html` n'a pas de taille définie : le rem vaut
   donc 16 px, pas 14. */
.t-3xs{font-size:.66rem}.t-2xs{font-size:.70rem}.t-xs{font-size:.74rem}
.t-sm{font-size:.80rem}.t-md{font-size:.84rem}.t-lg{font-size:.90rem}
.t-xl{font-size:1.05rem}.t-2xl{font-size:1.6rem}

/* ---------- Utilitaires de disposition ---------- */
.stack{display:flex;flex-direction:column}
.nowrap{white-space:nowrap}
.num{font-variant-numeric:tabular-nums}
.grow{flex:1}
.shrink0{flex-shrink:0}
.minw0{min-width:0}
.w-auto{width:auto}
.m-0{margin:0}
.mt-1{margin-top:.25rem}.mt-2{margin-top:.5rem}.mt-3{margin-top:.7rem}
.mt-4{margin-top:1rem}.mt-5{margin-top:1.4rem}.mt-6{margin-top:2rem}
.mb-1{margin-bottom:.25rem}.mb-2{margin-bottom:.5rem}.mb-3{margin-bottom:.7rem}
.mb-4{margin-bottom:1rem}.mb-5{margin-bottom:1.4rem}.mb-6{margin-bottom:2rem}

/* ---------- Largeurs de colonnes ----------
   Elles étaient posées en style en ligne sur chaque <th> — 55 occurrences
   pour 25 valeurs en pixels. Les valeurs se regroupent par CONTENU, pas
   par nombre ; l'écart maximal après regroupement est de 10 px sur un
   <th> dans une table en width:100%, donc invisible.
   Ces classes sont aussi le point d'accroche qui permettra de retirer les
   règles nth-child de masquage mobile (voir plus bas). */
.c-check{width:30px}.c-icon{width:44px}.c-num{width:62px}.c-score{width:78px}
.c-date{width:92px}.c-label{width:132px}.c-id{width:200px}

/* ---------- Hauteurs de tableau ---------- */
.tablewrap.h-sm{max-height:220px;overflow-y:auto}
.tablewrap.h-md{max-height:400px;overflow-y:auto}
.tablewrap.h-lg{max-height:520px;overflow-y:auto}

/* ---------- Pastilles pilotées par les données ----------
   Les écrans portaient des tables de couleurs en JavaScript
   (ETATS_IMAGE dans Dashboard, COULEURS dans Audit) appliquées en style
   en ligne. En sortant l'état dans un attribut, c'est le CSS qui colore —
   et le mode sombre est acquis sans y toucher. */
[data-etat]{--e-fg:var(--na-fg);--e-bg:var(--na-soft-bg);--e-bd:var(--na-fg)}
[data-etat="validee"]{--e-fg:var(--ok-fg);--e-bg:var(--ok-bg);--e-bd:var(--ok-border)}
[data-etat="a-valider"],[data-etat="choisie"]{--e-fg:var(--warn-fg);--e-bg:var(--warn-bg);--e-bd:var(--warn-border)}
[data-etat="en-ligne"]{--e-fg:var(--accent-soft-fg);--e-bg:var(--accent-soft-bg);--e-bd:var(--accent-soft-border)}
[data-etat="locale"],[data-etat="aucune"]{--e-fg:var(--text-faint);--e-bg:var(--surface-sunken);--e-bd:var(--border)}
[data-gravite="critique"]{--e-fg:var(--danger-fg);--e-bg:var(--danger-bg);--e-bd:var(--danger-border)}
[data-gravite="moyen"]{--e-fg:var(--warn-fg);--e-bg:var(--warn-bg);--e-bd:var(--warn-border)}
[data-gravite="faible"],[data-gravite="info"]{--e-fg:var(--info-fg);--e-bg:var(--info-bg);--e-bd:var(--info-border)}
.etiquette{display:inline-flex;align-items:center;gap:.3rem;padding:.14rem .5rem;
  border-radius:999px;font-size:.74rem;font-weight:700;white-space:nowrap;
  color:var(--e-fg);background:var(--e-bg);border:1px solid var(--e-bd)}
.dot{width:.55rem;height:.55rem;border-radius:50%;display:inline-block;background:var(--e-fg);flex-shrink:0}

/* =====================================================================
   RESPONSIVITÉ — du téléphone au grand écran.

   L'application était dessinée pour un écran de bureau : une colonne de
   navigation de 236 px collée à gauche et un contenu qui défile tout seul
   (`.main{max-height:100vh;overflow:auto}`). Sur un téléphone, cette
   colonne mange les deux tiers de la largeur et le double défilement rend
   les tableaux inutilisables.

   Trois paliers, choisis sur les usages réels et non sur des tailles
   d'appareils précises :
     ≤1100 px  colonne de navigation resserrée (tablette paysage, petit portable)
     ≤900 px   la colonne devient une barre horizontale (tablette portrait, téléphone)
     ≤600 px   densité réduite, actions pleine largeur (téléphone)
   Plus une règle pour les écrans tactiles, où une cible de 32 px se rate.
   ===================================================================== */

/* Rien ne doit dépasser en largeur : sur mobile, un seul élément trop large
   fait défiler toute la page de travers.
   PAS d'overflow-x:hidden sur html/body : cela ferait de la racine un
   conteneur de défilement et neutraliserait le `position:sticky` de la
   colonne de navigation et des en-têtes de tableau. On agit sur les
   contenus, pas sur la page. */
html,body{max-width:100%}
img,video,canvas{max-width:100%}
/* Une URL sans espace ne doit pas élargir sa cellule au-delà de l'écran. */
td,.muted,.sub{overflow-wrap:anywhere}
.page-head{flex-wrap:wrap}
/* Un titre long ne doit pas pousser les boutons hors de l'écran. */
.page-head > div:first-child{min-width:min(100%,220px);flex:1 1 220px}

@media(max-width:1100px){
  :root{--sb:198px;--gutter:1.15rem}
  .kpi .v{font-size:1.4rem}
  .split{grid-template-columns:minmax(0,1fr) 300px}
}

/* ---------- ≤900 px : la navigation passe en haut ---------- */
@media(max-width:900px){
  #root{flex-direction:column;min-height:100vh}

  .side{
    width:100%;height:auto;flex-direction:row;flex-wrap:wrap;align-items:center;
    gap:.35rem;padding:.5rem .7rem;position:static;
    box-shadow:0 2px 10px #1a214733;
  }
  /* L'ordre du DOM est marque → onglets → compte ; comme les onglets prennent
     toute la largeur, sans `order` la barre ferait trois rangées au lieu de
     deux. On remonte le bloc compte à côté de la marque. */
  .brand{padding:0 .5rem 0 0;flex-direction:row;align-items:center;gap:.5rem;flex:0 0 auto;order:1}
  .brand .logo{height:34px;width:auto;max-width:none;padding:.25rem .45rem}
  .brand small{display:none}

  /* Les onglets défilent horizontalement plutôt que de se replier sur
     plusieurs lignes : la hauteur de barre reste constante. */
  /* Rangée 1 : marque et compte. Rangée 2 : les onglets, sur UNE ligne qui
     défile horizontalement — sept onglets repliés en trois lignes mangeraient
     un tiers de l'écran d'un téléphone. */
  .navs{
    order:3;flex:1 0 100%;flex-direction:row;gap:.3rem;overflow-x:auto;
    scrollbar-width:none;-webkit-overflow-scrolling:touch;padding-bottom:2px;
  }
  .navs::-webkit-scrollbar{display:none}
  .side .nav{flex:0 0 auto;padding:.42rem .6rem;font-size:.82rem;white-space:nowrap}
  .side .nav .ic{width:auto}

  /* Le pied de colonne (budget + déconnexion) devient un coin discret. */
  .side .foot{
    margin:0 0 0 auto;padding:0;border-top:0;display:flex;align-items:center;
    gap:.5rem;flex:0 0 auto;font-size:.7rem;order:2;
  }
  .side .foot .bt,.side .foot .bar{display:none}
  .side .foot .bv{white-space:nowrap;font-variant-numeric:tabular-nums}
  .side .foot .row{margin-top:0 !important;gap:.4rem}

  /* Un seul défilement, celui de la page. */
  .main{max-height:none;overflow:visible;padding:1rem var(--gutter) 2.5rem}

  .split{grid-template-columns:1fr}
  .split .side-col{position:static}
  /* L'en-tête de tableau colle sous la barre de navigation, pas sous le haut
     de l'écran : sinon il disparaît derrière elle. */
  .tablewrap{max-height:none}
  /* Retargeté de .toast vers .toasts : c'est le CONTENEUR qui est
     positionné depuis la mise en pile. Sans ce changement, les
     notifications cessaient d'occuper toute la largeur sur mobile. */
  .toasts{left:.7rem;right:.7rem;bottom:.7rem;max-width:none}
}

/* ---------- ≤600 px : téléphone ---------- */
@media(max-width:600px){
  body{font-size:13.5px}
  :root{--gutter:.85rem}
  h1{font-size:1.18rem}
  .sub{font-size:.8rem}

  /* Les actions passent sous le titre, sur toute la largeur : au pouce,
     un bouton de 90 px collé à droite se rate une fois sur trois. */
  .page-head{gap:.45rem}
  .page-head > .spacer{display:none}
  .page-head > .btn{flex:1 1 auto;justify-content:center}

  .card{padding:.85rem .9rem;border-radius:12px}
  .kpis{grid-template-columns:repeat(auto-fit,minmax(132px,1fr));gap:.55rem}
  .kpi{padding:.6rem .7rem}
  .kpi .v{font-size:1.25rem}
  .kpi .l{font-size:.66rem}

  .filters{gap:.45rem}
  .filters .search{min-width:100%}
  .filters select{flex:1 1 45%;min-width:0}
  .seg{width:100%;overflow-x:auto}
  .seg button{white-space:nowrap}

  th,td{padding:.5rem .55rem}
  table{font-size:.8rem}
  .acts{justify-content:flex-start}
  .log-row{grid-template-columns:auto auto 1fr;gap:.35rem;font-size:.75rem}
  .grid-img{grid-template-columns:repeat(auto-fill,minmax(140px,1fr));gap:.6rem}
  .mono{font-size:.72rem;max-height:50vh}
  iframe.preview{height:52vh}
  .ff-modal{padding:.5rem}
  .ff-modal-box{padding:1rem;border-radius:10px}
  .scoreline{gap:.8rem;flex-wrap:wrap}
}

/* ---------- Écrans tactiles ----------
   Testé au doigt : sous 40 px de hauteur, les boutons d'action des lignes
   de tableau se ratent. On agrandit les cibles sans toucher au dessin sur
   les écrans à souris, et on retire les effets de survol qui restent
   « collés » après un appui. */
@media(pointer:coarse){
  .btn{min-height:40px;padding-left:.85rem;padding-right:.85rem}
  .btn.sm{min-height:34px}
  .nav{min-height:40px}
  .seg button{min-height:36px}
  input,select,textarea{font-size:16px;min-height:40px}  /* 16px : évite le zoom automatique d'iOS */
  input[type=checkbox]{min-height:0;width:18px;height:18px}
  .copiable{min-height:34px}
  tbody tr:hover{background:transparent}
  .btn:hover{background:var(--i600)}
  .btn.ghost:hover{background:#fff}
  .btn.gold:hover{background:var(--a400)}
}

/* ---------- Très grands écrans ----------
   Au-delà de 1900 px, une ligne de tableau qui traverse tout l'écran
   devient pénible à suivre : on borne la colonne de contenu. */
@media(min-width:1900px){
  .main{max-width:1680px}
}

/* ---------- Tableau des articles sur petit écran ----------
   Onze colonnes, dont une colonne d'actions qui peut porter douze boutons :
   sur un téléphone cela ferait quatre écrans de défilement horizontal. On
   masque les colonnes que l'on peut retrouver ailleurs — l'identifiant et le
   slug figurent déjà sous le titre, la catégorie reste accessible par le
   filtre — et jamais celles qui portent une décision (statut, score SEO,
   date de publication, actions). */
@media(max-width:900px){
  .t-articles th:nth-child(2),.t-articles td:nth-child(2),      /* ID */
  .t-articles th:nth-child(10),.t-articles td:nth-child(10){display:none}  /* Mis à jour */
}
@media(max-width:600px){
  .t-articles th:nth-child(3),.t-articles td:nth-child(3),      /* Image */
  .t-articles th:nth-child(5),.t-articles td:nth-child(5),      /* Catégorie */
  .t-articles th:nth-child(8),.t-articles td:nth-child(8){display:none}    /* Lisibilité */
  .t-articles .acts{max-width:168px}
  .t-articles .t-title{font-size:.84rem}
}

/* ---------- Registre des annuaires sur petit écran ----------
   Sept colonnes dont deux longues (identifiant, lien). On masque d'abord le
   résultat de la dernière vérification (relisible d'un appui sur 🔎), puis la
   date — jamais l'identifiant ni le lien de la fiche : ce sont les deux
   raisons d'ouvrir cet écran. */
@media(max-width:900px){
  .t-annuaires th:nth-child(6),.t-annuaires td:nth-child(6){display:none}   /* Vérification */
}
@media(max-width:600px){
  .t-annuaires th:nth-child(2),.t-annuaires td:nth-child(2),                /* Date */
  .t-annuaires th:nth-child(5),.t-annuaires td:nth-child(5){display:none}   /* Statut */
}

/* Entre 721 et 900 px (tablette portrait), trois colonnes de formulaire
   deviennent illisibles bien avant de se replier à 720 px : on passe par
   deux. La borne basse évite d'entrer en conflit avec la règle 720 px
   au-dessus, qui ramène déjà tout sur une colonne. */
@media(max-width:900px) and (min-width:721px){
  .three{grid-template-columns:1fr 1fr}
}
