/* ================================================================== *
 *  style.css — Shell SaaS (sidebar + main) · sans framework           *
 * ================================================================== */

:root {
    --bg:            #f7f8fa;
    --surface:       #ffffff;
    --surface-2:     #f9fafb;
    --border:        #e5e7eb;
    --border-soft:   #eef0f3;
    --text:          #1f2430;
    --muted:         #6b7280;
    --muted-2:       #9ca3af;
    --accent:        #2563eb;
    --accent-ink:    #1d4ed8;
    --accent-soft:   #eef2ff;
    --ok-bg:         #ecfdf5;  --ok-bd: #a7f3d0;  --ok-ink: #065f46;
    --err-bg:        #fef2f2;  --err-bd: #fecaca;  --err-ink: #991b1b;
    --warn-bg:       #fffbeb;  --warn-bd: #fde68a; --warn-ink: #92400e;
    --info-bg:       #eff6ff;  --info-bd: #bfdbfe; --info-ink: #1e40af;
    --shadow:        0 1px 2px rgba(16,24,40,.04), 0 1px 3px rgba(16,24,40,.06);
    --shadow-lg:     0 10px 30px rgba(16,24,40,.10);
    --radius:        12px;
    --radius-sm:     8px;
    --sidebar-w:     264px;
}

* { box-sizing: border-box; }

html, body { height: 100%; }

body {
    margin: 0;
    background: var(--bg);
    color: var(--text);
    font-family: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
    font-size: 14px;
    line-height: 1.5;
    -webkit-font-smoothing: antialiased;
}

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

h1 { font-size: 20px; font-weight: 650; margin: 0; letter-spacing: -.01em; }

code {
    background: var(--surface-2);
    border: 1px solid var(--border);
    padding: 1px 6px;
    border-radius: 6px;
    font-size: 12px;
    font-family: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
}

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

/* ================================================================== *
 *  Structure : app = sidebar + main                                  *
 * ================================================================== */
.app { display: flex; min-height: 100vh; }

/* --- Sidebar --- */
/* La sidebar ne défile PAS d'un bloc : seul .nav défile (overflow-y), ce qui
   laisse .sidebar-head collée en haut et .sidebar-foot collée en bas, sans
   position:sticky imbriqué. D'où overflow:hidden ici. */
.sidebar {
    width: var(--sidebar-w);
    flex: 0 0 var(--sidebar-w);
    background: var(--surface);
    border-right: 1px solid var(--border);
    padding: 16px 12px;
    position: sticky;
    top: 0;
    height: 100vh;
    overflow: hidden;
    display: flex;
    flex-direction: column;
    gap: 6px;
}

/* Le trait de séparation porte sur la tête entière (logo + éventuel bandeau
   « mode production »), pas sur le seul logo. */
.sidebar-head {
    flex: 0 0 auto;
    padding-bottom: 14px;
    border-bottom: 1px solid var(--border-soft);
    margin-bottom: 8px;
    transition: padding-bottom .15s ease, margin-bottom .15s ease;
}
.brand {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 6px 8px 0;
    color: var(--text);
}
.brand:hover { text-decoration: none; }
.brand-mark {
    width: 30px; height: 30px;
    display: grid; place-items: center;
    background: var(--accent);
    color: #fff;
    font-weight: 700;
    border-radius: 8px;
    font-size: 15px;
    transition: width .15s ease, height .15s ease, font-size .15s ease;
}
.brand-name { font-weight: 650; font-size: 14px; letter-spacing: -.01em; }

/* --- Tête compacte : classe posée par assets/sidebar.js dès que .nav défile --- */
/* Le logo rétrécit et le bandeau « mode production » se réduit à son titre :
   la liste des modules récupère la hauteur ainsi libérée. */
.sidebar-compact .sidebar-head { padding-bottom: 8px; margin-bottom: 4px; }
.sidebar-compact .brand { padding-top: 0; }
.sidebar-compact .brand-mark { width: 22px; height: 22px; font-size: 12px; border-radius: 6px; }
.sidebar-compact .brand-name { font-size: 13px; }
/* L'engrenage suit le logo : sans ces règles il garde ses 34px et son
   margin-top:6px (calé sur le padding de .brand, annulé en compact). */
.sidebar-compact .brand-cog { margin-top: 0; width: 26px; height: 26px; font-size: 19px; }
.sidebar-compact .mode-widget { margin-top: 8px; padding: 4px 8px; font-size: 11px; }
.sidebar-compact .mode-widget-txt { display: none; }
.sidebar-compact .mode-widget strong { display: inline; }

/* .nav est la SEULE zone défilante de la sidebar (min-height:0 : sans lui, un
   enfant flex refuse de rétrécir sous sa hauteur de contenu et déborde). */
.nav {
    display: flex;
    flex-direction: column;
    gap: 2px;
    flex: 1 1 auto;
    min-height: 0;
    overflow-y: auto;
    overscroll-behavior: contain;
}

.nav-item {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 8px 10px;
    border-radius: var(--radius-sm);
    color: var(--text);
    font-size: 13.5px;
    font-weight: 500;
}
.nav-item:hover { background: var(--surface-2); text-decoration: none; }
.nav-item.active { background: var(--accent-soft); color: var(--accent-ink); font-weight: 600; }
/* Porte-pictogramme de la navigation : gabarit fixe, que le contenu soit un
   SVG du jeu d'icônes ou un emoji hérité (icon_or_text). */
.nav-ico {
    width: 18px; flex: 0 0 18px;
    display: inline-flex; align-items: center; justify-content: center;
    opacity: .9; font-size: 14px; line-height: 1;
}
.nav-ico .icon { width: 17px; height: 17px; }

.nav-group {
    margin-top: 10px;
    padding-top: 10px;
    border-top: 1px solid var(--border-soft);
    display: flex;
    flex-direction: column;
    gap: 2px;
}
.nav-module { font-weight: 600; cursor: pointer; list-style: none; user-select: none; }
.nav-module::-webkit-details-marker { display: none; }
/* Repère « + » / « − » : le groupe (<details>) se déplie au clic sur le nom. */
.nav-module::after { content: "+"; margin-left: auto; color: var(--muted); font-weight: 400; font-size: 16px; line-height: 1; }
.nav-group[open] > .nav-module::after { content: "−"; }

.nav-sub { list-style: none; margin: 2px 0 2px; padding: 0 0 0 6px; }
.nav-subitem {
    display: flex;
    align-items: center;
    gap: 9px;
    padding: 6px 10px;
    margin-left: 6px;
    border-left: 2px solid var(--border);
    color: var(--muted);
    font-size: 13px;
    border-radius: 0 6px 6px 0;
}
.nav-subitem:hover { background: var(--surface-2); color: var(--text); text-decoration: none; }
.nav-subitem.active {
    color: var(--accent-ink);
    background: var(--accent-soft);
    border-left-color: var(--accent);
    font-weight: 600;
}
.nav-subtxt { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* Nombre de lignes du listing (core/layout.php, nav_count()). */
.nav-count {
    margin-left: auto;
    flex-shrink: 0;
    font-size: 11.5px;
    font-weight: 400;
    color: var(--muted);
    font-variant-numeric: tabular-nums;
}
/* Page enfant d'une autre page (clé 'parent' dans module.php) : en retrait. */
.nav-subitem.nav-child { margin-left: 24px; font-size: 12.5px; }

.dot {
    width: 7px; height: 7px; border-radius: 50%;
    background: var(--muted-2);
    flex: 0 0 7px;
    opacity: .5;
}
.dot-on { background: #22c55e; opacity: 1; }

.nav-action { color: var(--muted); font-size: 13px; }
.nav-action:hover { color: var(--accent-ink); }

/* --- Main --- */
.main { flex: 1 1 auto; min-width: 0; }
/* Convention : le contenu occupe toute la largeur disponible,
   avec seulement 20px de marge de chaque côté (jamais collé aux bords). */
.main-inner { width: 100%; max-width: none; margin: 0; padding: 28px 20px 48px; }

/* Bandeau de titre (dans le main, pas un header) */
.page-head {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 16px;
    flex-wrap: wrap;
    margin-bottom: 22px;
}
.page-head h1 { margin-bottom: 4px; }
/* « (148) » ou « (12 / 148) » : core/layout.php compteur_titre(), dashboard.js. */
.title-count { color: var(--muted); font-weight: 400; font-variant-numeric: tabular-nums; }
.page-sub { color: var(--muted); font-size: 13px; margin: 0; }
.page-head-actions { display: flex; gap: 8px; flex-wrap: wrap; }

/* ================================================================== *
 *  Composants                                                        *
 * ================================================================== */

/* --- Icônes (SVG en ligne, voir core/icons.php) --- */
/* Une icône hérite de la couleur du texte et se dimensionne ici, jamais dans le
   HTML : un même pictogramme sert donc dans un bouton, un badge ou un titre
   sans que le gabarit ne dépende du contexte. `flex: 0 0 auto` l'empêche d'être
   compressée quand le libellé voisin est long. */
.icon {
    width: 17px; height: 17px;
    flex: 0 0 auto;
    display: block;
    vertical-align: middle;
    pointer-events: none;   /* le clic vise toujours le bouton, jamais le tracé */
}
.icon-sm { width: 14px; height: 14px; }
/* Chevron de fin de bouton déroulant : plus discret que le pictogramme de tête,
   qui, lui, porte le sens du bouton. */
.icon-caret { opacity: .5; margin-left: -1px; }
.icon-lg { width: 20px; height: 20px; }
.icon-xl { width: 22px; height: 22px; }

/* Icône posée sur une pastille teintée : sert de vignette de tuile ou d'en-tête
   de section. Les variantes reprennent le code couleur des statuts. */
.icon-chip {
    display: inline-flex; align-items: center; justify-content: center;
    width: 32px; height: 32px; flex: 0 0 auto;
    border-radius: 9px;
    background: var(--surface-2);
    border: 1px solid var(--border-soft);
    color: var(--muted);
}
.icon-chip-accent { background: var(--accent-soft); border-color: #dbe3ff; color: var(--accent-ink); }
.icon-chip-ok     { background: var(--ok-bg);   border-color: var(--ok-bd);   color: var(--ok-ink); }
.icon-chip-err    { background: var(--err-bg);  border-color: var(--err-bd);  color: var(--err-ink); }
.icon-chip-warn   { background: var(--warn-bg); border-color: var(--warn-bd); color: var(--warn-ink); }

/* --- Boutons --- */
/* Hauteur commune à tous les contrôles de barre d'outils (--control-h) : sans
   elle, un bouton, un champ de recherche et un select ne s'alignent pas et la
   barre paraît bricolée. */
:root { --control-h: 38px; }

.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    min-height: var(--control-h);
    padding: 0 14px;
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    background: var(--surface);
    color: var(--text);
    font-size: 13.5px;
    font-weight: 550;
    cursor: pointer;
    white-space: nowrap;
    box-shadow: var(--shadow);
    transition: background .12s, border-color .12s, color .12s, transform .04s;
}
.btn:hover { background: var(--surface-2); border-color: var(--muted-2); text-decoration: none; }
.btn:active { transform: translateY(1px); }
.btn:focus-visible { outline: none; box-shadow: 0 0 0 3px rgba(37,99,235,.22); }
.btn:disabled { opacity: .5; cursor: default; box-shadow: none; }
.btn:disabled:hover { background: var(--surface); border-color: var(--border); }

/* L'icône d'un bouton est légèrement plus discrète que le texte : à couleur
   égale, un tracé plein paraît plus lourd qu'un libellé. */
.btn .icon { opacity: .85; }
.btn:hover .icon { opacity: 1; }

.btn-primary { background: var(--accent); border-color: var(--accent); color: #fff; }
.btn-primary:hover { background: var(--accent-ink); border-color: var(--accent-ink); }
.btn-primary .icon { opacity: .95; }
.btn-danger { background: var(--err-ink); border-color: var(--err-ink); color: #fff; }
.btn-danger:hover { background: var(--err-ink); border-color: var(--err-ink); filter: brightness(.9); }

/* Bouton sans libellé : carré, l'icône occupe toute la surface utile. Le titre
   (title=) porte le sens — un bouton icône seule sans title est un piège. */
.btn-icon { width: var(--control-h); padding: 0; }
.btn-icon .icon { width: 18px; height: 18px; }

/* --- Barre d'action de masse (à côté de « Réimporter ») --- */
/* Affichée par dashboard.js dès qu'au moins une ligne est cochée. */
.bulk-bar {
    display: inline-flex; align-items: center; gap: 8px;
    padding: 4px 6px 4px 12px;
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    background: var(--accent-soft);
}
.bulk-bar[hidden] { display: none; }
.bulk-count { font-size: 12.5px; font-weight: 600; color: var(--accent-ink); white-space: nowrap; }
.bulk-select {
    padding: 7px 10px;
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    background: var(--surface);
    color: var(--text);
    font-size: 13.5px;
}

.link-btn {
    border: none; background: none; color: var(--accent);
    cursor: pointer; font-size: 13px; padding: 0; font-weight: 550;
}
.link-btn:hover { text-decoration: underline; }

/* --- Alertes --- */
.alert { padding: 13px 16px; border-radius: var(--radius-sm); margin: 0 0 20px; border: 1px solid; }
.alert-ok  { background: var(--ok-bg);  border-color: var(--ok-bd);  color: var(--ok-ink); }
.alert-err { background: var(--err-bg); border-color: var(--err-bd); color: var(--err-ink); }
.alert-warn { background: var(--warn-bg); border-color: var(--warn-bd); color: var(--warn-ink); }
/* Neutre : ce que l'écran ne montre pas, et pourquoi (ni succès ni anomalie). */
.alert-info { background: var(--surface); border-color: var(--border); color: var(--text); }
.alert details { margin-top: 6px; }
.alert summary { cursor: pointer; font-size: 12.5px; }
.alert details p { margin: 6px 0 0; font-size: 12.5px; }

/* --- Statistiques (accueil) --- */
.stats { margin-bottom: 28px; }
.stats-title {
    font-size: 12px; font-weight: 600; text-transform: uppercase;
    letter-spacing: .05em; color: var(--muted);
    margin: 0 0 12px;
}
.stats-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(210px, 1fr));
    gap: 14px;
}
.stat-card {
    display: flex;
    flex-direction: column;
    gap: 10px;
    padding: 16px 18px;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    color: inherit;
    box-shadow: var(--shadow);
    transition: border-color .14s, box-shadow .14s, transform .06s;
}
.stat-card:hover {
    text-decoration: none;
    border-color: #c7d2fe;
    box-shadow: var(--shadow-lg);
    transform: translateY(-1px);
}
.stat-top { display: flex; align-items: center; gap: 9px; min-width: 0; }
.stat-ico { font-size: 17px; flex: 0 0 auto; }
.stat-label {
    font-size: 12.5px; font-weight: 600; color: var(--muted);
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.stat-value {
    font-size: 30px; font-weight: 700; line-height: 1;
    letter-spacing: -.02em; color: var(--text);
}
.stat-foot { font-size: 12px; }
.stat-sub { color: var(--muted-2); }

/* Tuile de référence (stock produit) : mise en valeur discrète par box-shadow. */
.stat-ref { box-shadow: 0 0 0 1px #c7d2fe, 0 4px 14px rgba(99, 102, 241, .18); }
.stat-ref:hover { box-shadow: 0 0 0 1px #c7d2fe, 0 8px 22px rgba(99, 102, 241, .24); }
.stat-ref .stat-value { color: var(--accent-ink); }

/* Tuiles « santé » (doublons, manquants, excédent) : 0 = valide, > 0 = anomalie */
.stat-health-ok  .stat-value { color: var(--ok-ink); }
.stat-health-err .stat-value { color: var(--err-ink); }
.stat-health-err { box-shadow: 0 0 0 1px var(--err-bd); }

/* Badges & écarts */
.stat-badge {
    display: inline-flex; align-items: center;
    font-size: 11px; font-weight: 600;
    padding: 2px 8px; border-radius: 999px;
    border: 1px solid var(--border);
    background: var(--surface-2); color: var(--muted);
}
.stat-badge-ref { background: var(--accent-soft); color: var(--accent-ink); border-color: #c7d2fe; }
.stat-badge-gap { background: var(--err-bg); color: var(--err-ink); border-color: var(--err-bd); }
.stat-badge-ok  { background: var(--ok-bg);  color: var(--ok-ink);  border-color: var(--ok-bd); }

.stat-delta { font-weight: 600; }
.stat-delta-ok  { color: var(--ok-ink); }
.stat-delta-neg { color: var(--err-ink); }
.stat-delta-pos { color: var(--accent-ink); }

/* --- Accès directs aux briques --- *
 * Dernière case du bandeau de statistiques : PAS de fond de carte, ce ne sont
 * pas des chiffres. Les boutons se rangent deux par deux pour tenir dans la
 * largeur d'une tuile sans allonger la page.                                 */
.access-block {
    /* Deux cases de la grille : chaque bouton garde alors la largeur d'une
       tuile, sans troncature du libellé. */
    grid-column: span 2;
    display: flex; flex-direction: column; gap: 8px; justify-content: center;
    background: none; border: 0; box-shadow: none; padding: 0;
}
@media (max-width: 560px) { .access-block { grid-column: auto; } }
.access-title {
    font-size: 11px; font-weight: 600; text-transform: uppercase;
    letter-spacing: .05em; color: var(--muted-2);
}
.access-grid {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 8px;
}
.module-card {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    min-width: 0;
    padding: 7px 10px 7px 8px;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    color: inherit;
    box-shadow: var(--shadow);
    transition: border-color .14s, box-shadow .14s, transform .06s;
}
.module-card:hover {
    text-decoration: none;
    border-color: #c7d2fe;
    box-shadow: var(--shadow-lg);
    transform: translateY(-1px);
}
/* Le pictogramme est posé dans un carré, le libellé s'aligne à sa droite. */
.module-icon {
    display: inline-flex; align-items: center; justify-content: center;
    width: 24px; height: 24px; flex: 0 0 24px;
    font-size: 14px; line-height: 1;
    background: var(--surface-2); border: 1px solid var(--border-soft);
    border-radius: 6px;
}
.module-label {
    font-size: 12.5px; font-weight: 600;
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

/* --- Formulaire d'import --- */
.import-form {
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
    align-items: center;
    padding: 20px;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    box-shadow: var(--shadow);
}
.import-form label { width: 100%; font-weight: 600; font-size: 13px; }
.import-form select {
    padding: 9px 12px;
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    background: var(--surface);
    min-width: 280px;
    font-size: 14px;
}

/* --- Toggle « mode de fusion » (local / import) --- */
.merge-mode { width: 100%; }
.merge-mode[hidden] { display: none; }
.merge-mode-toggle {
    display: flex;
    align-items: center;
    gap: 8px;
    width: 100%;
    font-weight: 500;
    cursor: pointer;
}
.merge-mode-toggle input { width: auto; margin: 0; cursor: pointer; }
.merge-mode-hint { margin: 4px 0 0 24px; }

/* --- Liste des tables (connexions) --- */
.card {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    box-shadow: var(--shadow);
    overflow: hidden;
    padding: 16px 18px;
}
/* Le padding ne doit pas s'ajouter aux marges du premier / dernier enfant */
.card > :first-child { margin-top: 0; }
.card > :last-child  { margin-bottom: 0; }
/* Carte qui n'enveloppe qu'un tableau : plein cadre, les cellules ont déjà leur padding */
.card:has(> table:only-child),
.card:has(> .table-scroll:only-child) { padding: 0; }
.conn-list { width: 100%; border-collapse: collapse; }
.conn-list th, .conn-list td { padding: 12px 16px; text-align: left; border-bottom: 1px solid var(--border-soft); }
.conn-list th {
    background: var(--surface-2);
    font-size: 11.5px; font-weight: 600;
    text-transform: uppercase; letter-spacing: .04em; color: var(--muted);
}
.conn-list tr:last-child td { border-bottom: none; }
.conn-list tbody tr:hover { background: var(--surface-2); }
.conn-name { font-weight: 600; }

/* Badge d'état */
.badge {
    display: inline-flex; align-items: center; gap: 6px;
    font-size: 11.5px; font-weight: 600;
    padding: 3px 9px; border-radius: 999px;
    background: var(--surface-2); color: var(--muted); border: 1px solid var(--border);
}
.badge-on  { background: var(--ok-bg);  color: var(--ok-ink);  border-color: var(--ok-bd); }
.badge-off { background: var(--err-bg); color: var(--err-ink); border-color: var(--err-bd); }
.badge-warn { background: var(--warn-bg); color: var(--warn-ink); border-color: var(--warn-bd); }
.badge-info { background: var(--info-bg); color: var(--info-ink); border-color: var(--info-bd); }
.badge-merge { background: var(--accent-soft); color: var(--accent-ink); border-color: #c7d2fe; }

/* ================================================================== *
 *  Commandes — vue globale tous canaux (bloc intégré à l'accueil)    *
 * ================================================================== */
.cmd-bloc { margin: 0 0 32px; }
.cmd-head {
    display: flex; align-items: baseline; gap: 12px; flex-wrap: wrap;
    margin: 0 0 16px;
}
.cmd-head .stats-title { margin: 0; }

/* --- Cartouches de canaux : compacts, une seule ligne s'il le faut --- */
.cmd-canaux { display: flex; flex-wrap: wrap; gap: 10px; margin: 0 0 20px; }
.cmd-canal-card {
    display: inline-flex; align-items: center; gap: 9px;
    padding: 7px 13px 7px 9px;
    background: var(--surface); border: 1px solid var(--border);
    border-radius: var(--radius-sm); color: inherit; box-shadow: var(--shadow);
    transition: border-color .14s, box-shadow .14s, transform .06s;
}
.cmd-canal-card:hover {
    text-decoration: none; border-color: #c7d2fe;
    box-shadow: var(--shadow-lg); transform: translateY(-1px);
}
.cmd-canal-on { border-color: #c7d2fe; background: var(--accent-soft); }
.cmd-canal-off { opacity: .62; }
.cmd-canal-ico {
    display: inline-flex; align-items: center; justify-content: center;
    width: 26px; height: 26px; flex: 0 0 26px; font-size: 15px; line-height: 1;
    background: var(--surface-2); border: 1px solid var(--border-soft); border-radius: 6px;
}
.cmd-canal-on .cmd-canal-ico { background: var(--surface); border-color: #c7d2fe; }
.cmd-canal-txt { display: flex; flex-direction: column; line-height: 1.25; }
.cmd-canal-nom { font-size: 12.5px; font-weight: 600; white-space: nowrap; }
.cmd-canal-sub { font-size: 11px; color: var(--muted-2); white-space: nowrap; }
.cmd-canal-n {
    font-size: 17px; font-weight: 650; margin-left: 5px;
    font-variant-numeric: tabular-nums;
}
.cmd-canal-on .cmd-canal-n { color: var(--accent-ink); }

/* --- Barre : filtres d'état à gauche, outils à droite --- */
.cmd-bar {
    display: flex; align-items: center; justify-content: space-between;
    gap: 16px; flex-wrap: wrap;
    margin: 0 0 16px; padding-top: 16px;
    border-top: 1px solid var(--border-soft);
}
.cmd-bar-tools { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.cmd-bar-tools input[type="search"] {
    padding: 7px 11px; font-size: 13px; min-width: 240px;
    border: 1px solid var(--border); border-radius: var(--radius-sm);
    background: var(--surface); color: var(--text);
}
.cmd-note { font-size: 12.5px; color: var(--muted); margin: 0 0 16px; }

.cmd-filters { display: flex; flex-wrap: wrap; gap: 8px; margin: 0; }
.cmd-chip {
    display: inline-flex; align-items: center; gap: 7px;
    padding: 6px 12px; border-radius: 999px;
    background: var(--surface); border: 1px solid var(--border);
    color: var(--text); font-size: 13px; font-weight: 500;
}
.cmd-chip:hover { background: var(--surface-2); border-color: var(--muted-2); }
.cmd-chip-on {
    background: var(--accent-soft); border-color: #c7d2fe; color: var(--accent-ink); font-weight: 600;
}
.cmd-chip-n { color: var(--muted); font-variant-numeric: tabular-nums; }
.cmd-chip-on .cmd-chip-n { color: var(--accent-ink); }
.cmd-canal { display: inline-flex; align-items: center; gap: 6px; white-space: nowrap; font-weight: 500; }
.cmd-articles { max-width: 320px; }
.cmd-missing { margin: 8px 0 10px; padding-left: 20px; }
.cmd-missing li { margin-bottom: 3px; }
/* Ligne d'attente : la table garde sa forme quand il n'y a rien à montrer.
   Le sélecteur passe par #data-table, sinon la règle générale des cellules
   (alignée à gauche, tronquée à 320 px) l'emporterait en spécificité. */
#data-table td.cmd-vide-cell {
    text-align: center; padding: 44px 16px;
    max-width: none; white-space: normal;
    color: var(--muted); font-weight: 500;
}
#data-table tbody tr.cmd-vide:hover { background: transparent; }

/* ================================================================== *
 *  Dashboard : barre d'outils, table, pagination                     *
 * ================================================================== */
/* La barre d'outils est une bande unique posée sur la surface : les contrôles y
   partagent une même hauteur (--control-h) et un même rayon, de sorte que la
   ligne se lise comme un seul objet et non comme une suite de widgets natifs. */
.toolbar {
    display: flex;
    gap: 8px;
    align-items: center;
    flex-wrap: wrap;
    padding: 10px;
    margin-bottom: 14px;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    box-shadow: var(--shadow);
}
/* Sépare visuellement le bloc « recherche + filtres » du bloc « affichage ». */
.toolbar-sep {
    width: 1px; height: 22px; flex: 0 0 auto;
    background: var(--border);
    margin: 0 2px;
}

/* Recherche avec loupe */
.search-box { position: relative; flex: 1 1 260px; min-width: 200px; }
.search-box::before {
    content: "";
    position: absolute; left: 12px; top: 50%;
    width: 16px; height: 16px; transform: translateY(-50%);
    background: no-repeat center/contain
        url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%239ca3af' stroke-width='1.75' stroke-linecap='round'%3E%3Ccircle cx='11' cy='11' r='7'/%3E%3Cpath d='m21 21-4.3-4.3'/%3E%3C/svg%3E");
    pointer-events: none;
}
.search-box input {
    width: 100%;
    height: var(--control-h);
    padding: 0 14px 0 36px;
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    font-size: 13.5px;
    background: var(--surface-2);
    color: var(--text);
    transition: background .12s, border-color .12s, box-shadow .12s;
}
.search-box input::placeholder { color: var(--muted-2); }
.search-box input:hover { border-color: var(--muted-2); }
.search-box input:focus {
    outline: none;
    background: var(--surface);
    border-color: var(--accent);
    box-shadow: 0 0 0 3px rgba(37,99,235,.16);
}
/* Le champ de recherche efface son propre contenu : la croix native de Chrome
   est minuscule et invisible sur fond gris. */
.search-box input::-webkit-search-cancel-button {
    -webkit-appearance: none; appearance: none;
    width: 15px; height: 15px; cursor: pointer; opacity: .55;
    background: no-repeat center/contain
        url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%236b7280' stroke-width='2.2' stroke-linecap='round'%3E%3Cpath d='M18 6 6 18M6 6l12 12'/%3E%3C/svg%3E");
}
.search-box input::-webkit-search-cancel-button:hover { opacity: 1; }

/* Panneau colonnes */
.columns-wrap { position: relative; }
.columns-panel {
    position: absolute;
    top: calc(100% + 6px); left: 0; z-index: 20;
    min-width: 240px; max-height: 340px; overflow-y: auto;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    box-shadow: var(--shadow-lg);
    padding: 10px;
}
.columns-panel-actions {
    display: flex; justify-content: space-between;
    padding-bottom: 8px; margin-bottom: 8px;
    border-bottom: 1px solid var(--border-soft);
}
.columns-panel label {
    display: flex; align-items: center; gap: 9px;
    padding: 6px 8px; cursor: pointer; border-radius: 6px; font-size: 13px;
}
.columns-panel label:hover { background: var(--surface-2); }
.columns-search {
    position: sticky; top: -2px; z-index: 1;
    box-sizing: border-box; width: 100%; padding: 7px 10px; margin-bottom: 8px;
    border: 1px solid var(--border); border-radius: var(--radius-sm);
    background: var(--surface); font-size: 13px;
}
.columns-empty { color: var(--muted); font-size: 13px; padding: 6px 8px; }

/* Panneau filtres */
.filters-wrap { position: relative; }
.filters-count {
    display: inline-flex; align-items: center; justify-content: center;
    min-width: 18px; height: 18px; padding: 0 5px;
    border-radius: 999px; background: var(--accent); color: #fff;
    font-size: 11px; font-weight: 700; line-height: 1;
}
.filters-count[hidden] { display: none; }
.filters-panel {
    position: absolute;
    top: calc(100% + 6px); left: 0; z-index: 20;
    width: 320px; max-height: 460px; overflow-y: auto;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    box-shadow: var(--shadow-lg);
    padding: 12px;
}
.filters-panel-head {
    display: flex; align-items: center; justify-content: space-between;
    padding-bottom: 8px; margin-bottom: 8px;
    border-bottom: 1px solid var(--border-soft);
}
.filters-empty { color: var(--muted); font-size: 13px; padding: 4px 2px 10px; }

.filter-row {
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    padding: 8px 9px;
    margin-bottom: 8px;
    background: var(--surface-2);
}
.filter-row-head { display: flex; align-items: center; gap: 8px; margin-bottom: 7px; }
.filter-col { font-weight: 600; font-size: 13px; flex: 1 1 auto; min-width: 0;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.filter-remove {
    border: none; background: none; cursor: pointer; color: var(--muted-2);
    font-size: 14px; line-height: 1; padding: 2px 4px; flex: 0 0 auto;
}
.filter-remove:hover { color: var(--err-ink); }

.filter-mode { display: inline-flex; border: 1px solid var(--border); border-radius: 6px; overflow: hidden; }
.filter-mode-btn {
    border: none; background: var(--surface); cursor: pointer;
    font-size: 11.5px; font-weight: 600; color: var(--muted); padding: 3px 8px;
}
.filter-mode-btn.active { background: var(--accent); color: #fff; }

.filter-text {
    width: 100%; padding: 7px 10px;
    border: 1px solid var(--border); border-radius: var(--radius-sm);
    background: var(--surface); font-size: 13px;
}
.filter-text:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px rgba(37,99,235,.14); }

.filter-facet-actions { display: flex; gap: 12px; margin-bottom: 6px; }
.filter-facet-search {
    width: 100%; padding: 6px 9px; margin-bottom: 6px;
    border: 1px solid var(--border); border-radius: var(--radius-sm);
    background: var(--surface); font-size: 12.5px;
}
.filter-facet-list { max-height: 190px; overflow-y: auto; }
.filter-facet-list label {
    display: flex; align-items: center; gap: 8px;
    padding: 4px 6px; cursor: pointer; border-radius: 6px; font-size: 13px;
}
.filter-facet-list label:hover { background: var(--surface); }
.filter-facet-list span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.filters-add { margin-top: 4px; }
.filters-add select {
    width: 100%; padding: 8px 10px;
    border: 1px solid var(--border); border-radius: var(--radius-sm);
    background: var(--surface); font-size: 13px; cursor: pointer;
}

/* Réglage étiqueté de la barre d'outils (« Statut : », « Lignes : »…). */
.perpage-box { display: flex; align-items: center; gap: 7px; white-space: nowrap; }
.perpage-box label {
    font-size: 12px; font-weight: 600; color: var(--muted);
    text-transform: uppercase; letter-spacing: .03em;
}

/* Selects redessinés : la flèche native de l'OS est la marque la plus visible
   d'un formulaire « brut ». On la remplace par un chevron cohérent avec le jeu
   d'icônes, et on aligne la hauteur sur celle des autres contrôles. */
.perpage-box select,
.bulk-select,
.filters-add select {
    appearance: none; -webkit-appearance: none;
    height: var(--control-h);
    padding: 0 32px 0 12px;
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    background-color: var(--surface-2);
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%236b7280' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 10px center;
    background-size: 15px 15px;
    color: var(--text);
    font: inherit; font-size: 13.5px;
    cursor: pointer;
    /* Un select trop large mange la place du champ de recherche et fait passer
       la barre sur deux lignes : on tronque le libellé plutôt que la mise en page. */
    max-width: 240px; text-overflow: ellipsis;
    transition: background-color .12s, border-color .12s, box-shadow .12s;
}
.perpage-box select:hover,
.bulk-select:hover,
.filters-add select:hover { border-color: var(--muted-2); }
.perpage-box select:focus-visible,
.bulk-select:focus-visible,
.filters-add select:focus-visible {
    outline: none; background-color: var(--surface);
    border-color: var(--accent); box-shadow: 0 0 0 3px rgba(37,99,235,.16);
}

/* Case à cocher étiquetée dans la barre d'outils (« Masquer les produits… ») :
   toute l'étiquette est cliquable et prend l'allure d'un contrôle à part
   entière, au lieu d'une case flottante collée à du texte. */
.toolbar-check {
    display: inline-flex; align-items: center; gap: 8px;
    height: var(--control-h); padding: 0 12px;
    border: 1px solid var(--border); border-radius: var(--radius-sm);
    background: var(--surface-2);
    font-size: 13.5px; color: var(--text); cursor: pointer;
    white-space: nowrap;
    transition: background .12s, border-color .12s, color .12s;
}
.toolbar-check:hover { border-color: var(--muted-2); }
.toolbar-check input { margin: 0; cursor: pointer; accent-color: var(--accent); width: 15px; height: 15px; }
.toolbar-check .icon { color: var(--muted); }
/* État actif : le filtre est en vigueur, il doit se voir sans lire l'étiquette. */
.toolbar-check:has(input:checked) {
    background: var(--accent-soft); border-color: #dbe3ff; color: var(--accent-ink);
}
.toolbar-check:has(input:checked) .icon { color: var(--accent-ink); }

.result-count { font-size: 13px; color: var(--muted); margin-bottom: 10px; }

/* Table de données */
.table-scroll {
    overflow-x: auto;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    box-shadow: var(--shadow);
}
#data-table { border-collapse: collapse; width: 100%; }
#data-table th, #data-table td {
    padding: 10px 14px;
    border-bottom: 1px solid var(--border-soft);
    text-align: left;
    max-width: 320px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
#data-table th {
    background: var(--surface-2);
    position: sticky; top: 0; z-index: 2;
    cursor: pointer; user-select: none;
    font-weight: 600; font-size: 12.5px; color: var(--muted);
    text-transform: uppercase; letter-spacing: .02em;
}
#data-table th:hover { color: var(--text); }
#data-table th .sort-ind { color: var(--accent); margin-left: 5px; font-size: 10px; }
#data-table tbody tr:hover { background: var(--accent-soft); }
#data-table tbody tr:last-child td { border-bottom: none; }

/* --- Réordonnancement des colonnes (glisser-déposer sur les en-têtes) --- */
/* Le trait bleu inset indique le côté où la colonne déplacée va atterrir. */
#data-table th.col-draggable { cursor: grab; }
#data-table th.col-draggable:active { cursor: grabbing; }
#data-table th.col-dragging { opacity: .45; }
#data-table th.drop-before { box-shadow: inset 3px 0 0 0 var(--accent); }
#data-table th.drop-after  { box-shadow: inset -3px 0 0 0 var(--accent); }

/* --- Colonne figée (première colonne, ex. « Présence ») --- */
/* Collée à gauche lors du défilement horizontal ; fond opaque + z-index pour
   passer au-dessus des cellules qui défilent dessous. L'en-tête figé (coin)
   cumule sticky top + left et prend le z-index le plus élevé. */
#data-table td.col-pinned {
    position: sticky; left: 0; z-index: 1;
    background: var(--surface);
    border-right: 1px solid var(--border);
    font-weight: 700; text-align: center;
}
#data-table th.col-pinned {
    left: 0; z-index: 3;
    border-right: 1px solid var(--border);
}
/* Conserver un fond opaque sous la cellule figée au survol de ligne. */
#data-table tbody tr:hover td.col-pinned { background: var(--accent-soft); }

/* --- Colonne de sélection (cases à cocher, tout à gauche) --- */
/* Elle précède la colonne figée : celle-ci est donc décalée de sa largeur. */
#data-table th.col-select,
#data-table td.col-select {
    position: sticky; left: 0;
    width: 42px; min-width: 42px; max-width: 42px;
    padding: 10px 0;
    text-align: center;
    background: var(--surface);
    border-right: 1px solid var(--border);
}
#data-table th.col-select { z-index: 4; background: var(--surface-2); cursor: default; }
#data-table td.col-select { z-index: 1; }
#data-table th.col-select input,
#data-table td.col-select input { cursor: pointer; margin: 0; vertical-align: middle; }
#data-table.has-select td.col-pinned { left: 42px; }
#data-table.has-select th.col-pinned { left: 42px; }
#data-table tbody tr:hover td.col-select { background: var(--accent-soft); }

/* --- Colonne de pastille d'état (entre la sélection et les données) --- */
/* Non collée : elle défile avec le tableau, contrairement à col-select. */
#data-table th.col-state,
#data-table td.col-state {
    width: 34px; min-width: 34px; max-width: 34px;
    padding: 8px 0;
    text-align: center;
}
#data-table th.col-state { cursor: default; }

.state-pill {
    display: inline-flex; align-items: center; justify-content: center;
    width: 18px; height: 18px;
    border: 1px solid transparent; border-radius: 50%;
    font-size: 11px; font-weight: 700; line-height: 1;
    cursor: help;
}
.state-live    { background: var(--ok-bg);    border-color: var(--ok-bd);  color: var(--ok-ink); }
.state-error   { background: var(--err-bg);   border-color: var(--err-bd); color: var(--err-ink); }
.state-draft,
.state-unknown { background: var(--surface-2); border-color: var(--border); color: var(--muted); }

/* --- Colonne des actions à la ligne (tout à droite du tableau) --- */
/* Elle ferme la ligne : au plus étroit, et jamais coupée par un retour ligne. */
#data-table th.col-rowact,
#data-table td.col-rowact {
    width: 1%;
    white-space: nowrap;
    text-align: right;
}
#data-table th.col-rowact { cursor: default; }

/* Ligne cochée : mise en évidence discrète, y compris sous les colonnes collées. */
#data-table tbody tr.row-selected > td { background: var(--accent-soft); }
#data-table tbody tr.row-selected > td.col-select,
#data-table tbody tr.row-selected > td.col-pinned { background: var(--accent-soft); }

/* Marqueur de présence : VP (présent des deux côtés) en vert, V / P (présent
   d'un seul côté) en rouge. */
#data-table td.mark-VP { color: var(--ok-ink); }
#data-table td.mark-V,
#data-table td.mark-P  { color: var(--err-ink); }

/* Ligne « colonne figée » dans le panneau Colonnes : atténuée (non masquable). */
.columns-panel label.col-locked { opacity: .7; cursor: default; }
.columns-panel label.col-locked input { cursor: default; }

.status-msg { padding: 28px; text-align: center; color: var(--muted); }
.status-msg:empty { display: none; }

/* Pagination */
.pagination {
    display: flex; flex-wrap: wrap; gap: 5px;
    align-items: center; justify-content: center;
    margin: 18px 0 0;
}
.pagination button {
    display: inline-flex; align-items: center; justify-content: center; gap: 6px;
    min-width: 34px; height: 34px; padding: 0 10px;
    border: 1px solid var(--border); border-radius: var(--radius-sm);
    background: var(--surface); color: var(--text);
    cursor: pointer; font-size: 13px; font-weight: 550;
    box-shadow: var(--shadow);
    transition: background .12s, border-color .12s, color .12s;
}
.pagination button .icon { width: 15px; height: 15px; opacity: .75; }
.pagination button:hover:not(:disabled) { background: var(--surface-2); border-color: var(--muted-2); }
.pagination button:focus-visible { outline: none; box-shadow: 0 0 0 3px rgba(37,99,235,.22); }
.pagination button:disabled { opacity: .4; cursor: default; box-shadow: none; }
.pagination button.active {
    background: var(--accent); border-color: var(--accent); color: #fff; font-weight: 650;
}
.pagination .ellipsis { padding: 0 4px; color: var(--muted-2); }

/* Pagination serveur (pagination_nav() de core/layout.php) : liens, pas boutons. */
.pagination .pg-btn {
    display: inline-flex; align-items: center; justify-content: center;
    min-width: 34px; height: 34px; padding: 0 10px;
    border: 1px solid var(--border); border-radius: var(--radius-sm);
    background: var(--surface); color: var(--text); text-decoration: none;
    font-size: 13px; font-weight: 550; box-shadow: var(--shadow);
}
.pagination a.pg-btn:hover { background: var(--surface-2); border-color: var(--muted-2); }
.pagination .pg-btn[aria-disabled] { opacity: .4; box-shadow: none; }
.pagination .pg-btn.active { background: var(--accent); border-color: var(--accent); color: #fff; font-weight: 650; }

/* ================================================================== *
 *  Import : indicateur « en cours » (spinner + barre indéterminée)   *
 * ================================================================== */
.import-progress {
    margin: 16px 0 0;
    padding: 14px 16px;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    box-shadow: var(--shadow);
}
.import-progress[hidden] { display: none; }
.import-progress-row {
    display: flex; align-items: center; gap: 10px;
    font-size: 13.5px; font-weight: 550; color: var(--text);
    margin-bottom: 12px;
}
.import-progress-txt { color: var(--muted); font-weight: 500; }

.spinner {
    width: 16px; height: 16px; flex: 0 0 16px;
    border: 2px solid var(--border);
    border-top-color: var(--accent);
    border-radius: 50%;
    animation: spin .7s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }

.progress-bar {
    height: 6px; border-radius: 999px;
    background: var(--surface-2);
    border: 1px solid var(--border-soft);
    overflow: hidden;
}
.progress-bar-fill {
    height: 100%; width: 40%;
    border-radius: 999px;
    background: var(--accent);
    animation: progress-slide 1.1s ease-in-out infinite;
}
@keyframes progress-slide {
    0%   { margin-left: -40%; }
    100% { margin-left: 100%; }
}

/* Bouton désactivé pendant l'import */
.btn:disabled { opacity: .6; cursor: default; box-shadow: none; }
.import-form select:disabled { opacity: .6; cursor: default; }

/* ================================================================== *
 *  Toasts (notifications) — coin supérieur droit                     *
 * ================================================================== */
.toast-container {
    position: fixed;
    top: 18px; right: 18px;
    z-index: 1000;
    display: flex; flex-direction: column; gap: 10px;
    max-width: min(380px, calc(100vw - 36px));
    pointer-events: none;
}
.toast {
    display: flex; align-items: flex-start; gap: 10px;
    padding: 12px 12px 12px 14px;
    background: var(--surface);
    border: 1px solid var(--border);
    border-left-width: 4px;
    border-radius: var(--radius-sm);
    box-shadow: var(--shadow-lg);
    pointer-events: auto;
    opacity: 0;
    transform: translateX(16px);
    transition: opacity .22s ease, transform .22s ease;
}
.toast-in  { opacity: 1; transform: translateX(0); }
.toast-out { opacity: 0; transform: translateX(16px); }

.toast-icon {
    flex: 0 0 20px;
    width: 20px; height: 20px;
    display: grid; place-items: center;
    border-radius: 50%;
    font-size: 12px; font-weight: 700; color: #fff;
    margin-top: 1px;
}
.toast-body { flex: 1 1 auto; min-width: 0; }
.toast-title { font-weight: 650; font-size: 13.5px; margin-bottom: 2px; }
.toast-msg { font-size: 13px; color: var(--text); word-wrap: break-word; }

.toast-close {
    flex: 0 0 auto;
    border: none; background: none; cursor: pointer;
    color: var(--muted-2); font-size: 18px; line-height: 1;
    padding: 0 2px; margin: -2px -2px 0 0;
}
.toast-close:hover { color: var(--text); }

.toast-success { border-left-color: #16a34a; }
.toast-success .toast-icon { background: #16a34a; }
.toast-error   { border-left-color: #dc2626; }
.toast-error   .toast-icon { background: #dc2626; }
.toast-info    { border-left-color: var(--accent); }
.toast-info    .toast-icon { background: var(--accent); }

@media (max-width: 820px) {
    .toast-container { top: 12px; right: 12px; left: 12px; max-width: none; }
}

/* Respect des préférences de réduction de mouvement */
@media (prefers-reduced-motion: reduce) {
    .spinner, .progress-bar-fill { animation: none; }
    .sidebar-head, .brand-mark, .brand-cog { transition: none; }
    .toast { transition: opacity .1s; transform: none; }
    .toast-in, .toast-out { transform: none; }
}

/* ================================================================== *
 *  Responsive : la sidebar passe en bandeau horizontal               *
 * ================================================================== */
@media (max-width: 820px) {
    .app { flex-direction: column; }
    .sidebar {
        width: 100%; flex-basis: auto; height: auto;
        position: static;
        overflow: visible;
        border-right: none; border-bottom: 1px solid var(--border);
    }
    /* Bandeau horizontal : plus de colonne à hauteur fixe, donc plus de zone
       défilante interne ni de tête compacte. */
    .nav { display: flex; flex-direction: row; flex-wrap: wrap; overflow: visible; min-height: 0; flex: 0 0 auto; }
    .sidebar-foot { margin-top: 12px; }
    .sidebar-compact .mode-widget-txt { display: inline; }
    .nav-group { margin: 0; padding: 0; border: none; flex-direction: row; flex-wrap: wrap; align-items: center; }
    .nav-sub { display: flex; padding: 0; }
    .nav-subitem, .nav-subitem.nav-child { border-left: none; margin: 0; }
    .main-inner { padding: 20px; }
}

/* ================================================================== *
 *  MAJ flux : pied de sidebar (bouton + date) + popup d'orchestration *
 * ================================================================== */

/* Pied de sidebar : collé en bas. C'est .nav (flex:1, overflow-y:auto) qui
   occupe la place restante ; margin-top:auto reste comme filet de sécurité
   si .nav est absent ou plus court que la colonne. */
.sidebar-foot {
    flex: 0 0 auto;
    margin-top: auto;
    padding-top: 12px;
    border-top: 1px solid var(--border-soft);
    background: var(--surface);
}
/* --- File Amazon : raccourci + compte à rebours, au-dessus de « MAJ flux » --- */
.queue-widget {
    display: block;
    margin-bottom: 10px;
    padding: 8px 10px;
    border: 1px solid var(--border-soft);
    border-radius: var(--radius-sm);
    background: var(--surface, #fff);
    text-decoration: none;
    color: inherit;
    transition: border-color .12s, background .12s;
}
.queue-widget:hover { border-color: var(--accent); }
.queue-widget-head {
    display: flex;
    align-items: center;
    gap: 8px;
    font-size: 12.5px;
    font-weight: 600;
}
.queue-widget-lbl   { flex: 1 1 auto; }
.queue-widget-count {
    flex: 0 0 auto;
    min-width: 20px;
    padding: 1px 6px;
    border-radius: 999px;
    background: #92400e;
    color: #fff;
    font-size: 11px;
    font-weight: 700;
    text-align: center;
}
.queue-widget-timer {
    display: block;
    margin-top: 3px;
    font-size: 11px;
    color: var(--muted);
    font-variant-numeric: tabular-nums;
}
.queue-widget-err .queue-widget-count { background: var(--err-ink, #b42318); }

/* File vide : l'encart reste en place (accès à l'écran + purge), en retrait. */
.queue-widget-count[hidden] { display: none; }
.queue-widget-idle { background: transparent; }
.queue-widget-idle .queue-widget-head { font-weight: 500; color: var(--muted); }
.queue-widget-idle .nav-ico { opacity: .55; }

.maj-btn {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    width: 100%;
    padding: 10px 12px;
    border: 1px solid var(--accent);
    border-radius: var(--radius-sm);
    background: var(--accent);
    color: #fff;
    font-size: 13.5px;
    font-weight: 600;
    cursor: pointer;
    box-shadow: var(--shadow);
    transition: background .12s, transform .04s;
}
.maj-btn:hover  { background: var(--accent-ink); }
.maj-btn:active { transform: translateY(1px); }
.maj-btn .nav-ico { opacity: 1; }
/* MAJ automatique (cron) en cours : bouton grisé, icône qui tourne. */
.maj-btn:disabled {
    background: var(--muted);
    border-color: var(--muted);
    cursor: not-allowed;
    box-shadow: none;
}
.maj-btn:disabled .nav-ico { animation: spin 1.2s linear infinite; }
.maj-last {
    margin: 8px 2px 0;
    font-size: 11.5px;
    color: var(--muted);
    text-align: center;
}
.maj-last #maj-last-val { color: var(--text); font-weight: 550; }

/* --- « Mode production » : sous le logo, au-dessus du trait de séparation --- */
/* Reprend .alert-err (mêmes couleurs, même bordure), resserré et centré pour
   tenir dans la colonne sans repousser la zone de travail. */
.mode-widget {
    margin: 12px 0 0;
    padding: 8px 10px;
    font-size: 11.5px;
    line-height: 1.45;
    text-align: center;
}
.mode-widget strong { display: block; }

/* --- Modales (coquille commune : assets/modal.js + « MAJ flux ») --- */
/* Toute boîte de dialogue de l'app partage ces règles : les classes .modal-*
   sont produites par modal.js, les .maj-modal-* par core/layout.php. */
.modal,
.maj-modal { position: fixed; inset: 0; z-index: 900; display: grid; place-items: center; }
.modal[hidden],
.maj-modal[hidden] { display: none; }
/* Empilement : une modale ouverte par-dessus une autre passe devant. */
.modal { z-index: 950; }
body.modal-lock { overflow: hidden; }

.modal-overlay,
.maj-modal-overlay {
    position: absolute; inset: 0;
    background: rgba(16, 24, 40, .45);
    backdrop-filter: blur(1px);
}
.modal-box,
.maj-modal-box {
    position: relative;
    width: min(460px, calc(100vw - 32px));
    max-height: calc(100vh - 48px);
    display: flex; flex-direction: column;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    box-shadow: var(--shadow-lg);
    overflow: hidden;
}
.modal-box:focus { outline: none; }

.modal-head,
.maj-modal-head {
    display: flex; align-items: center; justify-content: space-between;
    padding: 16px 18px;
    border-bottom: 1px solid var(--border-soft);
}
.modal-title,
.maj-modal-head h2 { font-size: 16px; font-weight: 650; margin: 0; }
.modal-title { flex: 1 1 auto; }
.modal-x,
.maj-modal-x {
    border: none; background: none; cursor: pointer;
    color: var(--muted-2); font-size: 22px; line-height: 1;
    padding: 0 4px; margin: -4px -4px 0 0;
}
.modal-x:hover,
.maj-modal-x:hover { color: var(--text); }

.modal-body,
.maj-modal-body {
    padding: 14px 18px;
    overflow-y: auto;
    display: flex; flex-direction: column; gap: 14px;
}
.modal-foot,
.maj-modal-foot {
    display: flex; justify-content: flex-end; gap: 8px;
    padding: 14px 18px;
    border-top: 1px solid var(--border-soft);
    background: var(--surface-2);
}

/* Pastille d'icône, colorée par le ton de la modale. */
.modal-ico {
    flex: 0 0 auto;
    width: 30px; height: 30px;
    display: grid; place-items: center;
    border-radius: 50%;
    font-size: 15px; line-height: 1;
    background: var(--accent-soft); color: var(--accent-ink);
    border: 1px solid transparent;
}
.modal-danger  .modal-ico { background: var(--err-bg); border-color: var(--err-bd); color: var(--err-ink); }
.modal-warn    .modal-ico { background: #fffbeb;       border-color: #fde68a;      color: #92400e; }
.modal-success .modal-ico { background: var(--ok-bg);  border-color: var(--ok-bd);  color: var(--ok-ink); }

/* Corps texte : paragraphes générés depuis le message. */
.modal-body .modal-p {
    margin: 0;
    font-size: 13.5px; line-height: 1.55;
    color: var(--text);
}
.modal-body .modal-p + .modal-p { color: var(--muted); }

/* Animation d'entrée / sortie (alignée sur les toasts). */
.modal .modal-overlay,
.modal .modal-box {
    opacity: 0;
    transition: opacity .16s ease, transform .16s ease;
}
.modal .modal-box { transform: translateY(8px) scale(.98); }
.modal.modal-in  .modal-overlay { opacity: 1; }
.modal.modal-in  .modal-box     { opacity: 1; transform: none; }
.modal.modal-out .modal-overlay,
.modal.modal-out .modal-box     { opacity: 0; }

@media (prefers-reduced-motion: reduce) {
    .modal .modal-overlay,
    .modal .modal-box { transition: none; }
}

/* Une modale sans bouton (traitement en cours) n'affiche pas son pied : les
   boutons n'y sont posés qu'à la fin, par RunModal. */
.modal-foot:empty { display: none; }

/* Barre déterminée : la largeur porte l'avancement, pas d'animation en boucle. */
.progress-bar.is-determinate .progress-bar-fill {
    animation: none;
    margin-left: 0;
    width: 0;
    transition: width .25s ease;
}

@media (prefers-reduced-motion: reduce) {
    .progress-bar.is-determinate .progress-bar-fill { transition: none; }
}

/* ================================================================== *
 *  Fenêtre de suivi d'un traitement (assets/run-modal.js)            *
 *                                                                     *
 *  Mise à jour de flux, import, envoi, action de masse, commande :    *
 *  tout ce qui « tourne » s'affiche ici, avec la même grammaire —     *
 *  étape en cours, barre, journal des étapes, rapport final.          *
 * ================================================================== */

.run-modal { display: flex; flex-direction: column; gap: 12px; }

/* En-tête : spinner (ou verdict), étape en cours, chronomètre. */
.run-head {
    display: flex; align-items: center; gap: 10px;
    font-size: 13.5px; font-weight: 600; color: var(--text);
}
.run-phase { flex: 1 1 auto; min-width: 0; }
.run-clock {
    flex: 0 0 auto;
    font-size: 12px; font-weight: 500; color: var(--muted);
    font-variant-numeric: tabular-nums;
}

/* Le spinner cède la place à un verdict une fois le traitement fini. */
.run-ico {
    flex: 0 0 16px;
    width: 16px; height: 16px;
    display: grid; place-items: center;
    border-radius: 50%;
    font-size: 11px; line-height: 1; font-weight: 700;
}
.run-ico-ok    { background: var(--ok-bg);  color: var(--ok-ink);  border: 1px solid var(--ok-bd); }
.run-ico-error { background: var(--err-bg); color: var(--err-ink); border: 1px solid var(--err-bd); }

.run-bar { height: 8px; }

.run-stats {
    display: flex; align-items: baseline; justify-content: space-between; gap: 12px;
    font-size: 12.5px; min-height: 18px;
}
.run-count  { font-weight: 600; color: var(--text); white-space: nowrap; font-variant-numeric: tabular-nums; }
.run-detail { color: var(--muted); text-align: right; }

/* Rapport de fin : reste à l'écran jusqu'à la fermeture par l'utilisateur. */
.run-report { margin: 0; font-size: 13px; line-height: 1.55; }
.run-report[hidden] { display: none; }
.run-report .muted { display: block; margin-top: 4px; font-size: 12px; }
.run-report-html { margin-top: 4px; }
.run-report-html ul { margin: 4px 0 0 18px; padding: 0; }

/* Journal : ce qui a déjà été fait, dans l'ordre, avec l'issue et la durée. */
.run-log-wrap { display: flex; flex-direction: column; gap: 6px; }
.run-log-title {
    font-size: 11.5px; font-weight: 650; color: var(--muted);
    text-transform: uppercase; letter-spacing: .04em;
}
.run-log {
    margin: 0; padding: 4px 0;
    list-style: none;
    max-height: 240px; overflow-y: auto;
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    background: var(--surface-2);
}
.run-log:empty { display: none; }

.run-step {
    display: flex; align-items: flex-start; gap: 9px;
    padding: 6px 10px;
    font-size: 12.5px; line-height: 1.45;
}
.run-step + .run-step { border-top: 1px solid var(--border-soft); }

.run-step-ico {
    flex: 0 0 16px;
    width: 16px; height: 16px; margin-top: 1px;
    display: grid; place-items: center;
    border-radius: 50%;
    font-size: 10px; font-weight: 700; line-height: 1;
    background: var(--surface); color: var(--muted-2);
    border: 1px solid var(--border);
}
/* L'étape en cours porte le spinner : son « rond » ne doit pas doubler le trait. */
.run-step-run .run-step-ico { background: none; border: none; }
.run-step-ok    .run-step-ico { background: var(--ok-bg);   color: var(--ok-ink);   border-color: var(--ok-bd); }
.run-step-warn  .run-step-ico { background: var(--warn-bg); color: var(--warn-ink); border-color: var(--warn-bd); }
.run-step-error .run-step-ico { background: var(--err-bg);  color: var(--err-ink);  border-color: var(--err-bd); }
.run-step-info  .run-step-ico { background: var(--info-bg); color: var(--info-ink); border-color: var(--info-bd); }

.run-step-body { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; }
.run-step-label { color: var(--text); word-break: break-word; }
.run-step-run   .run-step-label { font-weight: 600; }
.run-step-error .run-step-label { color: var(--err-ink); font-weight: 600; }
.run-step-sub { color: var(--muted); font-size: 12px; word-break: break-word; }
.run-step-sub:empty { display: none; }
.run-step-time {
    flex: 0 0 auto;
    font-size: 11.5px; color: var(--muted-2);
    font-variant-numeric: tabular-nums; white-space: nowrap;
}

.run-note { margin: 0; font-size: 12px; line-height: 1.5; color: var(--muted); }
.run-note strong { color: var(--text); }
.run-stop { align-self: flex-end; }

/* --- Groupes de flux dans la modale --- */
.maj-group {
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    padding: 10px 12px 12px;
    margin: 0;
    display: flex; flex-direction: column; gap: 6px;
}
.maj-group legend {
    padding: 0 6px;
    font-size: 12px; font-weight: 650;
    color: var(--muted);
    text-transform: uppercase; letter-spacing: .04em;
}
.maj-hint { margin: 0 0 4px; font-size: 12px; color: var(--muted); }
.maj-item {
    display: flex; align-items: center; gap: 9px;
    padding: 5px 4px;
    font-size: 13.5px;
    cursor: pointer;
    border-radius: 6px;
}
.maj-item:hover { background: var(--surface-2); }
.maj-item input { width: 15px; height: 15px; accent-color: var(--accent); cursor: pointer; }
.maj-item input:disabled { cursor: default; }

/* Ligne d'un flux : la case (extensible) + son champ de date facultatif. */
.maj-row { display: flex; align-items: center; gap: 10px; }
.maj-row .maj-item { flex: 1 1 auto; min-width: 0; }
.maj-date-ctl { display: inline-flex; align-items: center; gap: 6px; flex: 0 0 auto; }
.maj-date-label { font-size: 12px; color: var(--muted); white-space: nowrap; }
.maj-date {
    width: auto; height: auto;
    padding: 4px 7px;
    font: inherit; font-size: 12.5px;
    color: var(--text);
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
}
.maj-date:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft); }

.maj-mode {
    display: flex; flex-wrap: wrap; gap: 8px 16px;
    padding: 6px 4px 2px 26px;
}
.maj-mode.is-forced { opacity: .55; }
.maj-radio { display: flex; align-items: center; gap: 6px; font-size: 12.5px; color: var(--muted); cursor: pointer; }
.maj-radio input { accent-color: var(--accent); cursor: pointer; }

/* En bandeau horizontal (mobile), le pied reprend un flux normal. */
@media (max-width: 820px) {
    .sidebar-foot { margin-top: 8px; width: 100%; }
    .maj-btn { width: auto; }
}

/* ================================================================== *
 *  Page « État produit » Spartoo (acquittement check_status_products)*
 * ================================================================== */

/* Pictogramme d'une page de module dans la sidebar. Il occupe la même gouttière
   que la pastille .dot des connexions, pour que les deux familles d'entrées
   s'alignent sur un seul axe. */
.nav-ico-sm { width: 15px; flex: 0 0 15px; font-size: 11px; }
.nav-ico-sm .icon { width: 15px; height: 15px; }

/* Page d'ALERTE (module.php : 'icon_class' => 'nav-ico-alert'). Le pictogramme
   passe en rouge et garde sa couleur même sur l'entrée active : ce qu'il annonce
   — des annonces fantômes encore achetables — ne cesse pas d'être un problème
   parce qu'on est sur la page. Le libellé, lui, reste noir : une sidebar
   entièrement rouge ne hiérarchise plus rien. */
.nav-ico-alert,
.nav-subitem:hover .nav-ico-alert,
.nav-subitem.active .nav-ico-alert { color: var(--err-ink); opacity: 1; }

/* Tuiles de répartition : mêmes styles que .stat-card, mais cliquables (filtre). */
.st-tile {
    font: inherit; color: inherit; text-align: left;
    cursor: pointer; appearance: none;
}
.st-tile-active { box-shadow: 0 0 0 2px var(--accent); }
.st-tile-OK .stat-value { color: var(--ok-ink); }
.st-tile-KO .stat-value,
.st-tile-OS .stat-value { color: var(--err-ink); }
.st-tile-EC .stat-value { color: #92400e; }
.st-tile-NA .stat-value { color: var(--muted); }

/* Mapping Spartoo : filtre de lignes + tri alphabétique, côté navigateur. */
.sp-map-tools { margin: 0 0 10px; }
.sp-map-tools .sp-map-count { margin: 0; }
.sp-sort {
    display: inline-flex; align-items: center; gap: 6px;
    padding: 0; border: 0; background: none; cursor: pointer;
    font: inherit; color: inherit;
    text-transform: inherit; letter-spacing: inherit;
}
.sp-sort:hover { color: var(--accent-ink); }
.sp-sort-ind { font-size: 11px; color: var(--muted-2); }
.sp-sort[data-sens="1"] .sp-sort-ind,
.sp-sort[data-sens="-1"] .sp-sort-ind { color: var(--accent-ink); }

/* Table des statuts (rendu serveur, filtrée et paginée côté navigateur). */
.st-table { border-collapse: collapse; width: 100%; }
.st-table th, .st-table td {
    padding: 10px 14px;
    border-bottom: 1px solid var(--border-soft);
    text-align: left;
    vertical-align: top;
}
.st-table th {
    background: var(--surface-2);
    position: sticky; top: 0; z-index: 2;
    font-weight: 600; font-size: 12.5px; color: var(--muted);
    text-transform: uppercase; letter-spacing: .02em;
    white-space: nowrap;
}
.st-table tbody tr:hover { background: var(--accent-soft); }
.st-table tbody tr:last-child td { border-bottom: none; }
.st-table td.st-ref { font-family: ui-monospace, "SF Mono", Menlo, Consolas, monospace; font-size: 12px; white-space: nowrap; }
.st-table td.st-name { max-width: 340px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.st-table td.st-motif { max-width: 420px; font-size: 13px; }

/* Pastille de statut. */
.st-badge {
    display: inline-block; white-space: nowrap;
    padding: 2px 9px; border-radius: 999px;
    border: 1px solid var(--border);
    background: var(--surface-2);
    font-size: 12px; font-weight: 600;
}
.st-badge-OK { background: var(--ok-bg);  border-color: var(--ok-bd);  color: var(--ok-ink); }
.st-badge-OS { background: var(--err-bg); border-color: var(--err-bd); color: var(--err-ink); }
.st-badge-KO { background: #fee2e2;       border-color: #fca5a5;       color: #7f1d1d; }
.st-badge-EC { background: #fffbeb;       border-color: #fde68a;       color: #92400e; }
.st-badge-NA { background: var(--surface-2); border-color: var(--border); color: var(--muted); }

/* Pastille dont le contenu est une icône (« envoyé », « refusé »…) : le mot
   passe en infobulle, la pastille se resserre autour du dessin et le centre. */
.st-badge-ico { display: inline-flex; align-items: center; gap: 5px; padding: 3px 8px; vertical-align: middle; }
.st-badge-ico .icon { width: 14px; height: 14px; }
.st-table td.st-qty-diff { color: var(--err-ink); font-weight: 600; }
.st-table td.st-src { font-size: 12.5px; color: var(--muted); white-space: nowrap; }

/* ---- Contrôle à la demande (acquittement ciblé) ---- */

/* Barre d'actions au-dessus de la table. */
.st-actions {
    display: flex; flex-wrap: wrap; align-items: center; gap: 10px;
    margin: 14px 0 6px;
}
.st-actions-state { display: inline-flex; align-items: center; gap: 8px; font-size: 13px; color: var(--muted); }
/* `display: inline-flex` l'emporte sur la règle par défaut de [hidden] : sans
   cette ligne, le spinner reste visible alors qu'aucun contrôle ne tourne. */
.st-actions-state[hidden] { display: none; }

/* Colonne des cases à cocher : au plus étroit. */
.st-table th.st-check, .st-table td.st-check { width: 1%; padding-right: 0; white-space: nowrap; }
.st-table .st-check input { cursor: pointer; }

/* --- Boutons d'action de fin de ligne --- */
/* Carrés de 30 px : assez grands pour être visés à la souris (la cible
   recommandée est 24 px minimum) et pour que le tracé de l'icône se lise. Le
   fond ne s'allume qu'au survol de la ligne : cent boutons pleins en même temps
   feraient un damier illisible. */
.st-table td.st-row-actions { white-space: nowrap; }
.row-actions { display: inline-flex; align-items: center; gap: 4px; justify-content: flex-end; }

.btn-mini {
    display: inline-flex; align-items: center; justify-content: center;
    width: 30px; height: 30px; padding: 0;
    border-radius: 8px;
    border: 1px solid transparent; background: transparent;
    font: inherit; color: var(--muted); cursor: pointer;
    transition: background .12s, border-color .12s, color .12s;
}
.btn-mini .icon { width: 16px; height: 16px; }
/* `display: inline-flex` l'emporte sur la règle par défaut de [hidden] : sans
   cette ligne, les boutons masqués selon l'état de la ligne (retrait / remise
   en ligne sur « État produit ») resteraient visibles tous les deux. */
.btn-mini[hidden] { display: none; }
/* Variante à libellé texte (« Voir ») : la largeur s'adapte au contenu. */
.btn-mini-text { width: auto; padding: 0 9px; font-size: 12.5px; gap: 5px; }

.btn-mini:hover {
    background: var(--accent-soft); border-color: #dbe3ff; color: var(--accent-ink);
}
.btn-mini:focus-visible { outline: none; box-shadow: 0 0 0 3px rgba(37,99,235,.22); }
.btn-mini:disabled { opacity: .4; cursor: default; }
.btn-mini:disabled:hover { background: transparent; border-color: transparent; color: var(--muted); }

/* Les boutons ne se révèlent qu'au survol de la ligne : au repos ils restent
   présents mais estompés, pour ne pas saturer un tableau de 2 400 lignes. */
.st-table tbody tr .btn-mini,
#data-table tbody tr .btn-mini { opacity: .55; }
.st-table tbody tr:hover .btn-mini,
#data-table tbody tr:hover .btn-mini,
.st-table tbody tr .btn-mini:focus-visible,
#data-table tbody tr .btn-mini:focus-visible { opacity: 1; }

/* Variante « action à risque » : retrait d'un produit de la marketplace. Le
   rouge ne s'allume qu'au survol du bouton lui-même — le geste reste par
   ailleurs protégé par une confirmation. */
.btn-mini-danger:hover {
    background: var(--err-bg); border-color: var(--err-bd); color: var(--err-ink);
}

/* Ligne rafraîchie par un contrôle : surlignage fugace. */
@keyframes st-refreshed-flash {
    from { background: var(--accent-soft); }
    to   { background: transparent; }
}
.st-refreshed { animation: st-refreshed-flash 1.6s ease-out 1; }
@media (prefers-reduced-motion: reduce) {
    .st-refreshed { animation: none; }
}

/* ================================================================== *
 *  Étapes d'import en direct                                         *
 *  Alimenté par l'action `progress` du module, sondée pendant le     *
 *  POST : chaque page récupérée s'affiche sans attendre la fin.      *
 * ================================================================== */
.import-steps {
    margin-top: 14px;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    overflow: hidden;
}
.import-steps-head {
    padding: 10px 14px;
    font-weight: 650;
    background: var(--surface-2);
    border-bottom: 1px solid var(--border);
}
.import-steps-list {
    margin: 0;
    padding: 8px 14px 10px 14px;
    list-style: none;
    max-height: 320px;
    overflow-y: auto;
    font-size: 13px;
    line-height: 1.6;
}
.import-steps-list li {
    display: flex;
    gap: 10px;
    align-items: baseline;
    flex-wrap: wrap;
    padding: 2px 0;
    border-bottom: 1px dashed var(--border);
}
.import-steps-list li:last-child { border-bottom: 0; }
.import-step-meta {
    flex: 0 0 auto;
    min-width: 160px;
    color: var(--muted);
    font-variant-numeric: tabular-nums;
    font-size: 12px;
}
.import-step-label { flex: 1 1 240px; }
.import-steps-list code {
    font-size: 11.5px;
    color: var(--muted);
}
.import-step-fatal .import-step-label {
    color: var(--danger, #b42318);
    font-weight: 650;
}

/* ================================================================== *
 *  Panneau de debug Amazon SP-API                                    *
 *  Visible uniquement quand modules.amazon.debug vaut true.          *
 * ================================================================== */
.amz-debug {
    margin-top: 18px;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    box-shadow: var(--shadow);
    overflow: hidden;
}
.amz-debug > summary {
    cursor: pointer;
    padding: 12px 14px;
    font-weight: 650;
    background: var(--surface-2);
    border-bottom: 1px solid var(--border);
    display: flex; align-items: center; gap: 10px;
}
.amz-debug > summary::marker { color: var(--muted-2); }
.amz-debug-count {
    font-weight: 500; font-size: 12px; color: var(--muted);
    border: 1px solid var(--border); border-radius: 999px; padding: 1px 9px;
    background: var(--surface);
}

.amz-debug-call { padding: 12px 14px; border-bottom: 1px solid var(--border-soft); }
.amz-debug-call:last-child { border-bottom: none; }

.amz-debug-head { display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap; }
.amz-debug-badge {
    display: inline-block; min-width: 46px; text-align: center;
    padding: 2px 8px; border-radius: 999px;
    border: 1px solid var(--border); background: var(--surface-2);
    font-size: 12px; font-weight: 700;
}
.amz-debug-badge.amz-ok   { background: var(--ok-bg);  border-color: var(--ok-bd);  color: var(--ok-ink); }
.amz-debug-badge.amz-err  { background: var(--err-bg); border-color: var(--err-bd); color: var(--err-ink); }
.amz-debug-badge.amz-warn { background: #fffbeb;       border-color: #fde68a;       color: #92400e; }
.amz-debug-badge.amz-sim  { background: var(--accent-soft); border-color: #c7d2fe;  color: var(--accent-ink); }

.amz-debug-method { font-weight: 700; font-size: 12.5px; }
.amz-debug-url {
    font-family: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
    font-size: 12px; word-break: break-all; flex: 1 1 320px;
}
.amz-debug-meta { font-size: 12px; color: var(--muted); white-space: nowrap; }

.amz-debug-line { margin-top: 6px; font-size: 12.5px; }
.amz-debug-line b { color: var(--muted); font-weight: 600; margin-right: 6px; }
.amz-debug-line code { word-break: break-all; }
.amz-debug-error { color: var(--err-ink); }

.amz-debug-body {
    margin: 4px 0 0;
    padding: 10px 12px;
    max-height: 320px; overflow: auto;
    background: var(--surface-2);
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    font-family: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
    font-size: 12px; line-height: 1.45;
    white-space: pre-wrap; word-break: break-word;
}

/* ================================================================== *
 *  Mapping La Redoute : barre d'outils collante                      *
 * ================================================================== */
/* Le tableau court sur des centaines de lignes : « Enregistrer » posé en
   tête de page imposerait une remontée après chaque correction. La barre
   déborde donc les gouttières de .main-inner pour que les lignes glissent
   dessous sans se laisser voir de part et d'autre. Son z-index passe devant
   les en-têtes de tableau, eux aussi collants. */
.lr-map-bar {
    position: sticky; top: 0; z-index: 6;
    margin-left: -20px; margin-right: -20px;
    padding: 12px 20px;
    border-radius: 0;
    border-left: 0; border-right: 0; border-top: 0;
}

/* Le compteur de manquants n'est pas qu'un chiffre : il mène à la première
   ligne fautive. Il reste dans le fil du texte, souligné en pointillés pour
   annoncer le geste sans se donner des airs de bouton. Sa couleur vient du
   script, qui l'accorde à l'état (rouge s'il manque, vert sinon). */
.lr-manquants-btn {
    padding: 0; border: 0; background: none;
    font: inherit; font-weight: 700; color: inherit;
    cursor: pointer;
    text-decoration: underline dotted; text-underline-offset: 3px;
}
.lr-manquants-btn:hover:not(:disabled) { text-decoration-style: solid; }
.lr-manquants-btn:disabled { cursor: default; text-decoration: none; }

/* Ligne visée par le compteur : un éclat bref, le temps que l'œil la
   rattrape après le défilement. */
@keyframes lr-vise-flash {
    from { background: var(--accent-soft); }
    to   { background: transparent; }
}
tr.lr-vise > td { animation: lr-vise-flash 1.6s ease-out; }
@media (prefers-reduced-motion: reduce) {
    tr.lr-vise > td { animation-duration: 0s; }
}

/* ================================================================== *
 *  Rapport de débogage (écran « Produits à envoyer » La Redoute)     *
 *  Un champ unique, jamais replié : motifs, payloads et appels HTTP  *
 *  d'un seul tenant, sélectionnables et copiables en un bouton.      *
 * ================================================================== */
.lr-dump-box { padding: 0; margin-top: 18px; }
.lr-dump-head {
    display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
    padding: 12px 14px;
    background: var(--surface-2);
    border-bottom: 1px solid var(--border);
}
.lr-dump-head .muted { font-size: 12px; }
.lr-dump-head .btn { margin-left: auto; }

.lr-dump {
    display: block; width: 100%; box-sizing: border-box;
    min-height: 340px; resize: vertical;
    padding: 12px 14px;
    border: 0; border-radius: 0;
    background: var(--surface);
    color: var(--text);
    font-family: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
    font-size: 12px; line-height: 1.45;
    white-space: pre; overflow: auto;
}
.lr-dump:focus { outline: 2px solid var(--accent); outline-offset: -2px; }

/* ================================================================== *
 *  Page « Appels API » du module Amazon                              *
 *  Catalogue des opérations : URL, paramètres, exemples n8n/Make/PHP *
 * ================================================================== */

/* --- Jetons de la page (méthodes, typologies, exigences) --- */
.amz-m {
    display: inline-block; min-width: 46px; text-align: center;
    padding: 3px 8px; border-radius: 6px;
    font-family: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
    font-size: 11px; font-weight: 700; letter-spacing: .04em;
}
.amz-m-get  { background: var(--ok-bg);  color: var(--ok-ink);  border: 1px solid var(--ok-bd); }
.amz-m-post { background: #fff7ed;       color: #9a3412;        border: 1px solid #fed7aa; }

.amz-tag {
    display: inline-block; padding: 2px 8px; border-radius: 999px;
    font-size: 11px; font-weight: 650; letter-spacing: .02em; white-space: nowrap;
}
.amz-tag-type  { background: var(--accent-soft); color: var(--accent-ink); border: 1px solid #dbe3ff; }
.amz-tag-write { background: var(--err-bg); color: var(--err-ink); border: 1px solid var(--err-bd); }

/* --- Encart d'aide en tête de page --- */
.amz-guide {
    background: var(--surface);
    border: 1px solid var(--border); border-radius: var(--radius);
    box-shadow: var(--shadow);
    padding: 4px 18px 16px;
}
.amz-guide-grid {
    display: grid; gap: 2px 28px;
    grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
}
.amz-guide-cell { padding: 14px 0 4px; }
.amz-guide-k {
    display: block; margin-bottom: 6px;
    font-size: 11px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase;
    color: var(--muted-2);
}
.amz-guide-cell p { margin: 0; font-size: 13px; line-height: 1.65; color: var(--muted); }
.amz-guide-cell code { font-size: 11.5px; }
.amz-guide-warn {
    margin: 14px 0 0; padding: 11px 14px; font-size: 12.5px; line-height: 1.6;
    color: var(--muted);
    background: var(--surface-2);
    border: 1px solid var(--border); border-left: 3px solid var(--accent);
    border-radius: var(--radius-sm);
}
.amz-guide-warn b { color: var(--text); }

/* --- Barre d'outils collante --- */
.amz-bar {
    position: sticky; top: 0; z-index: 6;
    display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
    margin: 20px 0 14px; padding: 10px 0;
    background: var(--bg);
    border-bottom: 1px solid var(--border);
}
.amz-api-filter {
    flex: 1 1 300px; max-width: 420px;
    padding: 8px 12px;
    border: 1px solid var(--border); border-radius: var(--radius-sm);
    background: var(--surface); color: var(--text);
    font-size: 13.5px;
}
.amz-api-filter:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft); }
.amz-bar-count { font-size: 12.5px; color: var(--muted); white-space: nowrap; }
.amz-bar-sep { flex: 1 1 auto; }
.amz-bar-btn {
    padding: 7px 12px; cursor: pointer;
    border: 1px solid var(--border); border-radius: var(--radius-sm);
    background: var(--surface); color: var(--muted);
    font-size: 12.5px; font-weight: 600;
}
.amz-bar-btn:hover { color: var(--accent-ink); border-color: var(--accent); background: var(--accent-soft); }

/* --- Sommaire --- */
.amz-api-toc { display: flex; flex-wrap: wrap; gap: 7px; margin-bottom: 26px; }
.amz-api-toc a {
    display: inline-flex; align-items: center; gap: 7px;
    padding: 6px 12px; border-radius: 999px;
    border: 1px solid var(--border); background: var(--surface);
    font-size: 12.5px; font-weight: 600; color: var(--text);
}
.amz-api-toc a:hover { background: var(--accent-soft); border-color: #c7d2fe; color: var(--accent-ink); }
.amz-api-toc-n { font-size: 11px; color: var(--muted-2); font-weight: 500; }

/* --- Catégorie --- */
.amz-api-cat { margin-bottom: 34px; scroll-margin-top: 70px; }
.amz-cat-head { display: flex; align-items: center; gap: 10px; }
.amz-cat-ico { font-size: 17px; line-height: 1; }
.amz-cat-titre { margin: 0; font-size: 16px; font-weight: 650; letter-spacing: -.01em; }
.amz-cat-n {
    padding: 2px 9px; border-radius: 999px;
    background: var(--surface-2); border: 1px solid var(--border);
    font-size: 11px; color: var(--muted);
}
.amz-cat-desc { margin: 6px 0 12px; font-size: 13px; color: var(--muted); max-width: 900px; }

/* --- Opération (accordéon) --- */
.amz-op-list {
    background: var(--surface);
    border: 1px solid var(--border); border-radius: var(--radius);
    box-shadow: var(--shadow);
    overflow: hidden;
}
.amz-op { border-bottom: 1px solid var(--border-soft); scroll-margin-top: 70px; }
.amz-op:last-child { border-bottom: none; }
.amz-op[open] { background: var(--surface-2); }

.amz-op-head {
    display: flex; align-items: flex-start; gap: 12px;
    padding: 12px 14px; cursor: pointer;
    list-style: none;
}
.amz-op-head::-webkit-details-marker { display: none; }
.amz-op-head:hover { background: var(--accent-soft); }
.amz-op[open] > .amz-op-head { background: var(--surface); border-bottom: 1px solid var(--border-soft); }
.amz-op-head > .amz-m { margin-top: 1px; }

.amz-op-main { flex: 1 1 260px; min-width: 0; }
.amz-op-titre { display: block; font-size: 13.5px; font-weight: 600; }
.amz-op-sub {
    display: block; margin-top: 3px;
    font-size: 12.5px; line-height: 1.55; color: var(--muted);
    max-width: 780px;
}
.amz-op-tags { display: flex; align-items: center; gap: 7px; flex-wrap: wrap; margin-top: 1px; }
.amz-op-code { font-size: 11.5px; padding: 2px 7px; }
.amz-chev {
    flex: 0 0 auto; width: 14px; height: 14px; margin: 4px 0 0 2px;
    border-right: 2px solid var(--muted-2); border-bottom: 2px solid var(--muted-2);
    transform: rotate(45deg) translate(-3px, -3px);
    transition: transform .15s ease;
}
.amz-op[open] > .amz-op-head .amz-chev { transform: rotate(-135deg) translate(-3px, -3px); }

.amz-op-body { padding: 16px 18px 20px; background: var(--surface); }
.amz-op-note {
    margin: 0 0 16px; padding: 10px 13px; font-size: 12.5px; line-height: 1.6;
    background: #fffbeb; border: 1px solid #fde68a; border-radius: var(--radius-sm);
    color: #92400e; max-width: 900px;
}

.amz-block { margin-top: 18px; }
.amz-block:first-child { margin-top: 0; }
.amz-h4 {
    margin: 0 0 8px; font-size: 11px; font-weight: 700;
    letter-spacing: .06em; text-transform: uppercase; color: var(--muted-2);
}

/* --- Table des paramètres --- */
.amz-params { border-collapse: collapse; width: 100%; font-size: 13px; }
.amz-params th {
    text-align: left; padding: 7px 10px;
    font-size: 11px; font-weight: 650; letter-spacing: .04em; text-transform: uppercase;
    color: var(--muted-2); background: var(--surface-2);
    border-bottom: 1px solid var(--border); white-space: nowrap;
}
.amz-params td { padding: 8px 10px; border-bottom: 1px solid var(--border-soft); vertical-align: top; }
.amz-params tbody tr:last-child td { border-bottom: none; }
.amz-p-nom {
    font-family: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
    font-size: 12px; font-weight: 600; white-space: nowrap;
}
.amz-p-meta { color: var(--muted); font-size: 12.5px; white-space: nowrap; }
.amz-req {
    display: inline-block; padding: 1px 8px; border-radius: 999px;
    font-size: 11px; font-weight: 650;
}
.amz-req-req { background: var(--err-bg); color: var(--err-ink); border: 1px solid var(--err-bd); }
.amz-req-alt { background: #fffbeb;       color: #92400e;        border: 1px solid #fde68a; }
.amz-req-opt { background: var(--surface-2); color: var(--muted); border: 1px solid var(--border); }
.amz-legend { margin: 8px 0 0; font-size: 12px; color: var(--muted-2); }

/* --- Bloc de code + bouton de copie --- */
.amz-codewrap { position: relative; }
.amz-code {
    margin: 0; padding: 13px 78px 13px 14px;
    max-height: 300px; overflow: auto;
    background: #0f172a; color: #e2e8f0;
    border: 1px solid #1e293b; border-radius: var(--radius-sm);
    font-family: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
    font-size: 12px; line-height: 1.55;
    white-space: pre; tab-size: 4;
}
.amz-code-1 { white-space: pre-wrap; word-break: break-all; max-height: none; }
.amz-codewrap-inline .amz-code { padding-top: 11px; padding-bottom: 11px; }
.amz-copy {
    position: absolute; top: 8px; right: 9px; z-index: 1;
    padding: 3px 10px; border-radius: 6px; cursor: pointer;
    border: 1px solid #334155; background: #1e293b; color: #cbd5e1;
    font-size: 11px; font-weight: 600;
}
.amz-copy:hover { background: #334155; color: #fff; }

/* --- Onglets d'intégration (n8n / Make / PHP) --- */
.amz-tabs-nav { display: flex; gap: 6px; margin-bottom: 10px; }
.amz-tab {
    padding: 5px 14px; cursor: pointer;
    border: 1px solid var(--border); border-radius: 999px;
    background: var(--surface); color: var(--muted);
    font-size: 12.5px; font-weight: 600;
}
.amz-tab:hover { color: var(--text); border-color: var(--muted-2); }
.amz-tab.active {
    background: var(--accent); border-color: var(--accent); color: #fff;
}
.amz-pane { display: none; }
.amz-pane.active { display: block; }
.amz-pane-help { margin: 0 0 8px; font-size: 12.5px; color: var(--muted); max-width: 900px; }
.amz-pane-help code { font-size: 11.5px; }

/* ================================================================== *
 *  Suivi commandes Amazon — table à lignes dépliables                *
 *  Écran modules/amazon/actions/commandes.php. La ligne porte les    *
 *  colonnes de travail ; le reste des champs de commandes.json vit   *
 *  dans un tiroir (un <tr> masqué) ouvert au clic sur le chevron.    *
 * ================================================================== */

/* Libellé réservé aux lecteurs d'écran (en-tête de la colonne chevron). */
.sr-only {
    position: absolute; width: 1px; height: 1px;
    padding: 0; margin: -1px; overflow: hidden;
    clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

.az-table th.az-sortable { cursor: pointer; user-select: none; }
.az-table th.az-sortable:hover { color: var(--text); }
.az-table th.az-sorted { color: var(--text); }
.az-table th .sort-ind { color: var(--accent); margin-left: 5px; font-size: 10px; }

.az-table th.az-th-toggle, .az-table td.az-toggle-cell { width: 34px; padding-right: 0; }

.az-toggle {
    background: none; border: 0; cursor: pointer;
    padding: 0 4px; line-height: 1;
    color: var(--muted-2); font-size: 12px;
}
.az-toggle:hover { color: var(--accent); }
.az-toggle[aria-expanded="true"] { color: var(--accent); }

/* Tiroir : fond légèrement contrasté, pas de survol bleu (ce n'est pas
   une ligne cliquable) ; la cellule vide de gauche aligne le contenu
   sur la colonne « Commande ». */
.az-table tr.az-detail > td { background: var(--surface-2); padding-top: 4px; }
.az-table tr.az-detail:hover > td { background: var(--surface-2); }

.az-dl {
    margin: 0;
    display: grid; gap: 6px 24px;
    grid-template-columns: repeat(auto-fill, minmax(230px, 1fr));
}
.az-dl-item { display: flex; gap: 8px; min-width: 0; }
.az-dl dt {
    flex: 0 0 108px;
    font-size: 12px; color: var(--muted);
    text-transform: uppercase; letter-spacing: .02em;
}
.az-dl dd {
    margin: 0; min-width: 0;
    font-size: 13px; word-break: break-word;
}

/* Sélecteur « Depuis le » à côté du bouton « Synchroniser » (Suivi commandes). */
.az-sync-ctl { display: inline-flex; align-items: center; gap: 8px; }
.az-sync-ctl label { font-size: 13px; color: var(--muted); white-space: nowrap; }
.az-since {
    padding: 7px 10px;
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    background: var(--surface);
    color: var(--text);
    font: inherit; font-size: 13px;
}
.az-since:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft); }
#az-since-help { max-width: 900px; margin: -6px 0 14px; }

/* ================================================================== *
 *  Écran « Configuration » (index.php?core=settings)                 *
 *  Bouton ⚙ à droite du logo → formulaire généré depuis              *
 *  core/settings_schema.php. Navigation par onglets à gauche,        *
 *  réglages groupés en cartes à droite.                              *
 * ================================================================== */

/* Le logo et l'engrenage partagent la même ligne, en tête de sidebar. */
.brand-row { display: flex; align-items: center; gap: 4px; }
.brand-row .brand { flex: 1 1 auto; min-width: 0; }
/* Icône seule (pas de cadre) : plus visuelle, et le pivot au survol dit
   clairement qu'elle est cliquable. */
.brand-cog {
    flex: 0 0 auto;
    margin-top: 6px;
    width: 34px; height: 34px;
    display: grid; place-items: center;
    color: var(--muted-2);
    font-size: 24px; line-height: 1;
    border-radius: 9px;
    text-decoration: none;
    transition: transform .35s ease, color .15s ease,
                width .15s ease, height .15s ease, font-size .15s ease, margin-top .15s ease;
}
.brand-cog .icon { width: 19px; height: 19px; }
.brand-cog:hover {
    color: var(--accent);
    background: var(--accent-soft);
    text-decoration: none;
    transform: rotate(60deg);
}
.brand-cog.active { color: var(--accent-ink); }

.set-layout { display: flex; align-items: flex-start; gap: 20px; }

/* --- Navigation verticale --- */
.set-nav {
    flex: 0 0 220px;
    position: sticky; top: 20px;
    display: flex; flex-direction: column; gap: 2px;
}
.set-tab {
    display: flex; align-items: center; gap: 9px;
    padding: 9px 11px;
    border: 0; border-radius: var(--radius-sm);
    background: none; color: var(--text);
    font: inherit; font-size: 13.5px; text-align: left;
    cursor: pointer;
}
.set-tab:hover { background: var(--surface-2); }
.set-tab.active { background: var(--accent-soft); color: var(--accent-ink); font-weight: 600; }

.set-panes { flex: 1 1 auto; min-width: 0; }

/* --- Recherche transverse --- */
.set-search { display: flex; align-items: center; gap: 12px; margin-bottom: 16px; }
.set-search input {
    flex: 1 1 auto; max-width: 420px;
    padding: 9px 12px;
    border: 1px solid var(--border); border-radius: var(--radius-sm);
    background: var(--surface); color: var(--text);
    font: inherit; font-size: 13.5px;
}
.set-search input:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft); }
.set-search-info { font-size: 12.5px; color: var(--muted); }

/* --- Sections / groupes --- */
.set-pane { display: none; }
.set-pane.active { display: block; }
.set-searching .set-pane { display: block; }   /* la recherche traverse les onglets */
.set-searching .set-nav { opacity: .5; pointer-events: none; }

.set-group { margin-bottom: 18px; padding: 0; overflow: visible; }
.set-group-head {
    padding: 14px 18px;
    border-bottom: 1px solid var(--border-soft);
    background: var(--surface-2);
}
.set-group-head h2 { margin: 0; font-size: 14.5px; font-weight: 650; }
.set-group-help { margin: 5px 0 0; font-size: 12.5px; color: var(--muted); max-width: 900px; }

.set-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
    gap: 18px 22px;
    padding: 18px;
}
.set-field { min-width: 0; display: flex; flex-direction: column; gap: 6px; }
.set-field[hidden] { display: none; }
.set-field-wide { grid-column: 1 / -1; }
.set-field-danger {
    border-left: 3px solid var(--err-bd);
    padding-left: 12px;
}
.set-label { font-size: 13px; font-weight: 600; }
.set-help { margin: 0; font-size: 12px; color: var(--muted); line-height: 1.5; }
.set-path { font-size: 11px; color: var(--muted-2); }

.set-input {
    width: 100%;
    padding: 8px 11px;
    border: 1px solid var(--border); border-radius: var(--radius-sm);
    background: var(--surface); color: var(--text);
    font: inherit; font-size: 13px;
}
.set-input:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft); }
select.set-input { cursor: pointer; }

/* Liste « une valeur par ligne » (type de champ « lines »). */
textarea.set-lines { resize: vertical; min-height: 72px; line-height: 1.5; }
/* Bouton « verser les valeurs proposées » sous une zone « lines ». */
.set-suggest { display: inline-block; margin-top: 6px; text-align: left; }

.set-secret { display: flex; gap: 6px; }
.set-eye { flex: 0 0 auto; padding: 7px 11px; }
.set-eye.active { background: var(--accent-soft); border-color: var(--accent); }

.set-num { display: flex; align-items: center; gap: 8px; }
.set-num .set-input { max-width: 160px; }
.set-unit { font-size: 12.5px; color: var(--muted); }

/* --- Cases à cocher multiples --- */
.set-checks {
    display: flex; flex-wrap: wrap; gap: 6px 16px;
    padding: 9px 11px;
    border: 1px solid var(--border); border-radius: var(--radius-sm);
    background: var(--surface);
}
.set-check { display: inline-flex; align-items: center; gap: 6px; font-size: 12.5px; cursor: pointer; }
.set-check input { cursor: pointer; }
.set-checks-row { border: 0; padding: 0; background: none; }

/* --- Tableau à clés fixes --- */
.set-assoc { width: 100%; border-collapse: collapse; }
.set-assoc th {
    text-align: left; font-weight: 500; font-size: 12.5px; color: var(--muted);
    padding: 4px 12px 4px 0; white-space: nowrap; vertical-align: middle;
}
.set-assoc td { padding: 4px 0; }
.set-assoc td.set-assoc-key { padding-left: 10px; font-size: 11px; color: var(--muted-2); white-space: nowrap; }

/* --- Tableau clé/valeur extensible --- */
.set-map-table { width: 100%; border-collapse: collapse; margin-bottom: 8px; }
.set-map-table th {
    text-align: left; font-size: 11.5px; font-weight: 600;
    text-transform: uppercase; letter-spacing: .03em; color: var(--muted);
    padding: 0 10px 6px 0;
}
.set-map-table td { padding: 3px 10px 3px 0; vertical-align: top; }
.set-map-table th.set-map-x, .set-map-table td.set-map-x { width: 28px; padding-right: 0; }
.set-row-del {
    border: 0; background: none; cursor: pointer;
    color: var(--muted-2); font-size: 13px; padding: 6px 4px; line-height: 1;
}
.set-row-del:hover { color: var(--err-ink); }
.set-map-add { padding: 6px 12px; font-size: 12.5px; }
.set-map-next { display: none; }

/* --- Pied de formulaire --- */
.set-foot {
    display: flex; align-items: center; justify-content: space-between; gap: 20px;
    flex-wrap: wrap;
    margin-top: 22px; padding: 16px 18px;
    border: 1px solid var(--border); border-radius: var(--radius);
    background: var(--surface); box-shadow: var(--shadow);
}
.set-foot p { margin: 0; max-width: 720px; }
.set-changed { margin: 8px 0 0; padding-left: 20px; font-size: 12.5px; columns: 2; }
.set-changed code { font-size: 11.5px; }

@media (max-width: 900px) {
    .set-layout { flex-direction: column; }
    .set-nav { position: static; flex: 1 1 auto; width: 100%; flex-direction: row; flex-wrap: wrap; }
}

/* ================================================================== *
 *  Montages d'automatisation (écrans « Workflows n8n » / « Make »)   *
 * ================================================================== */

.wf {
    margin-bottom: 30px; padding: 18px 20px 20px;
    border: 1px solid var(--border); border-radius: var(--radius);
    background: var(--surface); box-shadow: var(--shadow);
    scroll-margin-top: 70px;
}
.wf-head { display: flex; align-items: flex-start; gap: 12px; flex-wrap: wrap; }
.wf-ico { font-size: 20px; line-height: 1.3; }
.wf-head-txt { flex: 1 1 320px; min-width: 0; }
.wf-titre { margin: 0; font-size: 16px; font-weight: 650; letter-spacing: -.01em; }
.wf-but { margin: 5px 0 0; font-size: 13px; line-height: 1.6; color: var(--muted); max-width: 900px; }

.wf-prereq {
    margin-top: 14px; padding: 10px 14px;
    border-left: 3px solid var(--accent); border-radius: 0 6px 6px 0;
    background: var(--accent-soft);
}
.wf-prereq-k {
    display: block; font-size: 11px; font-weight: 600;
    text-transform: uppercase; letter-spacing: .04em; color: var(--accent-ink);
}
.wf-prereq ul { margin: 6px 0 0; padding-left: 18px; }
.wf-prereq li { font-size: 12.5px; line-height: 1.6; }

.wf-steps td { vertical-align: top; }
.wf-n { width: 26px; color: var(--muted-2); font-size: 12.5px; font-variant-numeric: tabular-nums; }
.wf-cfg { white-space: nowrap; font-size: 12.5px; color: var(--muted); font-family: var(--mono, monospace); }

.wf-notes { margin: 0; padding-left: 18px; }
.wf-notes li { font-size: 12.5px; line-height: 1.7; color: var(--muted); margin-bottom: 4px; }
.wf-notes b { color: var(--text); }

/* ================================================================== *
 *  Ligne produit au code-barres invalide                             *
 * ================================================================== */

/* Un EAN à clé fausse ou mal formé condamne l'article sur toutes les places de
   marché : la ligne entière est teintée en ambre pour que le défaut se voie
   sans lire la colonne EAN. Le motif exact est en infobulle sur la ligne.
   Le fond est posé sur les CELLULES (et non sur <tr>) : c'est le seul moyen de
   passer devant la règle de survol et devant les colonnes figées, qui portent
   elles-mêmes un fond opaque. */
.st-table tbody tr.row-ean-ko > td,
#tromb-table tbody tr.row-ean-ko > td,
#data-table tbody tr.row-ean-ko > td,
#data-table tbody tr.row-ean-ko > td.col-pinned,
#data-table tbody tr.row-ean-ko > td.col-select { background: var(--warn-bg); }

/* Survol : même famille, un cran plus soutenu — sinon la ligne aurait l'air de
   redevenir normale sous la souris. */
.st-table tbody tr.row-ean-ko:hover > td,
#tromb-table tbody tr.row-ean-ko:hover > td,
#data-table tbody tr.row-ean-ko:hover > td,
#data-table tbody tr.row-ean-ko:hover > td.col-pinned,
#data-table tbody tr.row-ean-ko:hover > td.col-select { background: #fdf3d5; }

/* La sélection reste prioritaire : cocher une ligne doit se voir, même fautive. */
#data-table tbody tr.row-ean-ko.row-selected > td,
#data-table tbody tr.row-ean-ko.row-selected > td.col-pinned,
#data-table tbody tr.row-ean-ko.row-selected > td.col-select { background: var(--accent-soft); }

/* Cellule qui porte le code fautif : le code lui-même est souligné en pointillé
   (dashboard générique, où l'infobulle de ligne est masquée par celle des
   cellules). */
#data-table tbody td.cell-ean-ko {
    color: var(--warn-ink); font-weight: 600;
    text-decoration: underline dotted; text-underline-offset: 3px;
}

/* ================================================================== *
 *  Trombinoscope (module Airtable)                                   *
 *  Une ligne par produit non vendu : référence, titre, visuels        *
 *  réordonnables au glisser-déposer. L'écriture Airtable part au     *
 *  relâcher — d'où un état « en cours d'envoi » sur la rangée seule.  *
 * ================================================================== */
.tromb-aide {
    margin: 0 0 14px;
    padding: 10px 14px;
    background: var(--info-bg);
    border: 1px solid var(--info-bd);
    border-radius: var(--radius-sm);
    color: var(--info-ink);
    font-size: 13px;
}

/* La barre d'outils de cet écran ne porte qu'un compteur et le nombre de
   lignes par page : le compteur pousse le sélecteur à droite. */
.toolbar .result-count { margin: 0 auto 0 0; }

.tromb-table { width: 100%; border-collapse: collapse; }
.tromb-table th {
    padding: 8px 10px;
    text-align: left;
    font-size: 11.5px; font-weight: 650;
    text-transform: uppercase; letter-spacing: .04em;
    color: var(--muted);
    border-bottom: 1px solid var(--border);
    white-space: nowrap;
}
.tromb-table td {
    padding: 10px;
    border-bottom: 1px solid var(--border-soft);
    vertical-align: middle;
}
.tromb-table tbody tr:last-child td { border-bottom: none; }
.tromb-table tbody tr:hover { background: var(--surface-2); }

.tromb-col-ref { width: 1%; white-space: nowrap; }
/* Le titre prend la place qu'il reste sans repousser les visuels : au-delà,
   il passe à la ligne plutôt que d'élargir la table. */
.tromb-col-ttl { max-width: 380px; }

/* Rangée de visuels d'UNE ligne. C'est la seule zone de dépôt : un visuel ne
   quitte jamais sa rangée (voir assets/trombinoscope.js). */
.tromb-slots {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    flex-wrap: wrap;
    padding: 4px;
    border: 1px dashed transparent;
    border-radius: var(--radius-sm);
    transition: border-color .12s, opacity .12s;
}

.tromb-slot {
    position: relative;
    margin: 0;
    width: 84px;
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    background: var(--surface-2);
    overflow: hidden;
    cursor: grab;
    box-shadow: var(--shadow);
    transition: border-color .12s, box-shadow .12s, transform .06s;
}
.tromb-slot:hover { border-color: var(--muted-2); box-shadow: var(--shadow-lg); }
.tromb-slot:active { cursor: grabbing; }
.tromb-slot img {
    display: block;
    width: 100%;
    height: 84px;
    object-fit: cover;
    background: var(--surface);
}

/* Rang affiché (1, 2, 3…) : c'est l'ordre des colonnes Airtable, renuméroté
   pendant le geste pour que le résultat se lise avant le relâcher. */
.tromb-rank {
    position: absolute;
    top: 4px; left: 4px;
    min-width: 18px; height: 18px;
    display: inline-flex; align-items: center; justify-content: center;
    padding: 0 5px;
    border-radius: 9px;
    background: rgba(31,36,48,.78);
    color: #fff;
    font-size: 11px; font-weight: 650;
}

/* Visuel en cours de déplacement. */
.tromb-slot.is-dragging { opacity: .45; border-color: var(--accent); transform: scale(.97); }

/* Rangée en cours d'écriture chez Airtable : plus aucun geste accepté tant
   que la réponse n'est pas là, sinon deux PATCH se croiseraient sur la même
   ligne et le dernier arrivé gagnerait. */
.tromb-slots.is-saving { opacity: .55; pointer-events: none; border-color: var(--accent); }

/* Liens de pagination : cet écran pagine côté serveur, ses pages sont donc
   des <a> et non des <button> comme le dashboard générique. */
.pagination a.btn {
    min-width: 34px; height: 34px; min-height: 34px;
    padding: 0 10px;
    font-size: 13px;
}

/* Boutons « Envoyer sur … » : un par marketplace où le produit est déjà en
   ligne. La couleur dit le dernier résultat connu, l'infobulle le détail. */
.tromb-col-mp { width: 1%; white-space: nowrap; }
.tromb-mp { display: flex; flex-direction: column; gap: 6px; align-items: stretch; }
.tromb-mp-btn { min-height: 30px; padding: 0 12px; font-size: 12.5px; justify-content: flex-start; }
.tromb-mp-btn::before {
    content: ""; flex: 0 0 auto;
    width: 8px; height: 8px; border-radius: 50%;
    background: var(--border);
}
.tromb-mp-btn.is-envoye { border-color: var(--ok-bd); background: var(--ok-bg); color: var(--ok-ink); }
.tromb-mp-btn.is-envoye::before { background: var(--ok-ink); }
.tromb-mp-btn.is-simule { border-color: var(--info-bd); background: var(--info-bg); color: var(--info-ink); }
.tromb-mp-btn.is-simule::before { background: var(--info-ink); }
.tromb-mp-btn.is-attente { border-color: var(--warn-bd); background: var(--warn-bg); color: var(--warn-ink); }
.tromb-mp-btn.is-attente::before { background: var(--warn-ink); }
.tromb-mp-btn.is-erreur { border-color: var(--err-bd); background: var(--err-bg); color: var(--err-ink); }
.tromb-mp-btn.is-erreur::before { background: var(--err-ink); }
.tromb-mp-btn.is-cours { opacity: .6; cursor: progress; }
/* Verrou de cadence en cours (décompte du bandeau #tromb-cadence). */
.tromb-mp-btn.is-bloque,
.tromb-mp-btn.is-bloque:hover { opacity: .5; cursor: not-allowed; }
.tromb-mp-btn.is-cours::before { background: var(--accent); animation: tromb-pulse 1s ease-in-out infinite; }
@keyframes tromb-pulse { 50% { opacity: .25; } }

/* Ligne dont l'ordre des visuels est en cours d'écriture : ses boutons
   attendent, sinon la marketplace recevrait l'ordre précédent. */
tr.is-saving .tromb-mp-btn { pointer-events: none; opacity: .5; }

/* Files d'attente La Redoute / Spartoo, avec compte à rebours. */
.tromb-files {
    margin: 0 0 14px;
    padding: 10px 14px;
    background: var(--warn-bg);
    border: 1px solid var(--warn-bd);
    border-radius: var(--radius-sm);
    color: var(--warn-ink);
    font-size: 13px;
}

/* ================================================================== *
 *  Visite guidée (assets/onboarding.js, core/onboarding.php)          *
 * ================================================================== */

/* (?) global : même habillage que l'engrenage, sans le pivot au survol. */
button.brand-cog { border: 0; background: none; cursor: pointer; padding: 0; }
.brand-cog.tour-global-btn:hover { transform: none; }

/* (?) de page : discret, collé au titre. */
.tour-page-btn {
    display: inline-grid; place-items: center;
    width: 24px; height: 24px;
    margin-left: 8px; padding: 0;
    vertical-align: middle;
    border: 0; border-radius: 50%;
    background: none; color: var(--muted-2);
    cursor: pointer;
}
.tour-page-btn .icon { width: 17px; height: 17px; }
.tour-page-btn:hover { color: var(--accent); background: var(--accent-soft); }

/* Surbrillance : l'ombre géante assombrit tout le reste de l'écran. */
.tour-spot {
    position: fixed; z-index: 10000;
    border-radius: var(--radius-sm);
    box-shadow: 0 0 0 9999px rgba(15, 23, 42, .55);
    pointer-events: none;
    transition: top .2s ease, left .2s ease, width .2s ease, height .2s ease;
}
.tour-pop {
    position: fixed; z-index: 10001;
    width: min(380px, calc(100vw - 16px));
    padding: 16px 18px 14px;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    box-shadow: var(--shadow-lg);
}
/* Sans élément ciblé : bulle centrée sur un voile plein. */
.tour-pop-center {
    top: 50% !important; left: 50% !important;
    transform: translate(-50%, -50%);
    box-shadow: 0 0 0 9999px rgba(15, 23, 42, .55), var(--shadow-lg);
}
.tour-where { font-size: 11px; color: var(--muted-2); margin-bottom: 6px; }
.tour-title { margin: 0 0 6px; font-size: 15px; }
.tour-text { margin: 0 0 14px; font-size: 13px; color: var(--muted); line-height: 1.5; white-space: pre-line; }
.tour-foot { display: flex; align-items: center; gap: 10px; }
.tour-fill { flex: 1; }

/* Journal des intégrations (core/journal.php) */
.journal-filters { flex-wrap: wrap; gap: 8px; }
.journal-summary { margin: 12px 0; }
a.badge { text-decoration: none; cursor: pointer; }
a.badge:hover { filter: brightness(.95); }
a.badge.is-active { outline: 2px solid currentColor; outline-offset: 1px; }
.journal-json { max-width: 560px; max-height: 360px; overflow: auto; font-size: 12px; background: var(--accent-soft); padding: 8px; border-radius: 6px; white-space: pre-wrap; word-break: break-word; }
