/* ============================================================
   PCRT - Feuille de style
   Palette : bleu marine profond + accent vert. Police IBM Plex Sans
   hébergée localement (assets/fonts). Échelle fixe 12 à 22 px.
   ============================================================ */

@font-face{font-family:"IBM Plex Sans";font-weight:400;font-style:normal;font-display:swap;src:url(/assets/fonts/ibm-plex-sans-latin-400.woff2) format("woff2")}
@font-face{font-family:"IBM Plex Sans";font-weight:500;font-style:normal;font-display:swap;src:url(/assets/fonts/ibm-plex-sans-latin-500.woff2) format("woff2")}
@font-face{font-family:"IBM Plex Sans";font-weight:600;font-style:normal;font-display:swap;src:url(/assets/fonts/ibm-plex-sans-latin-600.woff2) format("woff2")}

*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }

:root {
    /* ── Brand green (signature) ──────────────────────────────── */
    --primary:        #1d9e75;        /* CTA, active, focus, accents */
    --primary-hover:  #168862;        /* assombri pour hover (4.4:1 AA) */
    --primary-light:  #d8eddf;        /* tint léger pour pills, badges actifs */
    --on-primary:     #ffffff;        /* texte sur primary : 3.4:1 AA-Large bold */
    --primary-text:   #1f7050;        /* version texte sur fond clair (AAA 6.5:1) */
    --primary-glow:   #5dc6a1;        /* version vive pour accents sur fond sombre */
    --accent:         #1d9e75;
    --accent-hover:   #168862;
    --fill:           #15806a;        /* remplissage bouton plein : blanc dessus 4,9:1 (AA) */
    --fill-hover:     #12705a;        /* 6:1 */
    --font: 'IBM Plex Sans', 'Segoe UI', system-ui, -apple-system, 'Helvetica Neue', Arial, sans-serif;
    --sunk: #f1f5f9;                  /* fond enfoncé (pied de modale, survol) */
    --on-fill: #ffffff;               /* texte sur --fill */
    --ok-text: #166534; --warn-text: #92400e; --danger-text: #b91c1c; --info-text: #1e40af; --violet-text: #5b21b6;   /* texte d'état */
    --info-light: #eff6ff; --violet-light: #f5f3ff;                                                              /* teintes claires (danger/warning/success-light existent) */
    --card: #ffffff;                  /* fond des cartes, tableaux, champs (blanc en clair) */
    --surface-2: #f1f5f9;             /* second niveau de surface */
    --btn-border: #cbd5e1;
    --field-border: #7b8b9a;          /* bordure des champs : 3,4:1 sur blanc (WCAG 1.4.11) */
    --scrim: rgba(11,27,41,.5);
    --r-ctl: 6px;                     /* rayon unique des contrôles */

    /* ── Surfaces sombres (navy-teal) ──────────── */
    --navy-deepest:   #0b1b29;        /* sidebar bg, hero bg (le plus foncé) */
    --navy-dark:      #122838;        /* sub-zones sidebar (footer, brand) */
    --navy-mid:       #1c3a4f;        /* dégradé header transition */
    --navy-light:     #2a5063;        /* dégradé header bottom */

    /* ── Sémantique (codes signalisation) ─────────────────────── */
    --danger:         #dc2626;
    --danger-hover:   #b91c1c;
    --danger-light:   #fef2f2;
    --warning:        #d97706;
    --warning-light:  #fffbeb;
    --success:        #16a34a;        /* vert "feu OK" — distinct du brand teal */
    --success-light:  #f0fdf4;

    /* ── Layout ────────────────────────────────────────────────── */
    --sidebar-w:  250px;
    --topbar-h:   56px;
    --bg:         #ffffff;
    --surface:    #f8fafc;
    --border:     #e2e8f0;            /* gris cool subtil (gris froid subtil) */
    --shadow:     0 1px 4px rgba(11,27,41,.06), 0 1px 2px rgba(11,27,41,.04);
    --shadow-md:  0 4px 16px rgba(11,27,41,.10), 0 2px 6px rgba(11,27,41,.06);

    /* ── Texte ─────────────────────────────────────────────────── */
    --text:    #0c1f2e;               /* navy-charcoal corporate */
    --muted:   #5a6873;               /* gris cool (AA 5.4:1 sur blanc) */
    --radius:  10px;

    /* ── Sidebar GRIS CLAIR (refonte v2026-05) ───────────────────
     * Palette claire et neutre, contraste AAA sur le texte. La pastille
     * "active" reste sur la palette primary green pour la continuité
     * de marque (nav active inversée). */
    --sb-bg:           #f1f5f9;                  /* slate 100 */
    --sb-border:       rgba(15,23,42,.10);
    --sb-text:         #334155;                  /* slate 700 — 11.2:1 sur slate 100 */
    --sb-text-hover:   #0f172a;                  /* slate 900 */
    --sb-hover-bg:     rgba(15,23,42,.06);
    --sb-active-bg:    rgba(29,158,117,.14);     /* pill primary green tint doux */
    --sb-active-text:  #0d6e51;                  /* vert foncé — 5.7:1 sur la pastille */
    --sb-active-border:#1d9e75;                  /* barre primary (inchangé) */
    --sb-sub-bg:       rgba(15,23,42,.04);       /* sous-niveau légèrement appuyé */
    /* Note : .sidebar-brand reprend le dégradé du reg-hd (var --header-*)
     * pour assurer la continuité visuelle du bandeau dark sur toute la
     * largeur du viewport — pas de variable dédiée nécessaire. */

    /* ── Headers fullscreen (reg-hd, cp-hd, …) ─────────────────── */
    --header-from:    var(--navy-deepest);       /* #0b1b29 */
    --header-mid:     var(--navy-dark);          /* #122838 */
    --header-to:      var(--navy-mid);           /* #1c3a4f */
}

::selection { background: var(--fill); color: var(--on-fill); }
:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }
body {
    font-family: var(--font);
    font-variant-numeric: tabular-nums;
    font-size: 14px;
    background: var(--bg);
    color: var(--text);
    line-height: 1.55;
    /* 100dvh : prend en compte le chrome dynamique iOS/Android (barre
     * d'adresse, onglets) — sinon le contenu en bas (journal bar) est
     * masqué derrière. Fallback 100vh pour les navigateurs anciens. */
    min-height: 100vh;
    min-height: 100dvh;
    /* Padding-top égal à la hauteur du bandeau global fixed top:0.
     * Approche robuste qui élimine tout risque de margin-collapsing
     * (bug où un margin-top sur .page-wrapper se "collapse" avec le
     * body et n'est plus appliqué). Tous les éléments en flux normal
     * (page-wrapper, etc.) commencent automatiquement sous le bandeau. */
    padding-top: var(--ptopbar-h);
    box-sizing: border-box;
}

a { color: var(--primary); }
a:hover { color: var(--primary-hover); }

/* Anciennement : .login-header img { filter: none } pour la carte login
 * blanche. Avec la refonte glassmorphism (carte translucide sur fond
 * sombre), le logo est ré-inversé en blanc — voir bloc PAGE LOGIN. */

/* ═══════════════════════════════════════════════════════════
   SIDEBAR
   ═══════════════════════════════════════════════════════════ */
.sidebar {
    /* Sidebar positionnée SOUS le bandeau global (.ptopbar) qui occupe
     * désormais la pleine largeur en haut. */
    position: fixed; top: var(--ptopbar-h); left: 0; bottom: 0;
    width: var(--sidebar-w);
    background: var(--sb-bg);
    border-right: 1px solid var(--sb-border);
    display: flex; flex-direction: column;
    z-index: 200; overflow-y: auto; overflow-x: hidden;
    transition: transform .25s ease;
    box-shadow: 2px 0 8px rgba(0,0,0,.06);   /* atténué (sidebar claire) */
}

/* .sidebar-brand : OBSOLÈTE (refonte v2026-05) — la zone du logo est
 * désormais la moitié gauche du bandeau global plein largeur (.ptopbar).
 * Les classes restent en CSS pour ne pas casser des pages legacy mais
 * elles ne sont plus rendues par layout_nav(). */

/* ═══════════════════════════════════════════════════════════
   BANDEAU GLOBAL PLEIN LARGEUR (.ptopbar)
   Position fixe en haut, couvre TOUTE la largeur du viewport.
   À gauche : zone brand (logo, même largeur que la sidebar).
   À droite : contenu spécifique à la page (titre, KPIs, …).
   ═══════════════════════════════════════════════════════════ */
:root {
    /* Hauteur ptopbar réduite de 25% : ancien 92.8 px → 70 px.
     * 1 seule source de vérité utilisée par .ptopbar, .sidebar, .page-wrapper,
     * body.reg-fullscreen .page-wrapper, .cp-panel/.eqdi-panel etc. */
    --ptopbar-h: 70px;
}
.ptopbar {
    position: fixed; top: 0; left: 0; right: 0;
    height: var(--ptopbar-h);
    display: flex; align-items: stretch;
    z-index: 250;
    /* Fond uni (plus de dégradé). On utilise le navy le plus foncé
     * de la palette (--header-from = #0b1b29). */
    background: var(--header-from);
    box-shadow: inset 0 -2px 0 0 var(--primary),
                0 2px 6px rgba(0,0,0,.18);
    box-sizing: border-box;
}
.ptopbar-brand {
    width: var(--sidebar-w);
    flex-shrink: 0;
    display: flex; align-items: center; justify-content: center; gap: .55rem;
    text-decoration: none;
    border-right: 1px solid rgba(255,255,255,.08);
    box-sizing: border-box;
    padding: 0 1rem;
    /* Pas de fond local : on garde la couleur unie du ptopbar pour
     * éviter de reproduire l'effet "deux zones" qu'on cherche à supprimer. */
}
.ptopbar-logo {
    width: 36px; height: 36px; max-width: none; max-height: none;
    border-radius: 0; background: none; display: block;
}
.ptopbar-toggle {
    display: none;                                /* visible uniquement sur mobile */
    background: none; border: none; cursor: pointer;
    color: #fff; font-size: 1.4rem; line-height: 1; padding: .25rem;
}
.ptopbar-content {
    flex: 1; min-width: 0;
    display: flex; align-items: center; gap: 1rem;
    /* padding-right large : réserve la place du menu utilisateur global
     * (.usermenu-wrap, position:fixed right:16px) afin que les éléments
     * alignés à droite (KPIs accueil, refresh-indicator, etc.) ne passent
     * pas SOUS le menu utilisateur. */
    padding: 0 264px 0 2rem;
    position: relative; overflow: hidden;
}
/* Décoration ronde (héritée du reg-hd) à droite du bandeau */
.ptopbar-content::after {
    content: ""; position: absolute;
    right: -40px; top: -40px; width: 180px; height: 180px;
    border-radius: 50%; background: rgba(255,255,255,.04);
    pointer-events: none;
}

/* Conteneur "texte" standard dans la ptopbar (titre + sous-titre) ─────
 * Réutilisable par toutes les pages — équivalent du .reg-hd-text.
 * Tailles compactes pour tenir dans 70 px de hauteur (titre 1rem
 * + sous-titre 0.72rem + line-height 1.2 ≈ 32 px de contenu, le reste
 * est l'air autour, centré verticalement par align-items:center). */
.ptb-text   { flex: 1; min-width: 0; z-index: 1; }
.ptb-text h1{ color: #fff; font-size: 1rem;  font-weight: 700; margin: 0; line-height: 1.2; }
.ptb-text p { color: rgba(255,255,255,.6); font-size: .75rem; margin: .1rem 0 0; line-height: 1.2; }
.ptb-meta   { z-index: 1; color: rgba(255,255,255,.65); font-size: .75rem; }

/* Zone "actions" (boutons à droite du titre) */
.ptb-actions {
    display: flex; align-items: center; gap: .5rem;
    z-index: 1;
}

.sidebar-nav { flex: 1; padding: .5rem 0; overflow-y: auto; }

.nav-section-label {
    font-size: .75rem; font-weight: 700; letter-spacing: .12em;
    text-transform: uppercase; color: var(--muted);
    padding: 1rem 1.25rem .35rem; user-select: none;
}

.nav-link {
    display: flex; align-items: center; gap: .65rem;
    margin: .15rem .6rem;
    padding: .55rem .9rem;
    color: var(--sb-text);
    text-decoration: none; font-size: .84rem; font-weight: 500;
    border-radius: 8px;                     /* pill arrondi nav */
    transition: background .15s ease, color .15s ease;
    cursor: pointer; user-select: none;
}
/* Hover : changement de couleur uniquement, pas de bg (épure). */
.nav-link:hover        { background: transparent; color: var(--sb-text-hover); }
.nav-link.active       { background: var(--sb-active-bg); color: var(--sb-active-text);
                         font-weight: 600; }
.nav-link.group-active { color: var(--sb-text-hover); font-weight: 600; }

.nav-icon    { flex-shrink: 0; width: 20px; height: 20px; display: flex; align-items: center; justify-content: center; }
.nav-icon svg { display: block; width: 18px; height: 18px; }
.nav-label   { flex: 1; }
.nav-chevron { font-size: .75rem; color: var(--sb-text); transition: transform .2s; }
.nav-chevron.open { transform: rotate(90deg); }

.nav-sub {
    display: none;
    /* Aucun bg, aucune bordure : épure totale. L'indentation seule
     * suffit à indiquer la hiérarchie. */
    margin: 0 .6rem .2rem 2rem;
}
.nav-sub.open { display: block; }

.nav-sub-link {
    display: block; padding: .35rem .9rem; font-size: .8rem;
    color: var(--sb-text); text-decoration: none;
    border-radius: 6px;
    transition: color .12s ease, background .12s ease;
}
/* Hover sub-link : changement couleur uniquement, aucun fond. */
.nav-sub-link:hover  { color: var(--sb-text-hover); background: transparent; }
/* Active sub-link : couleur primary green + bold. Aucun fond, aucune bordure.
 * On utilise --primary (vert standard) plutôt que --primary-glow (vert clair),
 * meilleur contraste sur le nouveau fond clair de la sidebar. */
.nav-sub-link.active { color: var(--sb-active-text); font-weight: 600; background: transparent; }

.nav-sep { height: 1px; background: var(--sb-border); margin: .6rem 1.25rem; }

/* .sidebar-footer / .sidebar-user : remplacés par le menu utilisateur
 * global (bouton flottant top-right géré par layout.php). Les classes
 * sont conservées mais inertes pour ne pas casser d'éventuelles pages
 * qui les référenceraient encore. */

/* Inert — l'ancien sidebar-footer (Déconnexion blanc) n'est plus rendu.
 * Conservé en cas de reuse ponctuelle ; restylé pour fond clair. */
.sidebar .btn-secondary {
    background: rgba(15,23,42,.05); color: var(--text);
    border-color: rgba(15,23,42,.15);
}
.sidebar .btn-secondary:hover {
    background: rgba(15,23,42,.10); color: var(--text); border-color: rgba(15,23,42,.25);
}

.sidebar-overlay {
    display: none; position: fixed; inset: 0;
    background: rgba(15,23,42,.45); z-index: 190;
    backdrop-filter: blur(2px);
}
.sidebar-overlay.visible { display: block; }

/* ═══════════════════════════════════════════════════════════
   TOPBAR MOBILE
   ═══════════════════════════════════════════════════════════ */
.topbar {
    display: none; position: fixed; top: 0; left: 0; right: 0;
    height: var(--topbar-h); background: var(--sb-bg);
    border-bottom: 1px solid var(--sb-border);
    align-items: center; padding: 0 1.25rem; gap: .75rem;
    z-index: 180; box-shadow: 0 2px 8px rgba(5,46,33,.20);
}
.topbar-toggle {
    background: none; border: none; cursor: pointer;
    font-size: 1.4rem; color: var(--sb-text-hover); padding: .25rem; line-height: 1;
}

/* ═══════════════════════════════════════════════════════════
   PAGE WRAPPER
   ═══════════════════════════════════════════════════════════ */
.page-wrapper {
    margin-left: var(--sidebar-w);
    /* Pas de margin-top : c'est le body qui a un padding-top égal à
     * la hauteur du bandeau global (.ptopbar). Voir règle body{}. */
    min-height: calc(100vh - var(--ptopbar-h));
}
.container { width: 100%; max-width: 1440px; margin: 0 auto; padding: 2rem 2rem; }

.page-header {
    display: flex; align-items: center; justify-content: space-between;
    margin-bottom: 1.75rem; flex-wrap: wrap; gap: 1rem;
}
.page-title    { font-size: 1.35rem; font-weight: 700; color: var(--text); }
.page-subtitle { font-size: .82rem; color: var(--muted); margin-top: .15rem; }

/* ═══════════════════════════════════════════════════════════
   CARDS
   ═══════════════════════════════════════════════════════════ */
.card {
    background: var(--surface); border: 1px solid var(--border);
    border-radius: var(--radius); box-shadow: var(--shadow); margin-bottom: 1.5rem;
}
.card-header {
    padding: 1rem 1.25rem; border-bottom: 1px solid var(--border);
    display: flex; align-items: center; justify-content: space-between; gap: 1rem;
}
.card-title {
    font-size: .88rem; font-weight: 600; color: var(--text);
    display: flex; align-items: center; gap: .45rem;
}
.card-body { padding: 1.25rem; }

/* ── Stats ── */
.stats-grid {
    display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
    gap: 1.25rem; margin-bottom: 2rem;
}
.stat-card {
    background: var(--surface); border: 1px solid var(--border);
    border-radius: var(--radius); padding: 1.5rem 1.25rem; box-shadow: var(--shadow);
    display: flex; flex-direction: column; gap: .35rem;
    transition: box-shadow .2s;
}
.stat-card:hover { box-shadow: var(--shadow-md); }
.stat-label {
    font-size: .75rem; color: var(--muted); font-weight: 600;
    text-transform: uppercase; letter-spacing: .06em;
}
.stat-value { font-size: 2.2rem; font-weight: 700; line-height: 1; }
.stat-value.green { color: var(--success); }
.stat-value.red   { color: var(--danger); }
.stat-value.blue  { color: var(--primary); }
.stat-value.amber { color: var(--warning); }
.stat-value.muted { color: var(--muted); }

/* ── Carrefour card ── */
.carrefour-card { border-left: 4px solid var(--primary); }
.carrefour-grid {
    display: grid; grid-template-columns: repeat(auto-fill, minmax(175px, 1fr)); gap: 1rem;
}
.info-block { display: flex; flex-direction: column; min-width: 0; }
.info-label {
    font-size: .75rem; color: var(--muted); text-transform: uppercase;
    letter-spacing: .06em; font-weight: 600; margin-bottom: .2rem;
}
.info-value { font-size: .95rem; font-weight: 600; overflow: hidden; }
.info-value .badge { white-space: normal; word-break: break-word; display: inline; }

/* ═══════════════════════════════════════════════════════════
   TABLEAU
   ═══════════════════════════════════════════════════════════ */
.table-wrap {
    background: var(--surface); border: 1px solid var(--border);
    border-radius: var(--radius); box-shadow: var(--shadow); overflow-x: auto;
}
table { width: 100%; border-collapse: collapse; font-size: .85rem; }
thead tr { background: var(--sunk); }
th {
    padding: .75rem 1rem; text-align: left; font-size: .75rem;
    letter-spacing: .08em; text-transform: uppercase;
    color: var(--muted); font-weight: 600; white-space: nowrap;
}
td { padding: .8rem 1rem; border-top: 1px solid var(--border); vertical-align: middle; }
tr:hover td { background: var(--sunk); }
.row-error td { background: var(--danger-light); }

/* ═══════════════════════════════════════════════════════════
   BADGES
   ═══════════════════════════════════════════════════════════ */
.badge {
    display: inline-block; padding: .2rem .6rem; border-radius: 6px;
    font-size: .75rem; font-weight: 600; white-space: nowrap;
}
.badge-blue   { background: var(--info-light); color: var(--info-text); }
.badge-green  { background: var(--success-light); color: var(--ok-text); }
.badge-red    { background: var(--danger-light); color: var(--danger-text); }
.badge-amber  { background: var(--warning-light); color: var(--warn-text); }
.badge-gray   { background: var(--sunk); color: var(--muted); }
.badge-purple { background: var(--violet-light); color: var(--violet-text); }

/* Badges rôle — fond clair (contenu principal) */
.role-admin    { background: var(--info-light); color: var(--info-text); }
.role-operator { background: var(--success-light); color: var(--ok-text); }
.role-viewer   { background: var(--sunk); color: var(--muted); }

/* Badges rôle — sidebar deep green */
.sidebar .role-admin    { background: rgba(29,158,117,.30); color: #d4f4e6; }
.sidebar .role-operator { background: rgba(22,163,74,.25);  color: #bbf7d0; }
.sidebar .role-viewer   { background: rgba(255,255,255,.10); color: #a8c8b9; }

.status-dot { display: inline-flex; align-items: center; gap: .4rem; font-weight: 500; font-size: .84rem; }
.dot { width: 9px; height: 9px; border-radius: 50%; flex-shrink: 0; }
.dot.online  { background: var(--success); box-shadow: 0 0 0 3px rgba(22,163,74,.18); }
.dot.alert   { background: var(--warning); box-shadow: 0 0 0 3px rgba(217,119,6,.18); }
.dot.offline { background: var(--danger);  box-shadow: 0 0 0 3px rgba(220,38,38,.18); }

/* ═══════════════════════════════════════════════════════════
   BOUTONS
   ═══════════════════════════════════════════════════════════ */
.btn {
    display: inline-flex; align-items: center; justify-content: center; gap: .5rem;
    min-height: 36px; padding: 0 1rem;
    border-radius: var(--r-ctl); font-family: inherit; font-size: 14px; font-weight: 500; line-height: 1.2;
    cursor: pointer; text-decoration: none; border: 1px solid transparent;
    transition: background-color .15s ease, border-color .15s ease, color .15s ease; white-space: nowrap;
}
.btn:active:not(:disabled) { transform: translateY(1px); }
.btn:disabled, .btn[aria-disabled="true"] { opacity: .45; cursor: not-allowed; }
.btn.is-loading { position: relative; color: transparent !important; pointer-events: none; }
.btn.is-loading::after { content: ""; position: absolute; width: 14px; height: 14px; border: 2px solid #fff; border-right-color: transparent; border-radius: 50%; animation: btn-spin .7s linear infinite; }
@keyframes btn-spin { to { transform: rotate(360deg); } }
.btn-primary   { background: var(--fill); color: #fff; font-weight: 600; }
.btn-primary:hover:not(:disabled)  { background: var(--fill-hover); color: #fff; }
.btn-danger    { background: var(--danger-hover); color: #fff; font-weight: 600; }
.btn-danger:hover:not(:disabled)   { background: #991b1b; color: #fff; }
.btn-warning   { background: #b45309; color: #fff; font-weight: 600; }
.btn-warning:hover:not(:disabled)  { background: #92400e; }
.btn-success   { background: #15803d; color: #fff; font-weight: 600; }
.btn-success:hover:not(:disabled)  { background: #166534; }
.btn-secondary { background: var(--bg); color: var(--text); border-color: var(--btn-border); }
.btn-secondary:hover:not(:disabled) { background: var(--sunk, #f1f5f9); border-color: var(--muted); color: var(--text); }
.btn-sm   { min-height: 30px; padding: 0 .75rem; font-size: 13px; }
.btn-group { display: flex; gap: .5rem; flex-wrap: wrap; }

/* ═══════════════════════════════════════════════════════════
   FORMULAIRES
   ═══════════════════════════════════════════════════════════ */
.form-card {
    background: var(--surface); border: 1px solid var(--border);
    border-radius: var(--radius); box-shadow: var(--shadow); max-width: 800px;
}
.form-header { padding: 1.1rem 1.5rem; border-bottom: 1px solid var(--border); }
.form-body { padding: 1.5rem; display: flex; flex-direction: column; gap: 1.1rem; }
.form-footer {
    padding: 1rem 1.5rem; border-top: 1px solid var(--border);
    display: flex; gap: .75rem; justify-content: flex-end;
}
.form-section { margin-bottom: 1.5rem; padding-bottom: 1.25rem; border-bottom: 1px solid var(--border); }
.form-section h2 { font-size: .95rem; font-weight: 600; margin-bottom: .75rem; color: var(--primary); }
.form-section h3 { font-size: .85rem; font-weight: 600; margin-bottom: .75rem; }
.form-row     { display: grid; grid-template-columns: 1fr 1fr; gap: 1rem; }
.form-row-3   { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 1rem; }
.form-group   { display: flex; flex-direction: column; gap: .35rem; margin-bottom: .85rem; }
.form-label   { font-size: .8rem; font-weight: 600; color: var(--text); }
.form-label .req { color: var(--danger); margin-left: .15rem; }
.form-control, input[type="text"], input[type="number"], input[type="password"],
input[type="email"], select, textarea {
    padding: .6rem .85rem; border: 1px solid var(--field-border); border-radius: 8px;
    font-size: .875rem; color: var(--text); background: var(--surface);
    transition: border-color .15s, box-shadow .15s; width: 100%;
    font-family: inherit;
}
.form-control:focus, input:focus, select:focus, textarea:focus {
    outline: none; border-color: var(--primary);
    box-shadow: 0 0 0 3px rgba(46,134,193,.12);
}
.form-hint  { font-size: .75rem; color: var(--muted); }
.form-actions { margin-top: 1.25rem; display: flex; gap: .75rem; }

/* ═══════════════════════════════════════════════════════════
   ALERTES
   ═══════════════════════════════════════════════════════════ */
.alert {
    padding: .85rem 1.15rem; border-radius: 8px; font-size: .84rem;
    display: flex; align-items: flex-start; gap: .6rem; margin-bottom: 1.25rem;
}
.alert-error   { background: var(--danger-light);  color: var(--danger-text); border: 1px solid rgba(220,38,38,.2); }
.alert-success { background: var(--success-light); color: var(--ok-text); border: 1px solid rgba(22,163,74,.2); }
.alert-warning { background: var(--warning-light); color: var(--warn-text); border: 1px solid rgba(217,119,6,.2); }
.alert-info    { background: var(--primary-light); color: var(--primary-text); border: 1px solid rgba(29,158,117,.35); }

/* ═══════════════════════════════════════════════════════════
   DIVERS
   ═══════════════════════════════════════════════════════════ */
.filter-bar { display: flex; gap: .75rem; align-items: center; margin-bottom: 1.25rem; flex-wrap: wrap; }
.filter-bar select, .filter-bar input { max-width: 280px; }
.pagination { display: flex; gap: .5rem; justify-content: center; margin-top: 1.5rem; }
.inline-form { display: inline-flex; gap: .5rem; align-items: center; }
.text-muted { color: var(--muted); }
.text-center { text-align: center; }
.nowrap { white-space: nowrap; }
code {
    font-family: 'SFMono-Regular', Consolas, 'Liberation Mono', monospace;
    font-size: .82rem; background: var(--sunk); padding: .15rem .45rem; border-radius: 5px;
    border: 1px solid var(--btn-border); color: var(--text);
}
.monospace { font-family: 'SFMono-Regular', Consolas, monospace; font-size: .82rem; }
.serveur-status { display: flex; align-items: center; gap: .75rem; font-size: .9rem; }

/* ── Applications DIASER ── */
.app-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(130px, 1fr)); gap: .75rem; }
.app-toggle {
    display: flex; flex-direction: column; align-items: center; gap: .3rem;
    padding: 1rem .75rem; background: var(--surface); border: 2px solid var(--border);
    border-radius: var(--radius); cursor: pointer; transition: all .2s;
    text-align: center; user-select: none;
}
.app-toggle:hover { border-color: var(--primary); box-shadow: var(--shadow); }
.app-toggle.app-active, .app-toggle:has(input:checked) {
    border-color: var(--primary); background: var(--primary-light);
}
.app-toggle input[type="checkbox"] { display: none; }
.app-icon { font-size: 1.6rem; line-height: 1; }
.app-name { font-size: .82rem; font-weight: 600; color: var(--text); }
.app-code { font-size: .75rem; color: var(--muted); font-family: monospace; }
.app-badge { font-size: .75rem; color: var(--primary); font-weight: 600; margin-top: .15rem; }

/* ── Badges applications synoptique ── */
.app-badges { display: flex; gap: .5rem; flex-wrap: wrap; margin-bottom: .75rem; }
.app-badge-item {
    display: inline-flex; align-items: center; gap: .35rem;
    padding: .3rem .7rem; border-radius: 6px; font-size: .78rem; font-weight: 500;
}
.app-badge-item.active { background: var(--primary-light); color: var(--primary-text); border: 1px solid rgba(29,158,117,.35); }
.app-badge-item.inactive { background: var(--sunk); color: var(--muted); border: 1px solid var(--border); opacity: .5; }
.app-badge-item small { font-size: .75rem; font-weight: 700; }

/* ── Carte standard (sous-page) ── */
#map-full { height: calc(100vh - 130px); border-radius: var(--radius); border: 1px solid var(--border); box-shadow: var(--shadow); }

/* ── Carte plein écran (Accueil) ──
 * La page Accueil utilise le pattern reg-fullscreen + reg-page + reg-hd + reg-body
 * (cohérence avec /eqdi/, /carrefours/, /mesure/, /configuration/regulation.php).
 * On override le .reg-body pour retirer le padding et laisser la carte +
 * le journalBar flottant remplir l'espace. */
body.accueil-page .reg-body { padding: 0; overflow: hidden; position: relative; z-index: 1; }
body.accueil-page #map-full { width: 100%; height: 100%; background: var(--card); border: none; border-radius: 0; box-shadow: none; }
/* Le bandeau garde son overflow:hidden global. Le menu utilisateur
 * (top-right) est désormais position:fixed via includes/layout.php,
 * donc il n a plus besoin de débordement du reg-hd pour s afficher. */
#map-picker { height: 320px; border-radius: var(--radius); border: 1px solid var(--border); margin-top: .75rem; box-shadow: var(--shadow); }
.leaflet-container { font-family: inherit; }
.leaflet-popup-content { min-width: 200px; font-size: .85rem; }

/* ═══════════════════════════════════════════════════════════
   LIGNES DE FEUX
   ═══════════════════════════════════════════════════════════ */
.feux-section { margin-top: 1rem; padding-top: 1rem; border-top: 1px solid var(--border); }
.feux-title { font-size: .78rem; font-weight: 600; color: var(--muted); margin-bottom: .75rem; display: flex; align-items: center; gap: .5rem; }
.feux-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(140px, 1fr)); gap: .6rem; }
.feu-item {
    display: flex; align-items: center; gap: .6rem;
    padding: .5rem .65rem; background: var(--surface); border-radius: 8px;
    border: 1px solid var(--border); transition: box-shadow .15s;
}
.feu-item:hover { box-shadow: var(--shadow); }
.feu-pastille {
    width: 22px; height: 22px; border-radius: 50%;
    flex-shrink: 0; border: 2px solid rgba(0,0,0,.15);
}
.feu-off         { background: #4a5568; }
.feu-red         { background: #dc2626; box-shadow: 0 0 8px rgba(220,38,38,.5); }
.feu-red-blink   { background: #dc2626; animation: feu-blink 1s infinite; }
.feu-amber       { background: #d97706; box-shadow: 0 0 8px rgba(217,119,6,.5); }
.feu-amber-blink { background: #d97706; animation: feu-blink 1s infinite; }
.feu-green       { background: #15803d; box-shadow: 0 0 8px rgba(22,163,74,.5); }
.feu-green-blink { background: #15803d; animation: feu-blink 1s infinite; }
.feu-red-amber   { background: linear-gradient(135deg, #dc2626 50%, #d97706 50%); }
.feu-open        { background: #cbd5e1; box-shadow: 0 0 5px rgba(148,163,184,.6); } /* OUVERT — couleur non configurée */
.feu-none        { background: var(--border); border-style: dashed; }
.feu-unknown     { background: #9ca3af; }
@keyframes feu-blink {
    0%, 100% { opacity: 1; }
    50% { opacity: .2; }
}
.feu-info { display: flex; flex-direction: column; min-width: 0; }
.feu-num { font-size: .75rem; font-weight: 600; color: var(--text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.feu-label { font-size: .75rem; color: var(--muted); }

/* ── Config lignes de feux (formulaire) ── */
.lignes-config { margin-top: .75rem; padding-top: .75rem; border-top: 1px dashed var(--border); }
.lignes-header {
    display: flex; align-items: center; justify-content: space-between;
    margin-bottom: .5rem;
}
.lignes-toggle {
    display: flex; align-items: center; gap: .5rem;
    font-size: .82rem; font-weight: 600; color: var(--muted);
    cursor: pointer; user-select: none;
}
.lignes-toggle:hover { color: var(--text); }
.lignes-body { margin-top: .5rem; }
/* En-têtes de colonnes */
.lignes-cols-header {
    display: flex; align-items: center; gap: .5rem;
    padding: .2rem .5rem; margin-bottom: .15rem;
    font-size: .75rem; font-weight: 700; color: var(--muted); text-transform: uppercase; letter-spacing: .04em;
}
.lignes-cols-header .col-num  { width: 58px; flex-shrink: 0; text-align: center; }
.lignes-cols-header .col-desc { flex: 1; min-width: 120px; }
.lignes-cols-header .col-type { width: 320px; flex-shrink: 0; }
.lignes-cols-header .col-del  { width: 32px; flex-shrink: 0; }
.ligne-row {
    display: flex; align-items: center; gap: .5rem;
    padding: .3rem .5rem; margin-bottom: .25rem;
    background: var(--bg); border-radius: 6px; border: 1px solid var(--border);
}
/* Override du padding global (input/select héritent de .6rem .85rem) pour les champs compacts */
.ligne-row input, .ligne-row select { padding: .3rem .5rem; }
/* Numéro de ligne — spécificité (0,2,0) > input[type="number"] (0,1,1) qui impose width:100% */
.ligne-row .ligne-input-num {
    width: 58px; flex-shrink: 0; text-align: center;
    font-weight: 700; color: var(--primary);
}
/* Masquer les flèches spinner (visuellement trop lourd dans un tableau compact) */
.ligne-row .ligne-input-num::-webkit-inner-spin-button,
.ligne-row .ligne-input-num::-webkit-outer-spin-button { -webkit-appearance: none; margin: 0; }
.ligne-row .ligne-input-num { -moz-appearance: textfield; }
/* Description — flex:1 l'emporte sur width:100% via flex-basis:0 de flex:1 */
.ligne-row .ligne-input-desc { flex: 1; min-width: 120px; width: auto; }
/* Type — spécificité (0,2,0) > select (0,0,1), pas de problème mais cohérence */
.ligne-row .ligne-input-type { width: 320px; flex-shrink: 0; }
.ligne-row .btn-danger { padding: .25rem .5rem; font-size: .85rem; line-height: 1; flex-shrink: 0; }

/* ═══════════════════════════════════════════════════════════
   REFRESH INDICATOR & ANIMATIONS
   ═══════════════════════════════════════════════════════════ */
.refresh-indicator {
    display: flex; align-items: center; gap: .5rem;
    font-size: .78rem; color: var(--muted); font-weight: 500;
}
.pulse-dot {
    width: 8px; height: 8px; border-radius: 50%;
    background: var(--success); display: inline-block;
    animation: pulse 2s infinite;
}
@keyframes pulse {
    0%, 100% { opacity: 1; box-shadow: 0 0 0 0 rgba(22,163,74,.4); }
    50% { opacity: .7; box-shadow: 0 0 0 6px rgba(22,163,74,0); }
}
.stat-flash {
    animation: flash .4s ease;
}
@keyframes flash {
    0% { transform: scale(1); }
    50% { transform: scale(1.15); }
    100% { transform: scale(1); }
}
.dashboard-grid {
    display: grid; grid-template-columns: 1fr; gap: 1.25rem;
    margin-bottom: 1.5rem;
}

/* ═══════════════════════════════════════════════════════════
   CHRONOGRAMME
   ═══════════════════════════════════════════════════════════ */
.chronogramme-container {
    margin-top: 1rem; padding-top: 1rem; border-top: 1px solid var(--border);
}
.chrono-title {
    font-size: .78rem; font-weight: 600; color: var(--muted);
    margin-bottom: .5rem; display: flex; align-items: center; gap: .5rem;
}
.chrono-axis {
    display: flex; justify-content: space-between;
    padding-left: 85px; margin-bottom: .25rem;
    font-size: .75rem; color: var(--muted); font-family: monospace;
}
.chrono-row {
    display: flex; align-items: center; gap: 0;
    margin-bottom: 2px; height: 22px;
}
.chrono-row-ligne {
    height: 10px; margin-bottom: 1px;
}
.chrono-row-ligne .chrono-label {
    font-size: .75rem; font-weight: 500; color: var(--muted);
}
.chrono-seg {
    position: absolute; top: 0; height: 100%;
}
.chrono-label {
    width: 85px; flex-shrink: 0; padding-right: .5rem;
    font-size: .75rem; font-weight: 600; color: var(--text);
    text-align: right; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.chrono-bar {
    flex: 1; height: 100%; position: relative;
    background: var(--bg); border-radius: 3px; overflow: hidden;
    border: 1px solid var(--border);
}
/* Quadrillage : uniquement les grandes graduations (toutes les 30 s = 4 traits) */
.chrono-bar::after {
    content: '';
    position: absolute; inset: 0;
    pointer-events: none;
    z-index: 3;
    background-image:
        linear-gradient(90deg,
            rgba(255,255,255,0.30) 0px, rgba(255,255,255,0.30) 1px,
            transparent 1px);
    background-size: calc(100% / 4) 100%;
}
.chrono-segment {
    position: absolute; top: 0; height: 100%;
    z-index: 1;
    display: flex; align-items: center; justify-content: center;
    overflow: hidden;
    /* pas de transition : redraw à 1 s, l'animation width est contre-productive */
}
.chrono-segment[title]:hover { opacity: .8; }
/* Segments tronqués par les bords de la fenêtre temporelle :
 * hachures blanches semi-transparentes sur le bord concerné pour signaler
 * que la durée réelle du segment est inconnue (> durée affichée). */
.chrono-seg-trunc-l {
    border-left: 2px dashed rgba(255,255,255,0.55);
}
.chrono-seg-trunc-r {
    border-right: 2px dashed rgba(255,255,255,0.55);
}
.chrono-seg-dur {
    position: relative; z-index: 2;
    font-family: monospace; font-size: .75rem; font-weight: 700;
    color: rgba(255,255,255,0.90);
    text-shadow: 0 1px 2px rgba(0,0,0,0.5);
    pointer-events: none; white-space: nowrap;
    line-height: 1;
}
.chrono-seg-off         { background: #4a5568; }
.chrono-seg-red         { background: #dc2626; }
.chrono-seg-red-blink   { background: repeating-linear-gradient(90deg, #dc2626 0px, #dc2626 6px, #8b1a1a 6px, #8b1a1a 12px); }
.chrono-seg-amber       { background: #d97706; }
.chrono-seg-amber-blink { background: repeating-linear-gradient(90deg, #d97706 0px, #d97706 6px, #92400e 6px, #92400e 12px); }
.chrono-seg-green       { background: #15803d; }
.chrono-seg-green-blink { background: repeating-linear-gradient(90deg, #15803d 0px, #15803d 4px, #14532d 4px, #14532d 8px); }
.chrono-seg-red-amber   { background: linear-gradient(135deg, #dc2626 50%, #d97706 50%); }
.chrono-seg-open        { background: #cbd5e1; }   /* OUVERT — couleur lampe non configurée */
.chrono-seg-none        { background: var(--border); }
.chrono-seg-unknown     { background: #9ca3af; }
.chrono-seg-dj-0        { background: #1f2937; }   /* DJ bit=0 : FERMÉ (lampe éteinte) */
.chrono-seg-dj-1        { background: var(--success-light); }   /* DJ bit=1 : OUVERT (lampe allumée) */

/* ── Rangées debug DJ ────────────────────────────────────────────── */
.chrono-row-dj { height: 8px; margin-bottom: 1px; }
.chrono-row-dj .chrono-label { font-size: .75rem; }
.chrono-label-dj { font-size: .75rem; font-style: italic; color: #94a3b8; }

/* ── Affichage binaire brut 0/1 ──────────────────────────────────── */
.chrono-bar-bits {
    display: flex;
    align-items: stretch;
    overflow: hidden;
}
.chrono-bit {
    flex-shrink: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 6px;
    font-family: monospace;
    font-weight: 700;
    line-height: 1;
    border-right: 1px solid rgba(0,0,0,0.08);
    box-sizing: border-box;
    overflow: hidden;
}
.chrono-bit-0         { background: #1f2937; color: #6b7280; }   /* tricolore fermé (rouge/jaune) */
.chrono-bit-1         { background: var(--success-light); color: var(--ok-text); }   /* tricolore ouvert (vert) */
.chrono-bit-ped-go    { background: var(--success-light); color: var(--ok-text); }   /* piéton bit=0 = vert (passe) */
.chrono-bit-ped-stop  { background: #fca5a5; color: #7f1d1d; }   /* piéton bit=1 = rouge (stop) */
.chrono-bit-antic     { background: #fde68a; color: #78350f; }   /* anticipation bit=1 = actif */
.chrono-bit-na        { background: #374151; color: #6b7280; font-size: 12px; }
.chrono-bit-future    { background: #111827; }

/* ── Séparateur entre section couleur et section ROUV ─────────── */
.chrono-section-sep {
    padding: 2px 6px;
    font-size: .75rem;
    font-family: monospace;
    font-weight: 700;
    letter-spacing: .08em;
    color: #94a3b8;
    background: #1e293b;
    border-top: 1px solid #334155;
    border-bottom: 1px solid #334155;
    margin: 2px 0;
}
.chrono-label-rouv {
    font-size: .75rem;
    color: #94a3b8;
}
/* Rangées ROUV plus compactes que les rangées couleur */
.chrono-row:has(.chrono-label-rouv) {
    height: 14px;
    margin-bottom: 1px;
}

/* ── Interphase (rouge de dégagement) ────────────────────────────── */
/* Marqueur vertical fin à chaque changement de phase */
.chrono-phase-marker {
    position: absolute;
    top: 0; bottom: 0;
    width: 1px;
    transform: translateX(-50%);
    background: repeating-linear-gradient(
        to bottom,
        rgba(251,191,36,0.9) 0px, rgba(251,191,36,0.9) 3px,
        transparent 3px, transparent 5px
    );
    z-index: 4;
    pointer-events: none;
}
/* Bande hachurée couvrant la durée de l'interphase */
.chrono-interphase {
    position: absolute;
    top: 0; bottom: 0;
    background: repeating-linear-gradient(
        135deg,
        rgba(251, 191, 36, 0.30)  0px,
        rgba(251, 191, 36, 0.30)  4px,
        rgba(17,  24,  39, 0.20)  4px,
        rgba(17,  24,  39, 0.20)  8px
    );
    border-right: 2px solid rgba(251, 191, 36, 0.85);
    z-index: 3;
    pointer-events: none;
}

/* Rangées Plan/Phase : texte par seconde */
.chrono-bar-text {
    background: var(--sunk);   /* fond légèrement différent des rangées couleur */
}
.chrono-bar-text::after {
    /* Même quadrillage que les rangées couleur, mais moins contrasté */
    background-image:
        linear-gradient(90deg,
            rgba(0,0,0,0.10) 0px, rgba(0,0,0,0.10) 1px,
            transparent 1px),
        linear-gradient(90deg,
            rgba(0,0,0,0.25) 0px, rgba(0,0,0,0.25) 1px,
            transparent 1px);
    background-size:
        calc(100% / 120) 100%,
        calc(100% / 12)  100%;
}
.chrono-text-seg {
    position: absolute; top: 0; height: 100%;
    z-index: 1;
    overflow: hidden;
    display: flex; align-items: center; justify-content: center;
    font-family: monospace; font-size: .75rem; font-weight: 700;
    color: var(--text); white-space: nowrap;
    border-right: 1px solid rgba(0,0,0,0.08);
}
.chrono-empty {
    padding: .75rem; text-align: center; color: var(--muted);
    font-size: .78rem; font-style: italic;
}
/* ── Grille état lignes de feux (supervision) ── */
.lignes-feux-grid {
    display: flex; flex-wrap: wrap; gap: 6px;
    padding: .65rem 0 .75rem;
    border-top: 1px solid var(--border);
    margin-top: .5rem;
}
.ligne-dot-wrap {
    display: flex; flex-direction: column; align-items: center; gap: 3px;
    cursor: default;
}
.ligne-dot {
    width: 18px; height: 18px; border-radius: 50%;
    display: block; flex-shrink: 0;
    box-shadow: 0 0 0 2px rgba(0,0,0,.08);
}
.ligne-dot-num {
    font-size: .75rem; font-family: monospace; color: var(--muted); line-height: 1;
}

.chrono-offline {
    display: flex; align-items: center; gap: .6rem;
    padding: .65rem 1rem; margin: .25rem 0;
    background: var(--warning-light); border: 1px solid #fed7aa; border-radius: 6px;
    font-size: .78rem; font-weight: 600; color: #c2410c;
}
.chrono-offline svg { flex-shrink: 0; }
.sartre-banner {
    display: flex; align-items: center; gap: .75rem;
    padding: .75rem 1.25rem; margin-bottom: 1rem;
    background: linear-gradient(135deg, #fff7ed, #fff);
    border: 1.5px solid #fb923c; border-radius: 10px;
    font-size: .83rem; color: #9a3412;
}
.sartre-banner svg { flex-shrink: 0; }
.sartre-banner strong { font-weight: 700; }
.refresh-indicator.offline .pulse-dot {
    background: #f97316 !important;
    box-shadow: 0 0 0 0 rgba(249,115,22,.6) !important;
    animation: none !important;
}

/* ═══════════════════════════════════════════════════════════
   RESPONSIVE — Smartphone & tablette
   ═══════════════════════════════════════════════════════════
   Breakpoints :
     ≤ 1024px  : tablette portrait
     ≤  900px  : seuil bascule sidebar → hamburger (existant)
     ≤  768px  : panels supervision plein écran
     ≤  600px  : tables → blocks empilés
     ≤  480px  : mobile portrait étroit
   Priorités UX mobile :
     - sidebar masquée + hamburger (déjà OK)
     - cibles tactiles ≥ 44 px (recommandation Apple/WCAG)
     - inputs ≥ 16px de font-size (sinon iOS auto-zoom au focus)
     - tables scrollables horizontalement OU empilées en blocks
     - modales et popups pleine largeur
     - boutons et badges sans débordement
   ─────────────────────────────────────────────────────────── */
@media (max-width: 900px) {
    /* Sidebar masquée par défaut, ouverte au tap du burger */
    .sidebar { transform: translateX(-100%); box-shadow: var(--shadow-md); }
    .sidebar.open { transform: translateX(0); }
    /* Bandeau global ne réserve plus la zone brand de var(--sidebar-w) :
     * la zone brand devient compacte (logo seul + burger) */
    .ptopbar-brand   { width: auto; padding: 0 .6rem; }
    .ptopbar-toggle  { display: inline-flex; padding: .35rem .5rem; font-size: 1.35rem; }
    .ptopbar-logo    { width: 30px; height: 30px; }
    /* Le contenu droit du bandeau peut scroller horizontalement si
     * beaucoup de KPIs (carto). Évite l'écrasement / le wrap chaotique.
     * Padding-right = 80px : libère la place pour le bouton user en
     * position:fixed (largeur ~50px + right:16px + marge de sécurité). */
    .ptopbar-content {
        overflow-x: auto; overflow-y: hidden;
        scrollbar-width: none;        /* Firefox */
        -webkit-overflow-scrolling: touch;
        padding: 0 80px 0 .75rem;     /* override du desktop 0 220px 0 2rem */
        gap: .5rem;
        /* Pas de mask-gradient : sur la home, on n\'affiche plus que 3
         * indicateurs (badges défauts + statut serveur) → tout tient sur
         * une ligne, aucun scroll n\'est nécessaire. Les autres pages
         * peuvent l\'activer ponctuellement si besoin. */
    }
    .ptopbar-content::-webkit-scrollbar { display: none; }  /* Chrome/Safari */
    /* Décoration ronde du bandeau : trop volumineuse sur petit écran,
     * elle vampirise la zone de scroll. On la masque. */
    .ptopbar-content::after { display: none; }
    /* Status group : laisse les KPIs en flex inline (pas de wrap → scroll
     * horizontal cohérent avec le parent). */
    .mapbar-status-group { flex-wrap: nowrap !important; }
    .mapbar-status-group > * { flex-shrink: 0; }
    /* Bouton user : passe SOUS le mask gradient (z-index plus haut)
     * pour rester pleinement visible et tactile. */
    .usermenu-wrap { z-index: 1500; }
    .usermenu-btn {
        height: 36px; padding: 0 .65rem;
        background: rgba(15,23,42,.85);
        backdrop-filter: blur(8px);
        border-color: rgba(255,255,255,.30);
    }
    /* Page-wrapper : pleine largeur, sous le ptopbar */
    .page-wrapper    { margin-left: 0; }
    /* L'ancienne .topbar mobile (logo + burger) n'est plus rendue. */
    .topbar          { display: none; }
    /* Formulaires : 1 colonne, inputs hauteur tactile */
    .form-row, .form-row-3 { grid-template-columns: 1fr; }
    .stats-grid { grid-template-columns: repeat(2, 1fr); }
    .container { padding: 1rem .75rem; }
    .page-header { flex-direction: column; align-items: flex-start; gap: .5rem; }
    .page-title { font-size: 1.15rem; }
    .form-card { max-width: 100%; }
    .carrefour-grid { grid-template-columns: repeat(2, 1fr); }

    /* iOS : empêche l'auto-zoom au focus en garantissant 16px sur tous
     * les inputs (la règle habituelle iOS). */
    input, select, textarea, button { font-size: 16px; }

    /* Cibles tactiles : 44px de hauteur minimum sur tous les contrôles
     * interactifs. Sur les .btn-sm on relâche à 38px pour rester compact. */
    .btn,
    .form-control,
    select, input[type=text], input[type=number], input[type=password],
    input[type=email], input[type=search], input[type=tel], input[type=url],
    input[type=date], input[type=time], input[type=datetime-local] {
        min-height: 44px;
    }
    .btn-sm { min-height: 38px; padding: .45rem .75rem; }
    /* checkboxes/radios légèrement agrandies (sans casser la lecture) */
    input[type=checkbox], input[type=radio] {
        width: 18px; height: 18px;
    }

    /* Tables : par défaut, scroll horizontal du conteneur — pattern le
     * moins invasif et qui fonctionne sur 100 % des tables existantes. */
    .table-wrap, .table-responsive { overflow-x: auto; -webkit-overflow-scrolling: touch; }
    table { font-size: .82rem; min-width: max-content; }
    th, td { padding: .55rem .7rem; }

    /* Dialogs / modales : pleine largeur avec marge confortable */
    .app-dialog,
    .modal-card,
    .cp-panel,
    .eqdi-panel {
        max-width: 100% !important;
    }

    /* Boutons groupes : wrap autorisé pour ne pas déborder en bas de form */
    .btn-group, .action-bar { flex-wrap: wrap; gap: .5rem; }
}

@media (max-width: 768px) {
    /* Panels supervision (carrefour/afficheur/EQDi) : pleine largeur viewport */
    .cp-panel,
    #cpPanel,
    #cpPanelAff,
    #cpPanelEqdi,
    .eqdi-panel { left: 0 !important; right: 0; width: 100%; }
    /* Onglets cp-tabs : scroll horizontal si trop nombreux */
    .cp-tabs { overflow-x: auto; -webkit-overflow-scrolling: touch; padding: 0 .5rem !important; }
    .cp-tabs::-webkit-scrollbar { display: none; }
    .cp-tab { padding: .65rem .7rem !important; font-size: .78rem !important; flex-shrink: 0; }
    .cp-body, .cp-pane { padding: 1rem !important; }
    .cp-hd { padding: .8rem 1rem !important; flex-wrap: wrap; }
    .cp-hd h2 { font-size: 1rem !important; }
    /* Grilles 3 colonnes (fonctionnement afficheur) → 1 colonne */
    .aff-fct-grid,
    .cp-fct-grid {
        grid-template-columns: 1fr !important;
    }
    /* Leaflet : agrandit les contrôles de zoom (tactile) */
    .leaflet-control-zoom a {
        width: 38px !important; height: 38px !important;
        line-height: 38px !important; font-size: 22px !important;
    }
}

@media (max-width: 600px) {
    /* Stats : 1 colonne */
    .stats-grid { grid-template-columns: 1fr; }
    .carrefour-grid { grid-template-columns: 1fr; }
    /* Cards : padding réduit */
    .card-header { padding: .8rem 1rem; }
    .card-body   { padding: 1rem; }
    /* Tables avec [data-label] (markup explicite) : empilement en blocks.
     * À ajouter dans les tables critiques (alarmes, journal, historique). */
    table.table-stacked,
    table.table-stacked thead,
    table.table-stacked tbody,
    table.table-stacked tr,
    table.table-stacked th,
    table.table-stacked td { display: block; width: 100%; }
    table.table-stacked thead { display: none; }
    table.table-stacked tr {
        border: 1px solid var(--border); border-radius: 6px;
        margin-bottom: .6rem; padding: .55rem .7rem;
        background: var(--surface);
    }
    table.table-stacked td {
        border: none; padding: .25rem 0;
        display: flex; justify-content: space-between; gap: .8rem;
        font-size: .82rem;
    }
    table.table-stacked td::before {
        content: attr(data-label);
        font-weight: 600; color: var(--muted);
        font-size: .75rem; text-transform: uppercase; letter-spacing: .03em;
        flex-shrink: 0;
    }
}

@media (max-width: 480px) {
    .carrefour-grid { grid-template-columns: 1fr; }
    /* Bandeau global : empile titre/sous-titre verticalement si la page
     * pousse beaucoup de contenu (badges, KPIs, etc.) */
    .ptopbar { min-height: 48px; }
    .ptopbar-content { padding: .35rem .6rem; }
    .container { padding: .75rem .6rem; }
    /* Buttons : full-width sur les actions principales pour faciliter le tap */
    .btn-block-mobile { width: 100%; }
    /* Réduit l'encombrement vertical des labels en uppercase tracking */
    .form-label { font-size: .75rem; margin-bottom: .25rem; }
    /* Boutons d'icônes : padding égalisé pour cible carrée 44x44 */
    .btn-icon { padding: .55rem; }
}

/* Tactile : supprime le délai 300ms du double-tap iOS sur les contrôles */
@media (pointer: coarse) {
    .btn, .nav-link, .nav-sub-link, .cp-tab, .reg-tab,
    [onclick], [role="button"] {
        touch-action: manipulation;
    }
}

/* ═══════════════════════════════════════════════════════════
   FULLSCREEN LAYOUT (.reg-page)
   Pages exploitation/configuration qui prennent toute la hauteur viewport
   avec un bandeau .reg-hd en haut + .reg-body scrollable dessous.
   Activé via body.reg-fullscreen (3e arg de layout_head).
   ═══════════════════════════════════════════════════════════ */
/* Pages fullscreen : page-wrapper occupe la hauteur restante SOUS le
 * bandeau global. Plus aucun calc complexe avec --topbar-h mobile. */
body.reg-fullscreen .page-wrapper {
    display: flex; flex-direction: column;
    /* iOS Safari : 100vh inclut la barre d'adresse + onglets du navigateur,
     * donc bottom:0 (journal bar, légende, etc.) tombait DERRIÈRE la chrome
     * native. 100dvh (dynamic viewport height) exclut le chrome dynamique
     * et est désormais supporté partout (Safari ≥ 15.4, Chrome ≥ 108). On
     * conserve 100vh en fallback pour les navigateurs anciens. */
    height: calc(100vh - var(--ptopbar-h));
    height: calc(100dvh - var(--ptopbar-h));
    overflow: hidden;
    /* Pas de margin-top : le padding-top sur body fait déjà le décalage. */
}
body.reg-fullscreen .container { flex: 1; padding: 0; max-width: none; min-height: 0; display: flex; flex-direction: column; }

.reg-page { flex:1; display:flex; flex-direction:column; min-height:0; background:var(--bg); }

.reg-hd {
    /* Padding HORIZONTAL seulement. Pas de padding vertical : la hauteur
     * est imposée par min-height (avec box-sizing:border-box) et le
     * contenu (titre + sous-titre) est centré verticalement via
     * align-items:center. Sans cela on ajouterait 44.8px (1.4rem×2) à
     * la hauteur, et le reg-hd dépasserait de ~45px le sidebar-brand. */
    padding: 0 2rem;
    display:flex; align-items:center; gap:1rem;
    flex-shrink:0; position:relative; overflow:hidden;
    box-sizing: border-box;
    /* Hauteur minimale alignée sur .sidebar-brand (logo 48px + 2×1.4rem
     * padding) → bandeau dark du logo et bandeau dark du reg-hd ont
     * exactement la même hauteur sur toutes les pages, indépendamment du
     * volume de contenu (titre court, KPIs, ou titre+sous-titre). */
    min-height: calc(1.4rem * 2 + 48px);
}
.reg-hd::after { content:""; position:absolute; right:-40px; top:-40px; width:180px; height:180px; border-radius:50%; background:rgba(255,255,255,.04); pointer-events:none; }
.reg-hd-text   { flex:1; min-width:0; z-index:1; }
.reg-hd-text h1{ color:#fff; font-size:1.15rem; font-weight:700; margin:0; }
.reg-hd-text p { color:rgba(255,255,255,.6); font-size:.78rem; margin:.15rem 0 0; }
.reg-hd-meta   { z-index:1; color:rgba(255,255,255,.65); font-size:.78rem; }

/* Boutons dans le bandeau : btn-secondary version claire-sur-foncé. */
.reg-hd .btn-secondary {
    background: rgba(255,255,255,.10);
    color: #ffffff;
    border-color: rgba(255,255,255,.22);
}
.reg-hd .btn-secondary:hover {
    background: rgba(255,255,255,.18);
    border-color: rgba(255,255,255,.34);
    color: #ffffff;
}

.reg-tabs {
    background:var(--surface); border-bottom:1px solid var(--border);
    display:flex; padding:0 1.75rem; flex-shrink:0; overflow-x:auto;
}
.reg-tab {
    display:inline-flex; align-items:center; gap:.5rem;
    padding:.9rem 1.2rem; font-size:.83rem; font-weight:600;
    color:var(--muted); background:transparent;
    border:none; border-bottom:3px solid transparent;
    cursor:pointer; transition:color .15s,border-color .15s;
    white-space:nowrap; user-select:none;
}
.reg-tab:hover     { color:var(--text); }
.reg-tab.active    { color:var(--primary-text); border-bottom-color:var(--primary); }
.reg-tab svg       { opacity:.75; }
.reg-tab.active svg{ opacity:1; }

.reg-body { flex:1; overflow-y:auto; padding:1.5rem 2rem 2rem; }

/* Toolbar interne (boutons d'action) en haut du .reg-body — remplace
   les boutons qu'on avait dans le bandeau .reg-hd, pour rester cohérent
   avec regulation.php (bandeau = titre+sous-titre uniquement). */
.reg-toolbar {
    display:flex;
    flex-wrap:wrap;
    gap:.5rem;
    align-items:center;
    justify-content:flex-end;
    margin-bottom:1rem;
}
.reg-toolbar > .btn { white-space:nowrap; }
.reg-pane { display:none; animation:regPaneIn .2s ease; }
.reg-pane.active { display:block; }
@keyframes regPaneIn { from { opacity:.4; transform:translateY(6px); } to { opacity:1; transform:none; } }

.reg-pane-hd    { margin-bottom:1.25rem; padding-bottom:.85rem; border-bottom:1px solid var(--border); display:flex; justify-content:space-between; align-items:flex-end; gap:1rem; }
.reg-pane-hd h2 { font-size:1.02rem; margin:0 0 .2rem; color:var(--text); }
.reg-pane-hd p  { margin:0; font-size:.8rem; color:var(--muted); }

.reg-empty {
    display:flex; flex-direction:column; align-items:center; justify-content:center;
    text-align:center; padding:3rem 1rem; color:var(--muted);
}
.reg-empty p       { margin:.5rem 0 0; font-size:.9rem; }
.reg-empty p.small { font-size:.78rem; }

/* ═══════════════════════════════════════════════════════════
   OVERRIDES HEADERS DE PANELS — palette claire (refonte v2026-05)
   Les headers de panels (cp-hd, ep-header, hist-modal-hd, tc-modal-hd)
   adoptent la même couleur de fond que le body (clair). Hauteur réduite
   de 25% par rapport à l'ancien bandeau (1.4rem padding → 1.05rem).
   Texte sombre au lieu de blanc, bordure inférieure subtile pour
   démarquer du contenu en dessous.
   !important nécessaire car les déclarations locales (extra_head) sont
   chargées après et utilisent encore les anciennes valeurs sombres.
   ═══════════════════════════════════════════════════════════ */
.cp-hd,
.ep-header,
.hist-modal-hd,
.tc-modal-hd {
    background: var(--bg) !important;                 /* fond identique au body */
    color: var(--text) !important;
    padding: 1.05rem 2rem !important;                  /* -25% sur le padding vertical */
    min-height: 0 !important;                          /* annule un éventuel min-height legacy */
    border-bottom: 1px solid var(--border) !important; /* séparation subtile */
    box-shadow: none !important;                       /* annule la barre primary verte */
}
/* Décoration ::after (cercle blanc transparent) inutile sur fond clair */
.cp-hd::after,
.ep-header::after,
.hist-modal-hd::after,
.tc-modal-hd::after { display: none !important; }

/* Texte des headers de panel : sombre sur fond clair */
.cp-hd-text h2,
.ep-header-text h2,
.hist-modal-hd h3,
.tc-modal-hd h3 {
    color: var(--text) !important;
    font-size: .98rem !important;                      /* légèrement plus petit (cohérent avec hauteur réduite) */
}
.cp-hd-text p,
.ep-header-text p,
.tc-modal-hd-text p,
.hist-modal-hd p {
    color: var(--muted) !important;
    font-size: .75rem !important;
}
.tc-modal-hd-text h3 { color: var(--text) !important; }
.cp-hd-meta { color: var(--muted) !important; }

/* Bouton fermer (X) : plus de fond sombre, juste un hover gris léger */
.cp-close,
.ep-close {
    background: rgba(15,23,42,.05) !important;
    color: var(--muted) !important;
    width: 32px !important; height: 32px !important;
}
.cp-close:hover,
.ep-close:hover {
    background: rgba(15,23,42,.10) !important;
    color: var(--text) !important;
}

/* Focus rings unifiés sur primary green */
input:focus, select:focus, textarea:focus, button:focus-visible {
    outline-color: var(--primary);
}

/* Liens : primary-text #1f7050 (AAA 6.5:1) sur fond clair, vif sur sombre. */
a       { color: var(--primary-text); }
a:hover { color: var(--primary-hover); text-decoration: underline; }

/* Sidebar : AUCUN underline jamais. Couleur gérée par .nav-link / .nav-sub-link. */
.sidebar a, .sidebar a:hover, .sidebar a:focus, .sidebar a:active {
    text-decoration: none !important;
}

/* Headers : pas d'underline, couleur primary green vif */
.reg-hd a, .cp-hd a, .reg-hd a:hover, .cp-hd a:hover { text-decoration: none; }
.reg-hd a, .cp-hd a       { color: var(--primary); }
.reg-hd a:hover, .cp-hd a:hover { color: var(--primary-glow); }

/* Carrefour-card border : primary green vif convient (large bande latérale). */
.carrefour-card { border-left-color: var(--primary) !important; }

/* Stat values blue → primary-text (AAA sur blanc) */
.stat-value.blue  { color: var(--primary-text); }

/* Textes de marque sur fond clair : passer de var(--primary) (3.4:1) à
 * var(--primary-text) #146247 (6.8:1 AAA) pour assurer la lisibilité. */
.form-section h2,
.app-badge,
.ligne-row .ligne-input-num {
    color: var(--primary-text) !important;
}

/* Form-control focus : ring primary green */
.form-control:focus, input.form-control:focus, select.form-control:focus, textarea.form-control:focus {
    border-color: var(--primary) !important;
    box-shadow: 0 0 0 3px rgba(29,158,117,.22) !important;
}

/* ═══════════════════════════════════════════════════════════
   MENU UTILISATEUR GLOBAL (bouton flottant top-right)
   Présent sur toutes les pages — rendu par includes/layout.php.
   Position fixe sur le viewport, reste sur le bandeau quand il y en
   a un (reg-hd) et flotte au-dessus du contenu sinon.
   ═══════════════════════════════════════════════════════════ */
.usermenu-wrap {
    display: flex; align-items: center; gap: 8px;
    position: fixed;
    /* Centré verticalement sur le bandeau global (.ptopbar) :
     * (ptopbar-h - btn-h) / 2 = (70 - 30) / 2 = 20 → top: 20px.
     * Si --ptopbar-h évolue, mettre à jour ici aussi. */
    top: 20px;
    right: 16px;
    z-index: 1500;                                 /* au-dessus de tout (carte, dropdowns) */
}
@media (max-width: 900px) {
    .usermenu-wrap { top: 20px; right: 12px; }
}

.usermenu-btn {
    display: inline-flex; align-items: center; gap: .4rem;
    height: 30px; padding: 0 .8rem 0 .7rem;         /* meme hauteur que .mapbar-badge */
    border: 1px solid rgba(255,255,255,.20);
    background: rgba(15,23,42,.55);
    color: #ffffff;
    border-radius: 2rem;
    font-size: .8rem; font-weight: 600;
    line-height: 1;
    cursor: pointer;
    backdrop-filter: blur(6px);
    transition: background .15s, border-color .15s;
}
.usermenu-btn:hover {
    background: rgba(15,23,42,.78);
    border-color: rgba(255,255,255,.32);
}
.usermenu-btn .usermenu-name { white-space: nowrap; max-width: 180px; overflow: hidden; text-overflow: ellipsis; }
.usermenu-btn .usermenu-chev { transition: transform .15s; opacity: .8; }
.usermenu-btn.open .usermenu-chev { transform: rotate(180deg); }

.usermenu {
    display: none;
    position: absolute; top: calc(100% + .35rem); right: 0;
    min-width: 250px;
    background: #1e293b;
    border: 1px solid rgba(255,255,255,.10);
    border-radius: .65rem;
    box-shadow: 0 10px 28px rgba(0,0,0,.5);
    overflow: hidden;
}
.usermenu.open { display: block; }
.usermenu-header {
    padding: .85rem 1rem .7rem;
    border-bottom: 1px solid rgba(255,255,255,.08);
    display: flex; align-items: center; justify-content: space-between; gap: .5rem;
}
.usermenu-fullname { font-weight: 700; color: #fff; font-size: .88rem; }
.usermenu-item {
    display: flex; align-items: center; gap: .65rem;
    width: 100%; padding: .65rem 1rem;
    background: transparent; border: none;
    color: #e2e8f0; font-size: .82rem; text-align: left;
    cursor: pointer; text-decoration: none;
    transition: background .12s;
}
.usermenu-item:hover { background: rgba(255,255,255,.06); }
.usermenu-item svg { color: rgba(226,232,240,.75); flex-shrink: 0; }
.usermenu-danger { border-top: 1px solid rgba(255,255,255,.08); }
.usermenu-danger:hover { background: rgba(220,38,38,.18); color: #fecaca; }
.usermenu-danger:hover svg { color: #fecaca; }

/* ═══════════════════════════════════════════════════════════
   MODALE CHANGEMENT DE MOT DE PASSE (globale, layout.php)
   ═══════════════════════════════════════════════════════════ */
.cp-modal-bg {
    position: fixed; inset: 0;
    background: rgba(0,0,0,.55);
    z-index: 2000;
    display: flex; align-items: center; justify-content: center;
    padding: 1rem;
}
.cp-modal-card {
    background: var(--card); border-radius: 8px;
    width: 100%; max-width: 420px;
    box-shadow: 0 20px 50px rgba(0,0,0,.45);
    display: flex; flex-direction: column;
    max-height: calc(100vh - 2rem); overflow: hidden;
}
.cp-modal-hd {
    padding: 1rem 1.25rem; border-bottom: 1px solid var(--border);
    display: flex; align-items: center; justify-content: space-between; gap: 1rem;
    background: var(--surface);
}
.cp-modal-hd h3 { margin: 0; font-size: 1rem; color: var(--text); }
.cp-modal-close {
    background: none; border: none; cursor: pointer;
    color: var(--muted); font-size: 1rem; padding: .2rem .4rem; line-height: 1;
}
.cp-modal-close:hover { color: var(--text); }
.cp-modal-card form { padding: 1.25rem; display: flex; flex-direction: column; gap: .85rem; overflow-y: auto; }
.cp-modal-footer {
    display: flex; justify-content: flex-end; gap: .5rem;
    margin-top: .25rem;
}


/* ═══════════════════════════════════════════════════════════
   MODE SOMBRE - jetons (bascule via <html data-theme="dark">)
   Suit la préférence système tant que l'utilisateur n'a pas choisi.
   ═══════════════════════════════════════════════════════════ */
:root[data-theme="dark"] {
    color-scheme: dark;
    --bg: #0b1b29; --surface: #122838; --sunk: #0e2130;
    --card: #152a3a; --surface-2: #0e2130; --on-fill: #04140e;
    --ok-text: #52c98d; --warn-text: #e8b04a; --danger-text: #f5a8a8; --info-text: #7cc0f0; --violet-text: #c4b5fd;
    --info-light: rgba(93,183,230,.14); --violet-light: rgba(167,139,250,.14);
    --border: #2b4457; --btn-border: #3a5468; --field-border: #5f7d93;
    --text: #e6eef4; --muted: #9db0bf;
    --primary: #3dc19a; --primary-text: #5dc6a1; --primary-light: rgba(61,193,154,.16);
    --fill: #2fae88; --fill-hover: #3dc19a;
    --danger-light: rgba(240,138,138,.12); --warning-light: rgba(232,176,74,.12); --success-light: rgba(82,201,141,.12);
    --shadow: 0 1px 3px rgba(0,0,0,.4); --shadow-md: 0 8px 24px rgba(0,0,0,.5);
    --scrim: rgba(0,0,0,.6);
    --sb-bg: #0e2130; --sb-border: rgba(255,255,255,.08); --sb-text: #b8c9d6; --sb-text-hover: #ffffff;
    --sb-hover-bg: rgba(255,255,255,.06); --sb-active-bg: rgba(61,193,154,.18); --sb-active-text: #7fe0bd;
    --sb-sub-bg: rgba(255,255,255,.04);
}
:root[data-theme="dark"] .btn-primary, :root[data-theme="dark"] .btn-primary:hover:not(:disabled) { color: #04140e; }
:root[data-theme="dark"] .btn-danger { background: #f08a8a; color: #2a0707; }
:root[data-theme="dark"] .btn-danger:hover:not(:disabled) { background: #f4a3a3; color: #2a0707; }
@media (prefers-color-scheme: dark) {
    :root:not([data-theme]) { color-scheme: dark; }
}

/* ═══════════════════════════════════════════════════════════
   MODALE APPLICATIVE (AppDialog) - classes .qd-*
   ═══════════════════════════════════════════════════════════ */
.qd { position: fixed; inset: 0; z-index: 2000; display: flex; align-items: center; justify-content: center; padding: 16px; }
.qd[hidden] { display: none; }
.qd-scrim { position: absolute; inset: 0; background: var(--scrim); }
.qd-box {
    position: relative; width: 100%; max-width: 440px; background: var(--surface);
    border: 1px solid var(--border); border-radius: 8px; box-shadow: 0 8px 24px rgba(0,0,0,.18);
    color: var(--text); outline: none; display: flex; flex-direction: column; max-height: calc(100dvh - 32px);
}
.qd-head { display: flex; align-items: flex-start; gap: 12px; padding: 16px 20px 0; }
.qd-ico { flex: none; margin-top: 2px; display: inline-flex; }
.qd-box[data-variant="info"] .qd-ico, .qd-box[data-variant="success"] .qd-ico { color: var(--primary-text); }
.qd-box[data-variant="warning"] .qd-ico { color: var(--warning); }
.qd-box[data-variant="danger"] .qd-ico { color: var(--danger-hover); }
:root[data-theme="dark"] .qd-box[data-variant="danger"] .qd-ico { color: #f08a8a; }
.qd-title { margin: 0; font-size: 16px; line-height: 1.3; font-weight: 600; }
.qd-body { padding: 4px 20px 16px 52px; overflow: auto; }
.qd-msg { margin: 0; color: var(--muted); font-size: 14px; line-height: 1.5; max-width: 60ch; }
.qd-detail { margin: 12px 0 0; padding: 8px 12px; background: var(--sunk); border: 1px solid var(--border); border-radius: 6px;
    font: 13px/1.45 ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; max-height: 240px; overflow: auto; white-space: pre-wrap; word-break: break-word; }
.qd-foot { display: flex; justify-content: flex-end; gap: 8px; padding: 12px 20px; border-top: 1px solid var(--border); background: var(--sunk); border-radius: 0 0 8px 8px; }
body.qd-open { overflow: hidden; }
@media (max-width: 560px) {
    .qd { align-items: flex-end; padding: 0; }
    .qd-box { max-width: none; border-radius: 12px 12px 0 0; border-bottom: 0; }
    .qd-foot { border-radius: 0; padding-bottom: calc(12px + env(safe-area-inset-bottom)); }
    .qd-foot .btn { flex: 1; }
}
@media (prefers-reduced-motion: reduce) { * { transition: none !important; animation: none !important; } }


/* ═══════════════════════════════════════════════════════════
   BOUTON CLAIR / SOMBRE - soleil qui devient croissant de lune
   (markup : includes/theme_toggle.php ; thème : <html data-theme>)
   ═══════════════════════════════════════════════════════════ */
.theme-toggle {
    flex: none; width: 36px; height: 36px; padding: 0;
    display: inline-grid; place-items: center; cursor: pointer;
    background: var(--bg); color: #d98a00;
    border: 1px solid var(--btn-border); border-radius: var(--r-ctl, 6px);
    transition: background-color .2s ease, border-color .2s ease, color .45s ease;
}
.theme-toggle:hover { background: var(--sunk, #f1f5f9); border-color: var(--muted); }
.theme-toggle:active { transform: scale(.94); }
.theme-toggle--bar {
    width: 30px; height: 30px;
    background: rgba(15,23,42,.55); border-color: rgba(255,255,255,.20); color: #f5b73d;
}
.theme-toggle--bar:hover { background: rgba(15,23,42,.8); border-color: rgba(255,255,255,.4); }
.tt-ico { width: 20px; height: 20px; overflow: visible; }
.tt-core, .tt-cut, .tt-rays {
    transition: transform .5s cubic-bezier(.4, 0, .2, 1), opacity .3s ease;
}
.tt-core { transform-origin: 12px 12px; }
.tt-cut  { transform: translate(18px, -18px); }              /* soleil : le disque de découpe est hors champ */
.tt-rays { transform-origin: 12px 12px; }
:root[data-theme="dark"] .theme-toggle { color: #cfe0ee; }
:root[data-theme="dark"] .theme-toggle--bar { color: #cfe0ee; }
:root[data-theme="dark"] .tt-core { transform: scale(1.6); }                  /* lune : disque plus grand ... */
:root[data-theme="dark"] .tt-cut  { transform: translate(5px, -4px); }       /* ... découpé en croissant */
:root[data-theme="dark"] .tt-rays { transform: rotate(80deg) scale(.2); opacity: 0; }
@media (max-width: 1024px) { .theme-toggle--bar { width: 36px; height: 36px; } }
@media (prefers-reduced-motion: reduce) {
    .tt-core, .tt-cut, .tt-rays, .theme-toggle { transition: none; }
}

/* Bandeau : sous 1500 px le nom d'utilisateur passe dans le menu déroulant
 * (icône + chevron restent) pour libérer de la place aux indicateurs. */
@media (min-width: 601px) and (max-width: 1499px) {
    .usermenu-btn .usermenu-name { display: none; }
    .ptopbar-content { padding-right: 150px; }
}

/* Socle de lisibilité commun aux deux thèmes */
::placeholder { color: var(--muted); opacity: .85; }
:root[data-theme="dark"] .btn-primary,
:root[data-theme="dark"] .btn-primary:hover { color: #04140e !important; }
:root[data-theme="dark"] select, :root[data-theme="dark"] input:not([type="checkbox"]):not([type="radio"]):not([type="range"]):not([type="color"]), :root[data-theme="dark"] textarea {
    color-scheme: dark;
}

/* Mode sombre : graphiques ZingChart et attribution de la carte */
:root[data-theme="dark"] [class*="zc-"] svg text,
:root[data-theme="dark"] [class*="zc-"] svg tspan { fill: var(--muted); }
:root[data-theme="dark"] .zc-abs.zc-legend-frame { background: var(--card) !important; border-color: var(--border) !important; }
:root[data-theme="dark"] .leaflet-control-attribution,
:root[data-theme="dark"] .maplibregl-ctrl-attrib { background: rgba(11,27,41,.78) !important; color: var(--muted) !important; }
:root[data-theme="dark"] .leaflet-control-attribution a,
:root[data-theme="dark"] .maplibregl-ctrl-attrib a { color: var(--primary-text) !important; }
:root[data-theme="dark"] .leaflet-bar a { background: var(--card); color: var(--text); border-color: var(--border); }
:root[data-theme="dark"] .leaflet-bar a:hover { background: var(--sunk); }
:root[data-theme="dark"] .leaflet-popup-content-wrapper, :root[data-theme="dark"] .leaflet-popup-tip { background: var(--card); color: var(--text); }
