/* Ez Translate — feuille de style de base.
   Volontairement sobre : l'outil est un back-office de travail, la
   lisibilite des tableaux prime sur tout le reste. */

:root {
    --bg:          #f4f5f7;
    --surface:     #ffffff;
    --border:      #dfe2e8;
    --text:        #1f2430;
    --text-muted:  #6b7280;
    --accent:      #2f5d9e;
    --accent-dark: #244b80;
    --ok:          #2e7d4f;
    --ko:          #b3352c;
    --warn-bg:     #fdf3d8;
    --error-bg:    #fdeceb;
    --focus:       #3b82f6;
    --radius:      6px;
}

* { box-sizing: border-box; }

body {
    margin: 0;
    background: var(--bg);
    color: var(--text);
    font: 15px/1.55 -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
          "Helvetica Neue", Arial, sans-serif;
}

/* --- Bandeau d'environnement ------------------------------------- */

.env-banner {
    background: var(--warn-bg);
    border-bottom: 1px solid #e6d9ab;
    color: #6b5417;
    font-size: 13px;
    padding: 5px 20px;
    text-align: center;
}

/* --- Barre supérieure : deux zones -------------------------------- */
/*
 * Zone 1 (topbar)  : selecteur de langue (gauche)
 *                    nom de l'app (centre)
 *                    identite + deconnexion (droite)
 * Zone 2 (subnav)  : onglets de navigation, ligne separee.
 *
 * Grille 3 colonnes pour le topbar : les deux colonnes 1fr aux extremes
 * poussent la colonne 'auto' du milieu au centre, meme si les blocs
 * gauche/droite n'ont pas la meme largeur.
 */

.topbar {
    align-items: center;
    background: var(--surface);
    border-bottom: 1px solid var(--border);
    display: grid;
    grid-template-columns: 1fr auto 1fr;
    gap: 24px;
    padding: 0 20px;
}

/* Colonne gauche : logo discret + pastilles de langue, alignés. */
.topbar-left  {
    align-items: center;
    display: flex;
    gap: 14px;
    justify-self: start;
}
.topbar-right { justify-self: end; }

.brand {
    color: var(--text);
    font-size: 17px;
    font-weight: 600;
    padding: 14px 0;
    text-decoration: none;
    justify-self: center;
}
.brand-logo {
    display: block;
    height: 24px;
    width: 24px;
    /* Le logo est rendu tel quel, sans arrondi ni ombre : c'est un
       carré plein qui suffit visuellement, et on respecte le rendu
       d'origine choisi par l'auteur du logo. */
}

/* Zone 2 : onglets sur leur propre ligne, meme surface que le topbar
   mais visuellement rattachee dessous par le bord partage. */
.subnav {
    background: var(--surface);
    border-bottom: 1px solid var(--border);
    display: flex;
    gap: 20px;
    padding: 0 20px;
}

.subnav a {
    color: var(--text-muted);
    padding: 12px 0;
    text-decoration: none;
    font-size: 14px;
}

.subnav a:hover { color: var(--accent); }

/* Onglet actif : souligné, pour situer d'un coup d'œil où l'on est. */
.subnav a.actif {
    box-shadow: inset 0 -2px 0 var(--accent);
    color: var(--text);
    font-weight: 500;
}

/* .nav conserve son ancien nom pour ne rien casser si un template
   externe l'utilisait ; il est desormais alias de .subnav. */
.nav { display: flex; gap: 18px; }
.nav a { color: var(--text-muted); padding: 12px 0; text-decoration: none; }
.nav a:hover { color: var(--accent); }
.nav a.actif { box-shadow: inset 0 -2px 0 var(--accent); color: var(--text); font-weight: 500; }

.account {
    align-items: center;
    display: flex;
    gap: 12px;
}

.account-name { color: var(--text-muted); font-size: 14px; }

.inline { display: inline; margin: 0; }

/* --- Sélecteur de langue de l'interface --------------------------- */
/* Rangée de boutons compacts type "chips" avec le code ISO à 2
   lettres visible et le nom local en tooltip. Le bouton actif est
   surligné, cliquer sur un autre pose un cookie + redirige. */

.locale-switch {
    display: flex;
    gap: 4px;
    align-items: center;
    padding: 8px 0;
}

.locale-btn {
    align-items: center;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: 4px;
    color: var(--text-muted);
    display: inline-flex;
    font-size: 12px;
    font-weight: 500;
    height: 26px;
    justify-content: center;
    letter-spacing: .5px;
    min-width: 32px;
    padding: 0 6px;
    text-decoration: none;
    transition: background .12s, color .12s, border-color .12s;
}

.locale-btn:hover {
    background: var(--bg);
    border-color: var(--accent);
    color: var(--text);
}

.locale-btn-actif {
    background: var(--accent-soft, #e7f1fc);
    border-color: var(--accent);
    color: var(--accent);
    font-weight: 600;
    pointer-events: none;
}

/* --- Structure ------------------------------------------------------ */

.container { margin: 0 auto; max-width: 1180px; padding: 24px 20px 48px; }

h1 { font-size: 22px; margin: 0 0 20px; }
h2 { font-size: 16px; margin: 0 0 14px; }

.panel {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    margin-bottom: 20px;
    padding: 20px;
}

.panel-narrow { margin: 40px auto; max-width: 420px; }

.footer {
    color: var(--text-muted);
    font-size: 13px;
    padding: 0 20px 32px;
    text-align: center;
}

/* --- Formulaires ---------------------------------------------------- */

.field { margin-bottom: 16px; }

.field label {
    display: block;
    font-size: 13px;
    font-weight: 500;
    margin-bottom: 5px;
}

.field input[type="text"],
.field input[type="password"],
.field input[type="search"],
.field input[type="date"],
.field input[type="email"],
.field input[type="number"],
.field select {
    border: 1px solid var(--border);
    border-radius: var(--radius);
    font: inherit;
    padding: 8px 10px;
    width: 100%;
}

/* Un input[type="date"] a 100% de largeur, c'est ridicule sur desktop
   (une seule case a remplir). On le contraint a une taille utile. */
.field input[type="date"] { max-width: 200px; }

.field input:focus, .field select:focus {
    border-color: var(--accent);
    outline: 2px solid rgba(47, 93, 158, .18);
}

.btn {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    color: var(--text);
    cursor: pointer;
    display: inline-block;
    font: inherit;
    padding: 8px 16px;
    text-decoration: none;
}

.btn:hover { border-color: #c3c8d1; }

.btn-primary {
    background: var(--accent);
    border-color: var(--accent);
    color: #fff;
}

.btn-primary:hover { background: var(--accent-dark); border-color: var(--accent-dark); }

/* Action destructive : rouge, à réserver aux confirmations de suppression. */
.btn-danger {
    background: var(--ko);
    border-color: var(--ko);
    color: #fff;
}

.btn-danger:hover { background: #922a22; border-color: #922a22; }

/* Variante « outline » du danger : texte + bordure rouges sur fond
   clair, pour les actions sortantes qui ne suppriment rien (typiquement
   « Deconnexion » en tete de page). Assez visible pour reperer, moins
   agressif qu'un bouton plein rouge. */
.btn-outline-danger {
    background: var(--surface);
    border-color: var(--ko);
    color: var(--ko);
}
.btn-outline-danger:hover {
    background: var(--ko);
    border-color: var(--ko);
    color: #fff;
}

/* Action positive de conclusion : vert, à réserver aux fins de tâches
   longues (lot terminé, import réussi, etc.) pour bien marquer que
   l'utilisateur peut sortir de l'écran. */
.btn-success {
    background: var(--ok);
    border-color: var(--ok);
    color: #fff;
}
.btn-success:hover { background: #245f3d; border-color: #245f3d; }

/* --- Messages -------------------------------------------------------- */

.alert {
    border-radius: var(--radius);
    margin: 0 0 16px;
    padding: 10px 12px;
}

.alert-error { background: var(--error-bg); color: var(--ko); }
.alert-ok    { background: #e3f2e8;         color: var(--ok); }

.hint { color: var(--text-muted); font-size: 13px; margin-top: 16px; }

.badge {
    border-radius: 10px;
    font-size: 12px;
    font-weight: 500;
    margin-left: 8px;
    padding: 2px 9px;
    vertical-align: middle;
}

.badge-ok { background: #e3f2e8; color: var(--ok); }
.badge-ko { background: var(--error-bg); color: var(--ko); }

/* --- Statistiques ----------------------------------------------------- */

.stats { display: flex; flex-wrap: wrap; gap: 28px; }

.stat-value { font-size: 26px; font-weight: 600; }
.stat-label { color: var(--text-muted); font-size: 13px; }

/* --- Tableaux ---------------------------------------------------------- */

.table { border-collapse: collapse; width: 100%; }

.table th, .table td {
    border-bottom: 1px solid var(--border);
    padding: 9px 8px;
    text-align: left;
    vertical-align: top;
}

.table tr:last-child th, .table tr:last-child td { border-bottom: none; }

.table th { font-weight: 500; }

.table td { color: var(--text-muted); }

.col-status { width: 24px; }

.dot {
    border-radius: 50%;
    display: inline-block;
    height: 9px;
    margin-top: 6px;
    width: 9px;
}

.dot-ok { background: var(--ok); }
.dot-ko { background: var(--ko); }

code {
    background: #eef0f4;
    border-radius: 3px;
    font-size: 13px;
    padding: 1px 5px;
}

.detail {
    background: #eef0f4;
    border-radius: var(--radius);
    font-size: 12px;
    overflow-x: auto;
    padding: 12px;
}

/* --- Entête de page avec action à droite ---------------------------- */

.page-head {
    align-items: center;
    display: flex;
    gap: 16px;
    justify-content: space-between;
    margin-bottom: 20px;
}

.page-head h1 { margin: 0; }

/* Groupe d'actions dans l'en-tête d'une page. */
.head-actions { display: flex; gap: 10px; }

/* Bouton Suggérer et son sélecteur de moteur, plus discrets que le
   bouton bleu d'enregistrement — c'est une aide, pas l'action finale. */
.btn-suggerer { background: #f4f8ff; border-color: #c7d6ea; }

.editeur-moteur {
    border: 1px solid var(--border);
    border-radius: var(--radius);
    font: inherit; font-size: 11px;
    padding: 1px 3px;
}

/* Barre outil du glossaire : sélecteur « Depuis » + formulaire d'ajout
   côte à côte sur les grands écrans, empilés sur les petits. */
.glossaire-toolbar {
    align-items: center;
    display: flex;
    flex-wrap: wrap;
    gap: 16px;
    margin: 6px 0 12px;
}
.glossaire-toolbar .glossaire-form { flex: 1; min-width: 320px; }

/* Sélecteur « Depuis : » — pas de marges verticales, la toolbar les porte. */
.glossaire-source {
    align-items: center;
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
    margin: 0;
}
.glossaire-source select {
    border: 1px solid var(--border);
    border-radius: var(--radius);
    font: inherit;
    padding: 5px 8px;
}

/* Formulaire d'ajout de terme au glossaire. */
.glossaire-form {
    align-items: center;
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    margin: 0;
}

.glossaire-form input[type="text"] {
    border: 1px solid var(--border);
    border-radius: var(--radius);
    font: inherit;
    padding: 6px 10px;
}
/* Les champs se compressent quand la ligne partage la place avec le
   sélecteur : min-width raisonnable pour rester lisible, flex-basis
   souple. */
.glossaire-form input[name="source"],
.glossaire-form input[name="target"] { flex: 1; min-width: 140px; }
.glossaire-form input[name="note"]   { flex: 2; min-width: 160px; }

/* Barre de recherche dans le glossaire — filtre client-side instantané.
   Input à gauche + compteur discret à droite. */
.glossaire-recherche {
    align-items: center;
    display: flex;
    gap: 12px;
    margin-bottom: 8px;
}
.glossaire-recherche input[type="search"] {
    border: 1px solid var(--border);
    border-radius: var(--radius);
    font: inherit;
    max-width: 320px;
    padding: 6px 10px;
    width: 100%;
}
.glossaire-recherche-compte {
    font-size: 13px;
    white-space: nowrap;
}

.glossaire-import {
    align-items: center;
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
    margin-top: 8px;
}

/* Formulaire d'ajout manuel d'une langue (page /langues/ajouter). */
.ajout-langue {
    align-items: center;
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
}
.ajout-langue select {
    border: 1px solid var(--border);
    border-radius: var(--radius);
    font: inherit;
    min-width: 320px;
    padding: 7px 10px;
}
.glossaire-import input[type="file"] {
    border: 1px dashed var(--border);
    border-radius: var(--radius);
    font: inherit;
    padding: 6px 10px;
}

/* Barre au-dessus du tableau des groupes : le décompte à gauche,
   l'action de traduction en masse à droite. */
.resultat-barre {
    align-items: center;
    display: flex;
    gap: 16px;
    justify-content: space-between;
    margin: 0 0 14px;
}
.resultat-barre .resultat { margin: 0; }

/* Barre outil de sélection multiple, apparaît au-dessus du tableau
   dès qu'une case est cochée. Contient le compteur, Tout/Rien/Inverser
   et le bouton « Traduire les sélectionnés ». */
.selection-barre {
    align-items: center;
    background: #f4f7fd;
    border: 1px solid #cfdaef;
    border-radius: var(--radius);
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    margin: 0 0 12px;
    padding: 8px 12px;
}
.selection-compte { color: var(--text); font-size: 13px; margin-right: 6px; }
.selection-compte strong { color: var(--accent); font-size: 14px; }

/* Écran de traduction par lots : bouton, barre de progression, erreurs. */
.lot-actions {
    align-items: center;
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
    margin: 18px 0 8px;
}
.lot-actions select { border: 1px solid var(--border); border-radius: var(--radius); font: inherit; padding: 6px 10px; }

.lot-barre {
    background: #e7eaef;
    border-radius: 4px;
    height: 10px;
    margin-top: 14px;
    overflow: hidden;
}
.lot-barre-fill {
    background: var(--accent);
    height: 100%;
    transition: width 200ms linear;
}

.lot-erreurs {
    background: var(--error-bg);
    border-radius: var(--radius);
    color: var(--ko);
    font-size: 13px;
    margin-top: 12px;
    max-height: 260px;
    overflow-y: auto;
    padding: 10px 12px 10px 30px;
}

/* Les deux sélecteurs de l'éditeur — cible et source — au même niveau,
   côte à côte : ce sont les deux données qui définissent l'écran. */
.head-langues { align-items: center; display: flex; flex-wrap: wrap; gap: 22px; }

.head-cible { align-items: center; display: flex; gap: 10px; }

.head-cible label {
    color: var(--text-muted);
    font-size: 13px;
    font-weight: 500;
}

.head-cible select {
    border: 1px solid var(--border);
    border-radius: var(--radius);
    font: inherit;
    font-size: 18px;
    font-weight: 600;
    padding: 5px 10px;
}

.head-cible select:focus {
    border-color: var(--accent);
    outline: 2px solid rgba(47, 93, 158, .18);
}

/* --- Colonnes numériques -------------------------------------------- */

.table td.num, .table th.num { text-align: right; white-space: nowrap; }

.num-warn { color: var(--ko); font-weight: 500; }

.muted { color: #9aa1ad; }

.col-actions { text-align: right; white-space: nowrap; }

/* --- Jauge d'avancement ---------------------------------------------- */

.col-progress { min-width: 150px; white-space: nowrap; }

.meter {
    background: #e7eaef;
    border-radius: 3px;
    display: inline-block;
    height: 7px;
    overflow: hidden;
    vertical-align: middle;
    width: 90px;
}

.meter span {
    background: var(--accent);
    display: block;
    height: 100%;
}

.meter-label {
    color: var(--text-muted);
    font-size: 12px;
    margin-left: 8px;
    vertical-align: middle;
}

/* --- Listes ------------------------------------------------------------ */

.list { color: var(--text-muted); margin: 0; padding-left: 20px; }
.list li { margin-bottom: 5px; }

.field input[type="file"] {
    border: 1px dashed var(--border);
    border-radius: var(--radius);
    font: inherit;
    padding: 14px;
    width: 100%;
}

.nowrap { white-space: nowrap; }

/* --- Icônes ------------------------------------------------------------ */
/* Les tracés sont dessinés en `currentColor` : l'icône suit la couleur du
   texte qui l'entoure, y compris au survol. */

svg { vertical-align: -2px; }

svg path {
    fill: none;
    stroke: currentColor;
    stroke-width: 1.6;
    stroke-linecap: round;
    stroke-linejoin: round;
}

.icon-btn {
    background: none;
    border: 1px solid transparent;
    border-radius: var(--radius);
    color: var(--text-muted);
    cursor: pointer;
    line-height: 1;
    padding: 5px 7px;
}

.icon-btn:hover  { background: #eef1f6; border-color: var(--border); color: var(--accent); }
.icon-btn:focus  { outline: 2px solid rgba(47, 93, 158, .35); outline-offset: 1px; }

/* Variante destructive : la couleur d'accent au survol devient rouge,
   pour signaler qu'il ne s'agit pas d'un clic anodin. */
.icon-btn-danger:hover { background: var(--error-bg); border-color: #e8c8c4; color: var(--ko); }
.icon-btn-danger:focus { outline: 2px solid rgba(179, 53, 44, .35); }

/* Texte réservé aux lecteurs d'écran : un bouton réduit à une icône doit
   rester annonçable. */
.sr-only {
    border: 0;
    clip: rect(0 0 0 0);
    height: 1px;
    margin: -1px;
    overflow: hidden;
    padding: 0;
    position: absolute;
    white-space: nowrap;
    width: 1px;
}

.col-lang { white-space: nowrap; }

/* Filet de sécurité : sur un écran étroit, le tableau défile
   horizontalement au lieu de déborder du panneau. */
.table-wrap { overflow-x: auto; }

/* --- Écran de traduction ---------------------------------------------- */

.head-sub {
    color: var(--text-muted);
    font-size: 15px;
    font-weight: 400;
    margin-left: 10px;
}

.filtres {
    align-items: flex-end;
    display: flex;
    flex-wrap: wrap;
    gap: 14px;
}

.filtre { flex: 0 0 auto; }

.filtre label {
    color: var(--text-muted);
    display: block;
    font-size: 12px;
    margin-bottom: 4px;
}

.filtre select, .filtre input[type="search"] {
    border: 1px solid var(--border);
    border-radius: var(--radius);
    font: inherit;
    max-width: 260px;
    padding: 7px 9px;
}

.filtre-recherche { flex: 1 1 200px; }
.filtre-recherche input { width: 100%; }
.filtre-actions { display: flex; gap: 8px; }

.resultat { margin: 0 0 14px; }

/* --- Tableau des groupes ------------------------------------------------ */

.table-trad td, .table-trad th { vertical-align: top; }

/* Case a cocher de la selection multiple, en tete de chaque ligne de
   groupe. La colonne existe sur les occurrences aussi (vide) pour que
   le tableau reste aligne. */
.col-select { padding-right: 0 !important; text-align: center; width: 28px; }
.col-select input[type="checkbox"] { cursor: pointer; margin: 0; }

.col-toggle { padding-right: 0 !important; width: 30px; }

.toggle {
    background: #eef1f6;
    border: 1px solid var(--border);
    border-radius: 3px;
    color: var(--text-muted);
    cursor: pointer;
    font: 600 13px/1 monospace;
    height: 19px;
    padding: 0;
    width: 19px;
}

.toggle:hover { border-color: var(--accent); color: var(--accent); }

.grp .col-src   { color: var(--text); font-weight: 500; }
.grp .col-dst   { color: var(--text); }
.grp-signal .col-toggle { border-left: 3px solid var(--warn-bg); }

/* Largeurs fixées : sans cela, une description de 800 caractères tire
   toute la colonne et les lignes ne s'alignent plus d'un groupe à l'autre. */
.table-trad { table-layout: fixed; width: 100%; }
.table-trad .col-select  { width: 28px; }
.table-trad .col-toggle  { width: 30px; }
.table-trad .col-section { width: 240px; }
.table-trad .col-src, .table-trad .col-dst { max-width: none; width: auto; }
/* La cellule doit pouvoir passer a la ligne : avec white-space: nowrap
   elle imposait sa largeur au tableau entier des qu'un groupe cumulait
   deux etats, et faisait apparaitre une barre de defilement. Seuls les
   badges restent insecables. */
.table-trad .col-etats { white-space: normal; width: 140px; }

.table-trad td { overflow-wrap: anywhere; }

/* Les occurrences se distinguent par un fond et un léger décalage, en
   restant dans les colonnes du tableau principal. */
.occ-ligne > td { background: #fafbfc; font-size: 13px; padding-bottom: 5px; padding-top: 5px; }
.occ-ligne .col-dst { padding-left: 20px; }
.occ-ligne .col-dst { color: var(--text-muted); }
.occ-ligne .col-section { color: #9aa1ad; }

.occ {
    color: var(--text-muted);
    font-size: 12px;
    margin-left: 6px;
    white-space: nowrap;
}

.vide { color: #b0b6c0; }

.col-section { color: var(--text-muted); font-size: 13px; }

.etat {
    border-radius: 3px;
    display: inline-block;
    font-size: 11px;
    margin-right: 4px;
    padding: 1px 6px;
    white-space: nowrap;
}

.etat-ko     { background: var(--error-bg); color: var(--ko); }
.etat-warn   { background: var(--warn-bg);  color: #7a5c12; }
.etat-neutre { background: #eef1f6;         color: var(--text-muted); }
/* Tag dédié aux traductions automatiques : violet clair, tranche des
   autres tons sans être criard. Une valeur `.` en tête d'un fichier
   .lng d'origine porte ce marqueur. */
.etat-auto   { background: #ede8f7;         color: #5b3fa0; font-weight: 500; }
/* Petit liseré violet sur la colonne Traduction quand la ligne porte
   une valeur automatique. Classe posée par PHP pour ne pas dépendre du
   sélecteur CSS :has() (encore inégal sur certains navigateurs). */
.grp-auto .col-dst, .occ-auto .col-dst { box-shadow: inset 3px 0 0 #b7a4e0; }

/* Badges de statut : mêmes visuels que les autres etats, tons distincts
   pour la lisibilité. Le tag validé n'apparaît pas (état terminal). */
.etat-statut-1 { background: #f2ecda; color: #7a5c12; }  /* Brouillon : jaune doux */
.etat-statut-2 { background: #dbe6f1; color: #365583; }  /* Relu     : bleu doux  */

/* Badges rendus sous forme de <button> quand ils sont cliquables.
   Aspect identique aux <span> mais avec curseur pointeur, léger relief
   au survol et transition douce. Le tag reste dans la ligne (bordure
   invisible sauf hover) pour ne pas polluer visuellement le tableau. */
button.etat-cliquable {
    border: 1px solid transparent;
    cursor: pointer;
    font-family: inherit;
    line-height: 1.4;
    transition: border-color .1s, transform .05s;
}
button.etat-cliquable:hover {
    border-color: rgba(0, 0, 0, .18);
}
button.etat-cliquable:active {
    transform: translateY(1px);
}
/* Accessibilité clavier : contour bleu net sur tab, indépendant du hover. */
button.etat-cliquable:focus-visible {
    border-color: var(--focus, #3b82f6);
    outline: 2px solid var(--focus, #3b82f6);
    outline-offset: 1px;
}
button.etat-cliquable[disabled],
button.etat-cliquable.etat-en-cours {
    cursor: wait;
    opacity: .55;
}

/* Bulle transitoire de confirmation ou de refus d'une action badge :
   fixee en bas-droite, monte en un fondu, disparait apres 2 s. Elle
   sert de trace visible quand un clic ne modifie pas la ligne (auto
   deja retire, statut deja valide, refus serveur…). */
.badge-toast {
    background: #333;
    border-radius: 4px;
    bottom: 20px;
    box-shadow: 0 4px 12px rgba(0, 0, 0, .18);
    color: #fff;
    font-size: 13px;
    max-width: 400px;
    opacity: 0;
    padding: 10px 16px;
    pointer-events: none;
    position: fixed;
    right: 20px;
    transform: translateY(6px);
    transition: opacity .18s, transform .18s;
    z-index: 100;
}
.badge-toast-visible {
    opacity: 1;
    transform: translateY(0);
}
.badge-toast-ok { background: #2d7a3d; }
.badge-toast-ko { background: #a93226; }

/* --- Occurrences dépliées ------------------------------------------------ */

/* --- Pagination ---------------------------------------------------------- */

.pagination {
    align-items: center;
    display: flex;
    gap: 14px;
    justify-content: center;
    margin-top: 18px;
}

.pagination-etat { color: var(--text-muted); font-size: 13px; }

/* Les descriptions montent à 800 caractères : on les borne à deux lignes
   pour que le tableau reste balayable. Le texte complet reste accessible
   en dépliant, et par l'infobulle. */
/* -webkit-INLINE-box et non -webkit-box : la version bloc sortirait le
   compteur d'occurrences sur une ligne a part. Et surtout, ne JAMAIS
   passer la cellule elle-meme en flex — cela la sort du modele tabulaire
   et disloque toute la ligne. */
.grp .col-src > .txt, .grp .col-dst > .txt {
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 2;
    display: -webkit-inline-box;
    line-clamp: 2;
    overflow: hidden;
    vertical-align: top;
}

.col-src, .col-dst { max-width: 420px; }

/* Toute la ligne d'un groupe repliable est cliquable. */
.grp-pliable { cursor: pointer; }
.grp-pliable:hover > td { background: #f7f9fc; }

/* --- Éditeur en ligne ----------------------------------------------------- */

/* La colonne « Traduction » est la zone d'édition : le reste de la ligne
   plie et déplie le groupe. Le curseur le dit avant le clic. */
.grp .col-dst, .occ-ligne .col-dst { cursor: text; }
.grp-pliable .col-dst:hover, .occ-ligne .col-dst:hover { background: #eef4fd; }

.ligne-edition > td { background: #f4f8ff !important; }

/* Après enregistrement : la ligne revient du serveur, un bref fond vert
   dit laquelle. */
.ligne-ok > td { background: #e8f6ed !important; transition: background 1.2s ease-out; }

/* Le textarea sert dans deux contextes : inline dans une cellule de
   l'éditeur, et pleine largeur pour le contexte de traduction. La règle
   cible la classe pour couvrir les deux, sans dépendre d'un ancêtre. */
.editeur textarea, .editeur-val {
    border: 1px solid var(--accent);
    border-radius: var(--radius);
    box-sizing: border-box;
    font: inherit;
    padding: 6px 8px;
    resize: vertical;
    width: 100%;
}

.editeur-barre {
    align-items: center;
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    margin-top: 6px;
}

/* Un flex DANS la cellule, jamais SUR la cellule : passer un <td> en flex
   le sort du modèle tabulaire et disloque toute la ligne. */
/* Boutons discrets : ils encadrent le texte à traduire, ils ne doivent pas
   le dominer. */
.btn-mini { font-size: 11px; line-height: 1.4; padding: 2px 7px; }
.btn-actif { background: var(--warn-bg); border-color: #d8c27a; color: #7a5c12; }

.editeur-statut { font: inherit; font-size: 11px; padding: 1px 3px; }

.editeur-portee { color: var(--text-muted); font-size: 12px; margin-left: auto; }

.editeur-msg { color: var(--ok); font-size: 12px; margin: 6px 0 0; }
.editeur-msg-ko { color: var(--ko); }

/* Marqueur divergent : sur une ligne en anomalie, c'est LE caractère qui
   pose problème, pas la phrase. Gras des deux côtés, à la même place. */
.marq { font-weight: 700; }

/* Autres traductions du groupe, à reprendre d'un clic. */
.editeur-variantes {
    align-items: baseline;
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    margin-top: 6px;
}

.editeur-etiquette { color: var(--text-muted); font-size: 12px; }

.btn-variante { font-weight: normal; max-width: 100%; overflow: hidden; text-align: left; }
.btn-variante .occ { margin-left: 3px; }

/* --- Ligne en cours d'édition : plus rien n'est tronqué -------------------- */

/* Au repos, source et traduction sont bornées à deux lignes pour que le
   tableau reste balayable. Sur la ligne qu'on modifie, on a justement
   besoin de lire la fin : le clamp saute des deux côtés. */
.groupe-edition .col-src > .txt,
.groupe-edition .col-dst > .txt {
    display: inline;
    line-clamp: none;
    overflow: visible;
    -webkit-line-clamp: none;
}

/* Bouton « Copier » sous le texte de référence : de quoi aller coller la
   phrase dans un traducteur en ligne sans la resaisir. */
.src-actions { margin-top: 6px; }

/* --- Modale de session expirée ---------------------------------------- */
/* Overlay opaque qui bloque toute interaction avec la page derrière : la
   session est morte, plus rien n'est enregistrable tant que l'utilisateur
   ne s'est pas reconnecté. */

.modal-overlay {
    align-items: center;
    background: rgba(0, 0, 0, .45);
    display: flex;
    inset: 0;
    justify-content: center;
    position: fixed;
    z-index: 1000;
    animation: modal-fade .15s ease-out;
}

/* Sans cette regle, .modal-overlay { display: flex } ecrase l'attribut
   HTML `hidden` (qui vaut display:none dans la feuille UA du navigateur,
   avec une specificite egale). La modale resterait donc AFFICHEE des le
   chargement de la page, meme si on n'a jamais appele afficher(). Cette
   ligne remet la priorite au bon endroit : quand [hidden] est present,
   on force display:none avec une specificite superieure. */
.modal-overlay[hidden] { display: none; }

/* Animations : le fond fond, la boite pop legerement en meme temps.
   Rapide (150 ms) pour ne pas retarder l'utilisateur : c'est de la
   politesse visuelle, pas un rideau qu'on remonte. */
@keyframes modal-fade {
    from { opacity: 0; }
    to   { opacity: 1; }
}
@keyframes modal-pop {
    from { transform: translateY(-8px) scale(.98); opacity: 0; }
    to   { transform: none;                        opacity: 1; }
}
.modal { animation: modal-pop .18s ease-out; }

/* Respect des utilisateurs qui ont demande a leur systeme
   d'attenuer les animations. */
@media (prefers-reduced-motion: reduce) {
    .modal-overlay,
    .modal { animation: none; }
}

/* --- Avertissement de session : petite pastille dans le topbar ------
 * Apparait dans les dernieres minutes avant expiration pour laisser au
 * traducteur le temps de finir ce qu'il tape. Cliquable : le geste
 * declenche un ping immediat, prolonge la session si tout va bien, ou
 * ouvre la modale si le serveur repond deja 401. */

.session-warning {
    align-items: center;
    background: var(--warn-bg);
    border: 1px solid #e6d9ab;
    border-radius: 4px;
    color: #6b5417;
    cursor: pointer;
    display: inline-flex;
    font-size: 12px;
    gap: 6px;
    padding: 4px 10px;
    margin-right: 12px;
}
.session-warning:hover { background: #f9ecc4; }
.session-warning[hidden] { display: none; }

.modal {
    background: var(--surface);
    border-radius: var(--radius);
    box-shadow: 0 12px 40px rgba(0, 0, 0, .25);
    max-width: 480px;
    padding: 24px 28px;
    width: 90%;
}

.modal h2 { margin: 0 0 12px 0; font-size: 18px; }
.modal p  { margin: 0 0 12px 0; }

.modal-actions {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    margin-top: 16px;
}

/* --- Acces traducteur ------------------------------------------------ */

/* Etiquette « profil reduit » a cote du nom du traducteur dans la
   topbar : jaune doux, evocateur d'un mode restreint sans jouer les
   danger. */
.badge-reduced {
    background: var(--warn-bg);
    border: 1px solid #e6d9ab;
    border-radius: 4px;
    color: #6b5417;
    font-size: 11px;
    font-weight: 500;
    padding: 3px 8px;
    text-transform: uppercase;
    letter-spacing: .3px;
}

/* Rangée de badges des permissions dans la liste des acces. */
.access-perms { display: flex; flex-wrap: wrap; gap: 4px; }
.access-perms .badge { font-size: 11px; padding: 2px 8px; }

/* URL d'un jeton fraichement genere : champ readonly + bouton copier. */
.access-url {
    align-items: center;
    display: flex;
    gap: 8px;
    margin: 8px 0;
}
.access-url input {
    border: 1px solid var(--border);
    border-radius: var(--radius);
    flex: 1;
    font: 13px/1.4 ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;
    padding: 8px 10px;
}

/* Champ de type case a cocher : label sur une ligne, aide dessous. */
.field-check label { font-weight: 400; }
.field-check .hint { margin-left: 22px; margin-top: 2px; }

/* ------------------------------------------------------------------- */
/* Tableau de bord / statistiques d'une langue                         */
/* ------------------------------------------------------------------- */
.stats-grid {
    display: grid;
    gap: 12px;
    margin: 0 0 16px 0;
}
.stats-grid-primary   { grid-template-columns: repeat(4, minmax(0, 1fr)); }
.stats-grid-secondary { grid-template-columns: repeat(6, minmax(0, 1fr)); }

.stat-tile {
    background: #fff;
    border: 1px solid #e2e5ea;
    border-radius: 6px;
    padding: 14px 14px 12px 14px;
    text-align: center;
}
.stat-tile-link {
    color: inherit;
    text-decoration: none;
    transition: border-color .1s, box-shadow .1s;
}
.stat-tile-link:hover,
.stat-tile-link:focus {
    border-color: #4a6fa5;
    box-shadow: 0 1px 3px rgba(0,0,0,.06);
}
.stat-tile-value {
    font-size: 22px;
    font-weight: 600;
    line-height: 1;
}
.stat-tile-value-date {
    font-size: 13px;
    font-weight: 500;
}
.stat-tile-label {
    color: #666;
    font-size: 12px;
    margin-top: 6px;
    text-transform: uppercase;
    letter-spacing: .3px;
}
/* Tuiles teintées : mêmes tons que le reste de l'app via les
   variables globales — pas de palette parallèle. */
.stat-tile-ok   { background: #e3f2e8;         color: var(--ok); }
.stat-tile-warn { background: var(--warn-bg);  color: #7a5c12; }
.stat-tile-ko   { background: var(--error-bg); color: var(--ko); }

.stat-tile-progress .progress-bar { margin-top: 8px; }

.progress-bar {
    background: #eef0f3;
    border-radius: 4px;
    height: 6px;
    overflow: hidden;
}
.progress-bar-fill {
    background: linear-gradient(90deg, #6b9c6b, #4a6fa5);
    height: 100%;
    transition: width .3s ease;
}

/* Bande inline : rythme + ETA + mots. */
.stats-inline {
    background: #f8f9fb;
    border: 1px solid #e2e5ea;
    border-radius: 6px;
    display: flex;
    flex-wrap: wrap;
    gap: 28px;
    padding: 10px 14px;
    margin: 0 0 16px 0;
}
.stats-inline-item {
    align-items: baseline;
    display: flex;
    gap: 6px;
}
.stats-inline-label {
    color: #666;
    font-size: 12px;
    text-transform: uppercase;
    letter-spacing: .3px;
}

/* Bandeau « Ma contribution » : discret liseré bleu clair pour
   marquer que la carte est personnelle sans écraser le reste. */
.panel-mine {
    background: linear-gradient(180deg, #f4f7fb, #fff 45%);
    border-color: #cbd6e6;
}

/* Ma contribution : mini grille de 4 tuiles internes. */
.stats-mine-grid {
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: 12px;
    text-align: center;
}
.stats-mine-expiry { margin-top: 12px; text-align: center; }

/* Graphe 30 jours : 30 colonnes, hauteur en pourcentage du max. */
.stats-chart {
    align-items: flex-end;
    background: #f8f9fb;
    border: 1px solid #eef0f3;
    border-radius: 4px;
    display: flex;
    gap: 3px;
    height: 120px;
    padding: 8px 8px 4px 8px;
}
.stats-chart-col {
    display: flex;
    align-items: flex-end;
    flex: 1;
    height: 100%;
}
.stats-chart-bar {
    background: #4a6fa5;
    border-radius: 2px 2px 0 0;
    min-height: 1px;
    width: 100%;
    transition: background .1s;
}
.stats-chart-col:hover .stats-chart-bar { background: #365583; }
.stats-chart-legend {
    display: flex;
    font-size: 11px;
    justify-content: space-between;
    margin-top: 4px;
}

.stats-footer { margin-top: 20px; }

/* Sur mobile, on empile tout proprement. */
@media (max-width: 720px) {
    .stats-grid-primary   { grid-template-columns: repeat(2, 1fr); }
    .stats-grid-secondary { grid-template-columns: repeat(2, 1fr); }
    .stats-columns        { grid-template-columns: 1fr; }
    .stats-mine-grid      { grid-template-columns: repeat(2, 1fr); }
}
