/* Trobot — même registre que le programme Windows : ivoire, encre, bleu. */
:root {
    --fond:   #f8fafc;
    --carte:  #ffffff;
    --encre:  #0f172a;
    --gris:   #64748b;
    --gris-c: #cbd5e1;
    --bleu:   #2563eb;
    --bleu-f: #1d4ed8;
    --rouge:  #dc2626;
    --vert:   #16a34a;
}

* { box-sizing: border-box; }

body {
    margin: 0;
    /* Fond BLANC egaye par de fines rayures diagonales tres discretes (teinte du
       bleu accent). Fixe au defilement pour que le motif ne "glisse" pas. Les
       cartes ont leur propre fond blanc plein : le motif n'apparait qu'autour. */
    background-color: #ffffff;
    background-image: repeating-linear-gradient(
        45deg,
        rgba(37, 99, 235, 0.045) 0px,
        rgba(37, 99, 235, 0.045) 1px,
        transparent 1px,
        transparent 16px
    );
    background-attachment: fixed;
    color: var(--encre);
    font: 14px/1.5 "Segoe UI", Inter, system-ui, sans-serif;
}

a { color: var(--bleu); text-decoration: none; }
a:hover { text-decoration: underline; }

/* ---------------------------------------------------------------- bandeau */

header.bandeau {
    background: var(--carte);
    border-bottom: 1px solid var(--gris-c);
    /* Le bandeau reste en haut quand la liste defile : on ne perd ni les
       onglets ni le compte. */
    position: sticky;
    top: 0;
    z-index: 30;
    padding: 0 24px;
    display: flex;
    align-items: center;
    gap: 18px;
    height: 56px;
}
header.bandeau .marque { font-size: 17px; font-weight: 600; letter-spacing: .3px; }
header.bandeau nav { display: flex; align-items: center; gap: 14px; margin-left: 10px; }
header.bandeau nav a { color: var(--gris); font-size: 13px; white-space: nowrap; }   /* titres toujours sur une ligne */
header.bandeau nav a.actif { color: var(--encre); font-weight: 600; }

/* Barre support : menus déroulants (Définir, Création, Journal). */
header.bandeau nav .menu-nav { position: relative; display: inline-flex; }
header.bandeau nav .onglet-groupe {
    display: inline-flex; align-items: center; gap: 4px;
    background: none; border: 0; padding: 0; cursor: pointer;
    color: var(--gris); font-size: 13px; font-family: inherit;
}
header.bandeau nav .onglet-groupe:hover { color: var(--encre); }
header.bandeau nav .onglet-groupe.actif { color: var(--encre); font-weight: 600; }
header.bandeau nav .onglet-groupe svg { width: 10px; height: 10px; }
header.bandeau nav .sous-nav {
    display: none; position: absolute; left: 0; top: calc(100% + 10px);
    background: var(--carte); border: 1px solid var(--gris-c); border-radius: 4px;
    box-shadow: 0 6px 20px rgba(15, 23, 42, .15); min-width: 190px; z-index: 40; overflow: hidden;
}
header.bandeau nav .sous-nav.ouvert { display: block; }
header.bandeau nav .sous-nav a {
    display: block; padding: 9px 14px; color: var(--encre); font-size: 13px; font-weight: 400;
}
header.bandeau nav .sous-nav a:hover { background: var(--fond); }
header.bandeau nav .sous-nav a.actif { font-weight: 600; background: var(--fond); }
/* Ordinateur : mis en avant dans une bulle jaune, c'est important. */
header.bandeau nav a.onglet-ordi {
    background: #fde68a; color: #713f12; font-weight: 600;
    padding: 4px 13px; border-radius: 999px; border: 1px solid #f59e0b;
}
header.bandeau nav a.onglet-ordi:hover { background: #fcd34d; color: #713f12; }
header.bandeau nav a.onglet-ordi.actif { background: #fbbf24; }
/* Errors (rouge) et Working (vert) : memes pastilles que Ordinateurs DLL. */
header.bandeau nav a.onglet-err,
header.bandeau nav a.onglet-work {
    display: inline-flex; align-items: center; gap: 6px;
    font-weight: 600; padding: 4px 12px; border-radius: 999px;
}
header.bandeau nav a.onglet-err  { background: #fee2e2; color: #991b1b; border: 1px solid #dc2626; }
header.bandeau nav a.onglet-work { background: #dcfce7; color: #166534; border: 1px solid #16a34a; }
header.bandeau nav a.onglet-err:hover  { background: #fecaca; color: #991b1b; }
header.bandeau nav a.onglet-work:hover { background: #bbf7d0; color: #166534; }
header.bandeau nav a.onglet-err.actif  { background: #dc2626; color: #fff; }
header.bandeau nav a.onglet-work.actif { background: #16a34a; color: #fff; }
header.bandeau nav a.onglet-err .nb-onglet  { background: #dc2626; }
header.bandeau nav a.onglet-work .nb-onglet { background: #16a34a; }
header.bandeau nav a.onglet-err.actif .nb-onglet,
header.bandeau nav a.onglet-work.actif .nb-onglet { background: rgba(0,0,0,.28); }
.nb-onglet {
    display: inline-flex; align-items: center; justify-content: center;
    min-width: 18px; height: 18px; padding: 0 5px; border-radius: 9px;
    color: #fff; font-weight: 800; font-size: 11px;
}
header.bandeau .qui { margin-left: auto; color: var(--gris); font-size: 13px; }

main { max-width: 1100px; margin: 26px auto 60px; padding: 0 24px; }

h1 { font-size: 21px; font-weight: 600; margin: 0 0 4px; }
h2 { font-size: 15px; font-weight: 600; margin: 28px 0 10px; }
p.sous { color: var(--gris); margin: 0 0 22px; }

/* ----------------------------------------------------------------- cartes */

.carte {
    background: var(--carte);
    border: 1px solid var(--gris-c);
    border-radius: 4px;
    padding: 20px 22px;
    margin-bottom: 20px;
}

.boutons-menu { display: grid; grid-template-columns: repeat(auto-fill, minmax(230px, 1fr)); gap: 14px; }
.boutons-menu a {
    display: block;
    background: var(--carte);
    border: 1px solid var(--gris-c);
    border-radius: 4px;
    padding: 16px 18px;
    color: var(--encre);
}
.boutons-menu a:hover { border-color: var(--bleu); text-decoration: none; }
.boutons-menu a strong { display: block; font-size: 15px; margin-bottom: 3px; }
.boutons-menu a span { color: var(--gris); font-size: 12.5px; }

/* --------------------------------------------------------------- tableaux */

table { width: 100%; border-collapse: collapse; }
th {
    text-align: left;
    font-size: 11px;
    letter-spacing: .8px;
    text-transform: uppercase;
    color: var(--gris);
    font-weight: 600;
    padding: 0 10px 8px;
    border-bottom: 1px solid var(--gris-c);
}
td { padding: 9px 10px; border-bottom: 1px solid #eef2f6; vertical-align: middle; }
tr:last-child td { border-bottom: none; }
td.actions { text-align: right; white-space: nowrap; }
.vide { color: var(--gris); padding: 18px 10px; }

/* ------------------------------------------------------------ formulaires */

label.champ { display: block; margin-bottom: 14px; }
label.champ span {
    display: block;
    font-size: 11px;
    letter-spacing: .8px;
    text-transform: uppercase;
    color: var(--gris);
    margin-bottom: 5px;
}
input[type=text], input[type=password], input[type=number], input[type=email], select, textarea {
    width: 100%;
    padding: 8px 10px;
    border: 1px solid var(--gris-c);
    border-radius: 3px;
    font: inherit;
    background: #fff;
    color: var(--encre);
}
input:focus, select:focus, textarea:focus { outline: none; border-color: var(--bleu); }
textarea { min-height: 74px; resize: vertical; }

.rangee { display: flex; gap: 16px; flex-wrap: wrap; }
.rangee > label.champ { flex: 1 1 200px; }

button, .bouton {
    display: inline-block;
    border: none;
    border-radius: 3px;
    padding: 9px 18px;
    font: inherit;
    font-weight: 600;
    background: var(--bleu);
    color: #fff;
    cursor: pointer;
}
button:hover, .bouton:hover { background: var(--bleu-f); text-decoration: none; }
button.gris, .bouton.gris { background: #e2e8f0; color: var(--encre); }
button.gris:hover, .bouton.gris:hover { background: #cbd5e1; }
button.rouge, .bouton.rouge { background: var(--rouge); }
button.petit, .bouton.petit { padding: 5px 11px; font-size: 12.5px; font-weight: 500; }

/* ---------------------------------------------------------------- messages */

.flash {
    border: 1px solid var(--gris-c);
    border-left-width: 3px;
    border-radius: 3px;
    padding: 10px 14px;
    margin-bottom: 16px;
    background: var(--carte);
}
.flash.ok  { border-left-color: var(--vert); }
.flash.err { border-left-color: var(--rouge); }

.erreurs {
    border: 1px solid var(--rouge);
    border-left-width: 3px;
    border-radius: 3px;
    background: #fff5f5;
    padding: 10px 14px 10px 30px;
    margin-bottom: 16px;
}
.erreurs li { margin: 2px 0; }

/* --------------------------------------------------------------- connexion */

/* La boîte de connexion est centrée dans la page, à la verticale comme à
   l'horizontale : le conteneur prend toute la hauteur et centre son contenu. */
.ecran-login {
    min-height: 100vh;
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    padding: 24px;
    box-sizing: border-box;
}
.ecran-login > * { width: 100%; max-width: 380px; }
.ecran-login h1 { text-align: center; margin-bottom: 6px; }
.ecran-login p.sous { text-align: center; }

/* ------------------------------------------------------ boutons icônes */

.icones { display: flex; gap: 4px; align-items: center; }

.icone {
    background: none;
    border: 1px solid transparent;
    border-radius: 3px;
    padding: 4px;
    color: var(--gris);
    cursor: pointer;
    line-height: 0;
}
.icone:hover { background: #eef2f6; border-color: var(--gris-c); color: var(--encre); }
.icone.danger:hover { background: #fef2f2; border-color: var(--rouge); color: var(--rouge); }

/* Orange tant que l'ordre attend d'être pris par le poste, gris ensuite.
   La couleur porte l'information : plus besoin d'une phrase à côté. */
.icone.attente,
.icone.attente:hover { color: #ea580c; }
/* Vert : un état allumé (les détails du journal), sans rien à attendre. */
.icone.actif,
.icone.actif:hover { color: #16a34a; }
/* Dans Piloter : l'œil VISIBLE se repère au premier coup d'œil — vert, avec la
   même aura verte que la lampe d'état. L'œil barré (invisible) reste neutre. */
.icone.oeilvu,
.icone.oeilvu:hover {
    color: #15803d;
    border-radius: 6px;
    box-shadow: 0 0 6px 2px rgba(34, 197, 94, 0.55);
}
/* Dans Piloter : un poste EN PAUSE (icône PLAY) se repère au premier coup d'œil
   — rouge, avec une aura rouge, comme l'œil visible en vert. */
.icone.pauserouge,
.icone.pauserouge:hover {
    color: #dc2626;
    border-radius: 6px;
    box-shadow: 0 0 6px 2px rgba(220, 38, 38, 0.55);
}

/* -------------------------------------------------- fenêtre Planning */
table.planning { width: 100%; border-collapse: separate; border-spacing: 0; }
table.planning thead th {
    text-align: left;
    font-size: 10.5px; letter-spacing: .6px; text-transform: uppercase;
    color: #64748b; font-weight: 600;
    padding: 4px 10px 8px; border-bottom: 1px solid var(--gris-c, #e2e8f0);
}
table.planning tbody td { padding: 5px 10px; vertical-align: middle; }
table.planning tbody tr:nth-child(even) { background: #f8fafc; }
table.planning tbody tr:hover { background: #eef4ff; }
table.planning tbody tr td:first-child { border-radius: 8px 0 0 8px; }
table.planning tbody tr td:last-child  { border-radius: 0 8px 8px 0; }
table.planning .pl-num { color: #94a3b8; font-weight: 700; width: 26px; text-align: center; }
table.planning select,
table.planning .pl-heure input {
    padding: 5px 7px; border: 1px solid var(--gris-c, #cbd5e1); border-radius: 7px;
    background: #fff; font: inherit;
}
table.planning select { min-width: 92px; }
table.planning select[id^="pl_act_"] { min-width: 168px; }
/* Heure : HH : MM collés, champs étroits et centrés. */
.pl-heure { white-space: nowrap; }
.pl-heure input { width: 42px; text-align: center; -moz-appearance: textfield; }
.pl-heure input::-webkit-outer-spin-button,
.pl-heure input::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
.pl-sep { font-weight: 800; margin: 0 3px; color: #475569; }
/* Coche verte à côté de l'action ; cliquable (bulle) pour le sélectif. */
.pl-coche { color: #16a34a; font-weight: 800; margin-left: 8px; font-size: 15px; }
.pl-coche.cliquable {
    cursor: pointer; display: inline-flex; align-items: center; justify-content: center;
    width: 22px; height: 22px; border-radius: 50%;
    background: #dcfce7; border: 1px solid #86efac;
}
.pl-coche.cliquable:hover { background: #bbf7d0; }

/* --------------------------------------------------- fenêtres maison */
/* Pas de confirm() du navigateur : il ne sait afficher ni deux listes ni un
   avertissement lisible. */

.voile {
    display: none;
    position: fixed;
    inset: 0;
    background: rgba(15, 23, 42, .45);
    align-items: center;
    justify-content: center;
    z-index: 50;
}
.voile .fenetre {
    background: var(--carte);
    border: 1px solid var(--gris-c);
    border-radius: 4px;
    padding: 22px 24px;
    width: min(520px, 92vw);
    box-shadow: 0 8px 30px rgba(15, 23, 42, .2);
}
.voile .fenetre h2 { font-size: 17px; }
.voile .fenetre p.sous { margin-bottom: 18px; }

.pied { color: var(--gris); font-size: 12px; margin-top: 30px; }
code { background: #eef2f6; padding: 1px 5px; border-radius: 3px; font-size: 12.5px; }

/* Menu contextuel de la liste : celui du navigateur ne peut pas porter nos
   actions, et une colonne de boutons alourdirait un tableau déjà large. */
.menu-contextuel {
    display: none;
    position: absolute;
    z-index: 60;
    background: var(--carte);
    border: 1px solid var(--gris-c);
    border-radius: 4px;
    box-shadow: 0 6px 20px rgba(15, 23, 42, .18);
    padding: 4px 0;
    min-width: 250px;
}
.menu-contextuel a {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 8px 16px;
    color: var(--encre);
    font-size: 13px;
}
.menu-contextuel a svg { flex: none; color: var(--gris); }
.menu-contextuel a.danger svg { color: var(--rouge); }
.menu-contextuel a:hover { background: #eef2f6; text-decoration: none; }

/* Actions propres à la page, dans le bandeau : elles restent au même endroit
   d'une page à l'autre, plutôt que de flotter au-dessus du contenu. */
header.bandeau .actions-page {
    display: flex;
    gap: 8px;
    flex: 1;
    justify-content: center;   /* au milieu du bandeau, entre les onglets et le compte */
}
/* Les trois boutons d'action a la meme largeur (celle du plus large). */
header.bandeau .actions-page button { min-width: 138px; justify-content: center; }

/* Une page qui porte un tableau large. Elle prend ce qu'il lui faut et pas
   plus : le contenu décide, les 90 % ne sont qu'un plafond. */
main.large {
    max-width: 90vw;
    width: fit-content;
    min-width: min(1100px, 90vw);
}

/* Les postes : deux listes déroulantes et une rangée d'icônes par ligne. Rien
   ne revient à la ligne — un nom de magasin coupé en deux se lit mal — et les
   listes gardent leur largeur naturelle pour qu'on voie ce qu'elles contiennent.
   La page s'élargit jusqu'à 90 % de l'écran pour les loger. */
table.postes th,
table.postes td { white-space: nowrap; }
table.postes select { width: auto; max-width: none; }

/* Tableau dense : beaucoup de colonnes chiffrées à faire tenir d'un regard.
   Les nombres ne se coupent jamais en deux lignes ; seul le libellé du
   produit, qui est le seul texte long, a le droit de revenir à la ligne. */
table.compact { font-size: 12px; }
table.compact th {
    font-size: 10px;
    letter-spacing: .6px;
    padding: 0 7px 6px;
    font-weight: 700;   /* noms de colonnes en gras */
}
table.compact td { padding: 5px 7px; white-space: nowrap; }
table.compact td.texte { white-space: normal; min-width: 210px; }

/* Case modifiable posée dans une cellule : elle doit se lire comme une
   valeur du tableau, pas comme un formulaire. */
input.cellule {
    width: 74px;
    padding: 2px 5px;
    font: inherit;
    text-align: right;
    border: 1px solid transparent;
    border-radius: 3px;
    background: #f8fafc;
}
input.cellule:hover  { border-color: var(--gris-c); }
input.cellule:focus  { border-color: var(--bleu); background: #fff; outline: none; }
input.cellule.enregistre { background: #ecfdf5; border-color: var(--vert); }
/* AJOUT vide (donc zéro) : un bleu léger, cadre et fond, pour le repérer. */
input.cellule.vide { background: #eff6ff; border-color: #93c5fd; }
input.cellule.vide:focus { background: #fff; border-color: var(--bleu); }

/* Une ligne qui vient de changer, ou celle qu'on cherchait : elle s'éclaire
   le temps qu'on la trouve des yeux, puis redevient une ligne comme une autre. */

/* L'entrée destructrice d'un menu contextuel : rouge, et détachée des autres
   par un filet — pour qu'on ne la clique pas en visant celle du dessus. */
.menu-contextuel a.danger {
    color: var(--rouge);
    border-top: 1px solid var(--gris-c);
    margin-top: 4px;
    padding-top: 8px;
}
.menu-contextuel a.danger:hover { background: #fef2f2; }

/* Dans la liste, le curseur reste une flèche : sans cela il se change en barre
   de saisie au-dessus du moindre chiffre, et il clignote sans arrêt quand on
   parcourt le tableau. Seules les cases qu'on remplit gardent la barre. */
table.compact,
table.compact th,
table.compact td { cursor: default; }
table.compact input.cellule { cursor: text; }

/* La fiche d'un article : deux colonnes serrées, le libellé puis la valeur.
   Pas de filets — ce sont des couples, pas un tableau à parcourir. */
.voile .fenetre table td { border: none; padding: 3px 12px 3px 0; }
.voile .fenetre table td:first-child { white-space: nowrap; }
.voile .fenetre h2 { margin: 22px 0 6px; }
.voile .fenetre h2:first-child { margin-top: 0; }

/* Une ligne que le programme vient de mettre à jour : deux clignotements verts
   francs, puis le vert s'efface doucement. Le jaune fixe d'avant ne disait pas
   si le changement venait d'arriver ou traînait là depuis une minute — un
   mouvement, lui, attire l'œil au bon moment et ne survit pas à l'instant. */
@keyframes maj-verte {
      0% { background: #dcfce7; }
     12% { background: transparent; }
     24% { background: #dcfce7; }
     36% { background: transparent; }
     48% { background: #dcfce7; }
    100% { background: transparent; }
}
tr.majour td { animation: maj-verte 2.4s ease-out; }

/* La ligne qu'on cherchait — un HOPE déjà présent — reste en jaune : elle ne
   signale pas un changement, elle répond à « laquelle ? ». */
tr.surligne td { background: #fef9c3; transition: background .6s; }

/* La lampe d'état d'un poste : une petite lumière ronde, allumée. Le dégradé
   met un reflet en haut à gauche et l'ombre colorée fait le halo — c'est ce
   qui la distingue d'une simple pastille plate. Verte : en route. Rouge :
   arrêté. Le mot reste dans l'infobulle pour qui veut le lire. */
.lampe {
    display: inline-block;
    width: 13px;
    height: 13px;
    border-radius: 50%;
    vertical-align: middle;
    border: 1px solid rgba(0, 0, 0, 0.18);
}
.lampe.verte {
    background: radial-gradient(circle at 35% 30%, #bbf7d0 0, #22c55e 45%, #15803d 100%);
    box-shadow: 0 0 6px 2px rgba(34, 197, 94, 0.55), inset 0 0 2px rgba(255, 255, 255, 0.6);
}
.lampe.rouge {
    background: radial-gradient(circle at 35% 30%, #fecaca 0, #ef4444 45%, #b91c1c 100%);
    box-shadow: 0 0 6px 2px rgba(239, 68, 68, 0.55), inset 0 0 2px rgba(255, 255, 255, 0.6);
}

/* La barre d'ajout d'un HOPE reste visible sous le bandeau quand la liste
   défile : on encode un article sans avoir à remonter. */
.barre-hope {
    position: sticky;
    top: 56px;
    z-index: 20;
}

/* Une bulle de comptage dans le bandeau, à côté des onglets : le nombre
   d'articles que le programme a encore à traiter pour ce magasin. */
header.bandeau .bulle {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    margin-left: 4px;
}
header.bandeau .bulle .nb {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 20px;
    height: 20px;
    padding: 0 6px;
    border-radius: 10px;
    background: var(--bleu);
    color: #fff;
    font-size: 12px;
    font-weight: 600;
}
header.bandeau .bulle .nb.zero { background: var(--gris-c); color: var(--gris); }
header.bandeau .bulle a.det {
    display: inline-flex;
    color: var(--gris);
    line-height: 0;
}
header.bandeau .bulle a.det:hover { color: var(--encre); }

/* Un bouton d'action avec une icône à sa gauche. */
.bouton-ic {
    display: inline-flex;
    align-items: center;
    gap: 6px;
}
.bouton-ic svg { display: block; }

/* En-tête du tableau de la liste : collant, sous le bandeau et la barre
   d'ajout. Le décalage exact (--thead-top) est posé par le JS, qui mesure la
   hauteur des deux bandes au-dessus ; la valeur ici n'est qu'un repli. */
table.compact thead th {
    position: sticky;
    top: var(--thead-top, 130px);
    background: var(--carte);
    z-index: 15;
    box-shadow: inset 0 -1px 0 var(--gris-c);
}
table.compact thead th .ent-titre { display: block; }
/* En-tête triable (Marge, Stats, Gain) : le curseur main dit qu'on peut cliquer,
   et une flèche apparaît sur la colonne active. */
table.compact thead th.triable { cursor: pointer; user-select: none; }
table.compact thead th.triable:hover .ent-titre { color: var(--encre); }
table.compact thead th .tri-fl { font-size: 9px; color: var(--accent, #2563eb); }
/* Le trait neutre d'une colonne triable pas encore triée : un trait horizontal
   NET et épais (dessiné en bordure, pas un simple tiret) pour bien se voir, tout
   en restant plus discret que la flèche de la colonne active. */
table.compact thead th .tri-fl.muet {
    opacity: .6;
    font-size: 0;                 /* on masque le tiret texte, on dessine le trait */
    display: inline-block;
    width: 11px; height: 0;
    border-top: 3px solid var(--accent, #2563eb);
    border-radius: 2px;
    vertical-align: middle;
    margin-left: 4px;
}

/* Les deux champs de filtre, sous HOPE et sous Produit. Discrets au repos, ils
   se marquent quand ils portent un filtre actif (classe posée par le JS). */
.filtre {
    width: 100%;
    box-sizing: border-box;
    margin-top: 3px;
    padding: 2px 5px;
    font-size: 11px;
    font-weight: 400;
    text-transform: none;
    letter-spacing: 0;
    border: 1px solid var(--gris-c);
    border-radius: 3px;
    background: var(--fond);
}
.filtre:focus { outline: none; border-color: var(--bleu); background: var(--carte); }
.filtre.actif { border-color: var(--bleu); background: #eff6ff; }
/* Le filtre HOPE doit pouvoir accueillir 6 chiffres : marges intérieures
   gauche/droite réduites pour gagner de la place sans élargir la colonne. */
#filtreHope { padding-left: 2px; padding-right: 2px; }

/* Un bouton désactivé (ex. STOP quand il n'y a rien à arrêter) : grisé, sans
   interaction. */
button:disabled,
button[disabled] {
    opacity: .45;
    cursor: not-allowed;
    filter: grayscale(1);
}

/* Bulle d'état du programme : WORKING (vert), WAITING (orange), SLEEPING
   (jaune), ERROR (rouge). Une pastille compacte, lisible d'un coup d'œil. */
.bulle-etat {
    display: inline-block;
    padding: 3px 11px;
    border-radius: 999px;
    font-size: 11px;
    font-weight: 800;
    letter-spacing: .6px;
    color: #fff;
    white-space: nowrap;
    vertical-align: middle;
    /* Toutes les bulles d'etat (WORKING, PAUSE, WAKING UP...) a la meme largeur,
       texte centre, pour un alignement net dans PILOTER. */
    min-width: 96px;
    box-sizing: border-box;
    text-align: center;
}
.bulle-etat.etat-working  { background: #16a34a; }
.bulle-etat.etat-waiting  { background: #f97316; }
.bulle-etat.etat-sleeping { background: #eab308; color: #422006; }
.bulle-etat.etat-error    { background: #dc2626; }
.bulle-etat.etat-pause    { background: #2563eb; }
.bulle-etat.etat-close    { background: #991b1b; }
.bulle-etat.etat-waking   { background: #0891b2; }

/* Message « chargement du reste » à côté d'Ajouter : vert, clignotant, tant
   que les pages de fond arrivent. */
.charge-reste {
    display: inline-block;
    margin-left: 12px;
    color: #16a34a;
    font-weight: 700;
    font-size: 12px;
    white-space: nowrap;
    animation: clign-verte 1s ease-in-out infinite;
}
@keyframes clign-verte { 0%, 100% { opacity: 1; } 50% { opacity: .25; } }

/* Sélection à la souris : les lignes retenues (clic, Ctrl+clic, Maj/Alt+clic)
   se teintent de bleu, quelle que soit la rayure ou le survol. Le curseur
   « main » invite à cliquer pour sélectionner. */
table.compact tbody tr td { cursor: default; }
table.compact tbody tr.selectionne > td { background: #dbeafe !important; }
table.compact tbody tr.selectionne:hover > td { background: #cfe0fd !important; }
/* Pas de sélection de texte parasite lors d'un Maj/Alt+clic en bloc. */
table.compact tbody { -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; }
table.compact tbody input { -webkit-user-select: text; -moz-user-select: text; -ms-user-select: text; user-select: text; }

/* Tous les titres de colonnes au même niveau : en haut de la cellule, même
   quand la colonne HOPE porte deux filtres sous son titre. */
table.compact thead th { vertical-align: top; }

/* Le gain potentiel total, dans le bandeau tout en haut : une bulle verte. */
.extra-bandeau { display: inline-flex; align-items: center; margin-left: 8px; }
.bulle-verte {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 6px 14px;
    border-radius: 16px;
    background: #dcfce7;
    color: #166534;
    border: 1px solid #86efac;
    font-size: 13px;
}
.bulle-verte strong { font-size: 13px; }

/* Le compte : un carré de couleur portant le nom, qui ouvre un petit menu. */
.compte { position: relative; display: inline-block; margin-left: 8px; }
.compte .pastille {
    border: none;
    color: #fff;
    font-size: 12px;
    font-weight: 600;
    padding: 4px 10px;
    border-radius: 4px;
    cursor: pointer;
    line-height: 1.4;
}
.compte .menu-compte {
    display: none;
    position: absolute;
    right: 0;
    top: calc(100% + 6px);
    background: var(--carte);
    border: 1px solid var(--gris-c);
    border-radius: 4px;
    box-shadow: 0 6px 20px rgba(15, 23, 42, .15);
    min-width: 200px;
    z-index: 40;
    overflow: hidden;
}
.compte .menu-compte.ouvert { display: block; }
.compte .menu-compte a {
    display: block;
    padding: 9px 14px;
    color: var(--encre);
    font-size: 13px;
}
.compte .menu-compte a:hover { background: var(--fond); }
.compte .menu-compte a { display: flex; align-items: center; gap: 9px; }
.compte .menu-compte a.actif { font-weight: 600; background: var(--fond); }
.compte .menu-compte .drapeau { border: 1px solid var(--gris-c); border-radius: 2px; flex: none; }
.compte .menu-compte .sep { display: block; height: 1px; background: var(--gris-c); margin: 4px 0; }

/* La version du site, discrète à côté du nom. */
header.bandeau .marque .version { font-size: 11px; font-weight: 400; color: var(--gris); }

/* Le bouton Actions et son menu déroulant, dans le bandeau. */
.menu-bloc { position: relative; display: inline-flex; }
.menu-bloc .menu-deroulant {
    display: none;
    position: absolute;
    right: 0;
    /* Colle au bouton (pas d'ecart) pour que le survol reste continu du bouton
       vers le menu. */
    top: 100%;
    background: var(--carte);
    border: 1px solid var(--gris-c);
    border-radius: 4px;
    box-shadow: 0 6px 20px rgba(15, 23, 42, .15);
    width: max-content;
    max-width: 90vw;
    z-index: 40;
    overflow: hidden;
    text-align: left;
}
.menu-bloc .menu-deroulant.ouvert { display: block; }
/* Ouverture AU SURVOL du bloc (bouton + menu). Le sous-menu (flyout) reste
   gere par sa propre regle :hover plus bas. */
.menu-bloc:hover > .menu-deroulant { display: block; }
.menu-bloc .menu-deroulant a {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 10px 14px;
    color: var(--encre);
    font-size: 13px;
    white-space: nowrap;
}
.menu-bloc .menu-deroulant a:hover { background: var(--fond); text-decoration: none; }
.menu-bloc .menu-deroulant a svg { flex: none; color: var(--gris); }

/* La case POURCENTAGE : l'input suivi d'un « % ». */
.case-mod { display: inline-flex; align-items: center; gap: 2px; }
.case-mod .suffixe { color: var(--gris); font-size: 11px; }

/* La coche d'une option d'affichage active : cachée par défaut, visible quand
   l'option porte la classe .coche-on. */
.menu-deroulant a .coche { visibility: hidden; }
.menu-deroulant a.coche-on .coche { visibility: visible; }
/* La boule verte (mode actif en tête, ou choix unique de « Afficher uniquement ») :
   cachée par défaut, visible quand la ligne porte .boule-on. */
.menu-deroulant .boule { visibility: hidden; }
.menu-deroulant .boule-on .boule { visibility: visible; }
.menu-deroulant .sm-a .sm-lbl { display: inline-flex; align-items: center; gap: 8px; }

/* Sous-menus (flyout) du menu Affichage : un titre avec une flèche à droite qui
   ouvre un second menu déroulant à sa droite au survol. Le menu parent doit
   laisser DEBORDER le flyout (sinon overflow:hidden le coupe). */
#menuAffichage, #menuCheckAll { overflow: visible; }
.menu-deroulant .sm-parent { position: relative; }
.menu-deroulant .sm-parent > .sm-a {
    display: flex; align-items: center; justify-content: space-between; gap: 12px;
    padding: 10px 14px; color: var(--encre); font-size: 13px; white-space: nowrap; cursor: default;
}
.menu-deroulant .sm-parent > .sm-a:hover { background: var(--fond); }
.menu-deroulant .sm-parent > .sm-a svg { flex: none; color: var(--gris); }
/* Le flyout : positionné à droite du parent, masqué sauf au survol du parent. */
.menu-deroulant .sm-fly {
    left: 100%; right: auto; top: -1px; width: max-content;
}
.menu-deroulant .sm-parent:hover > .sm-fly { display: block; }

/* La bulle « en travail » : verte, avec le sablier. */
header.bandeau .bulle.bulle-travail { color: #166534; }
header.bandeau .bulle-travail .nb { background: var(--vert); color: #fff; gap: 5px; }
header.bandeau .bulle-travail .nb svg { flex: none; }

/* Le compteur en tête du menu Affichage. */
.menu-deroulant .menu-info {
    padding: 8px 14px;
    font-size: 12px;
    color: var(--gris);
    border-bottom: 1px solid var(--gris-c);
}

/* La table de la fenêtre « Informations sur les articles ». */
table.infos-articles { width: 100%; }
table.infos-articles td { padding: 7px 4px; border-bottom: 1px solid #eef2f6; }
table.infos-articles td.v { text-align: right; font-weight: 600; white-space: nowrap; }

/* Séparateur dans un menu déroulant. */
.menu-deroulant .sep { display: block; height: 1px; background: var(--gris-c); margin: 4px 0; }

/* Un HOPE hors assortiment : une bulle rouge léger dans la colonne HOPE. */
.hope-hors {
    display: inline-block;
    padding: 1px 7px;
    border-radius: 10px;
    background: #fef2f2;
    border: 1px solid #fecaca;
    color: #b91c1c;
    cursor: help;
}

/* Les cases à cocher des magasins d'un compte. */
.cases-magasins { display: flex; flex-direction: column; gap: 4px; margin-top: 4px; }
.cases-magasins .case {
    display: flex; align-items: center; gap: 8px;
    text-transform: none; letter-spacing: 0; font-size: 13px; color: var(--encre);
}

/* Le bouton magasin (carré) et son menu, à gauche de CHECK ALL. */
header.bandeau .actions-page button.carre { min-width: 0; padding: 5px 8px; }

/* Fenêtre « Promotions Delhaize » : hauteur fixe, seule la liste des articles
   défile ; le titre, les cases et la semaine restent en place. */
.pd-fenetre {
    width: min(1100px, 98vw);
    height: min(88vh, 820px);
    display: flex;
    flex-direction: column;
    overflow: hidden;
    position: relative;
}
/* Bouton fermer fixe en haut à droite. */
.pd-fermer {
    position: absolute; top: 10px; right: 12px;
    width: 30px; height: 30px; padding: 0;
    border: 1px solid var(--gris-c); border-radius: 50%;
    background: var(--carte); color: var(--encre);
    font-size: 20px; line-height: 1; cursor: pointer;
    display: flex; align-items: center; justify-content: center;
    z-index: 5;
}
.pd-fermer:hover { background: var(--fond); }
.pd-titre { margin: 0 40px 6px 0; }
.pd-appliquer { font-weight: 600; margin: 2px 0 10px; }
/* Les cinq groupes, sur plusieurs colonnes selon la largeur (libellés longs). */
.pd-types { columns: 330px; column-gap: 24px; margin-bottom: 12px; }
.pd-type {
    display: flex; align-items: baseline; gap: 8px;
    break-inside: avoid; margin: 4px 0;
    font-size: 13px;
}
.pd-barre { display: flex; align-items: flex-end; gap: 16px; margin-bottom: 8px; }
/* Fenêtre Assortiment. Boutons bascule d'affichage, tous de MÊME largeur, avec un
   œil : VERT = affiché + œil ouvert (par défaut), ROUGE = masqué + œil fermé. */
.pd-barre .as-toggle {
    display: inline-flex; align-items: center; gap: 7px;
    width: 178px; justify-content: flex-start;
    background: #16a34a; color: #fff; border: none;
}
.pd-barre .as-toggle.actif { background: #dc2626; color: #fff; }
.as-toggle .oeil-off { display: none; }
.as-toggle.actif .oeil-on { display: none; }
.as-toggle.actif .oeil-off { display: inline; }

/* Le tableau de l'assortiment : colonnes à la largeur du contenu (pas étirées),
   HOPE en chasse fixe SANS fond gris, lignes vertes = déjà dans la liste. */
.as-table { border-collapse: collapse; }
.as-table th, .as-table td { padding: 4px 14px; white-space: nowrap; text-align: left; vertical-align: middle; }
.as-table th {
    font-size: 11px; letter-spacing: .04em; text-transform: uppercase;
    color: var(--gris); border-bottom: 1px solid var(--gris-c);
}
.as-table tbody tr { border-bottom: 1px solid #eef2f6; }
.as-table tbody tr:hover { background: #f1f5f9; }
.as-table tr.deja { background: #dcfce7; }
.as-table tr.deja:hover { background: #bbf7d0; }
.as-hope { font-family: Consolas, monospace; }
.as-pct { width: 58px; text-align: right; }
.as-ajout { text-align: right; font-weight: 600; }
/* La seule zone qui défile — verticalement seulement. */
.pd-liste {
    flex: 1; min-height: 0; overflow-y: auto; overflow-x: hidden;
    border: 1px solid var(--gris-c); border-radius: 8px; padding: 4px;
}
.pd-art {
    display: flex; align-items: center; gap: 10px;
    padding: 7px 6px; border-bottom: 1px solid #eef2f6;
}
.pd-art:last-child { border-bottom: none; }
/* Images produit SANS cadre : ni bordure, ni fond. */
.pd-art img.pd-img, .pd-art .pd-vide-img {
    width: 50px; height: 50px; flex: none;
}
.pd-art img.pd-img { object-fit: contain; }
/* Le bloc texte prend la place restante et peut retrecir (pas de scroll
   horizontal : le texte passe a la ligne). */
.pd-art .pd-txt { flex: 1; min-width: 0; }
.pd-art .pd-nom { font-weight: 600; }
.pd-art .pd-nom .pd-nl { font-weight: 400; color: var(--gris); }
.pd-art .pd-sous { color: var(--gris); font-size: 12px; }
/* Le badge du GROUPE de promo, a droite de chaque article. */
.pd-art .pd-grp {
    flex: none; align-self: center;
    padding: 2px 9px; border-radius: 11px;
    background: #fef9c3; border: 1px solid #fde047; color: #854d0e;
    font-size: 12px; font-weight: 600; white-space: nowrap;
}

/* Le sablier de chargement (ouverture d'un magasin). */
.sablier-charge {
    width: 34px; height: 34px; margin: 4px auto 0;
    border: 3px solid var(--gris-c);
    border-top-color: var(--bleu);
    border-radius: 50%;
    animation: tourne 0.8s linear infinite;
}
@keyframes tourne { to { transform: rotate(360deg); } }

/* Un prix en promotion : bulle mauve autour du prix offre. */
.prix-promo {
    display: inline-block;
    padding: 1px 7px;
    border-radius: 10px;
    background: #f5f3ff;
    border: 1px solid #c4b5fd;
    color: #6d28d9;
}
/* Nouveau prix d'un article en promo, magasin suivant les promos : pendant la
   promo le prix ne bouge pas, il reste au prix OFFICIEL. Bulle JAUNE pour le
   distinguer d'un nouveau prix ordinaire. */
.prix-offre-promo {
    display: inline-block;
    padding: 1px 7px;
    border-radius: 10px;
    background: #fef9c3;
    border: 1px solid #fde047;
    color: #854d0e;
    font-weight: 700;
}
/* Le petit « WEEK » a droite du logo lion (P'tit Lion de la SEMAINE). */
.lion-week {
    font-size: 9px; font-weight: 800; letter-spacing: .5px;
    color: #1e293b; background: #e2e8f0; border-radius: 4px;
    padding: 0 3px; line-height: 1.5;
}

/* Petit badge JAUNE en fin de nom : le type de promo Delhaize abrege. */
.promo-badge {
    display: inline-block;
    margin-left: 5px;
    padding: 0 6px;
    border-radius: 9px;
    background: #fef9c3;
    border: 1px solid #fde047;
    color: #854d0e;
    font-size: 11px;
    font-weight: 600;
    white-space: nowrap;
    vertical-align: middle;
}
