/* ==========================================================================
   MODELFLOW — feuille de style
   --------------------------------------------------------------------------
   Partie 1 : socle de la Médiathèque Photosol, repris tel quel (jetons de la
   charte, base, en-tête, structure, formulaires, boutons, tableaux, messages,
   connexion, installateur, administration, pied de page).
   Partie 2 : composants propres à ModelFlow, dessinés avec les mêmes jetons.
   Pour coller au nuancier officiel, ne modifier que le bloc « Jetons de marque ».
   ========================================================================== */
/* --- Jetons de marque ---------------------------------------------------- */
:root {
    /*
     * Bleu Photosol — la teinte officielle. Elle reste réservée au TEXTE et
     * aux petits accents (8:1 sur blanc) : en grand aplat, sa saturation
     * maximale fatigue l'œil.
     * Les nuances foncées se désaturent progressivement (210° de teinte,
     * saturation qui descend de 100 % à 80 %) : c'est ce qui donne un bleu
     * profond plutôt qu'électrique sur les grandes surfaces.
     */
    --ps-blue:         #004F9F;
    --ps-blue-700:     #0A4381;
    --ps-blue-800:     #0A3765;  /* en-tête — 12:1 en blanc dessus */
    --ps-blue-900:     #082A4D;  /* texte sur le jaune — 9,6:1 */
    --ps-blue-050:     #EDF2F8;

    /*
     * Jaune Photosol — couleur de remplissage. À 1,5:1 sur blanc il reste
     * illisible en texte sur fond clair : il sert de fond, avec du bleu
     * profond par-dessus (9,6:1), jamais de couleur de texte sur du blanc.
     */
    --ps-yellow:       #FFCC00;
    --ps-yellow-600:   #F0BE00;
    --ps-yellow-700:   #D6A800;
    --ps-yellow-050:   #FFF7DB;

    /* Bleu profond des surfaces sombres (bandeaux, visionneuse, connexion) */
    --ps-navy:         #0B3762;
    --ps-navy-800:     #10467C;
    --ps-navy-600:     #2A5F91;

    /* Accent solaire, conservé pour les étoiles et les mises en avant */
    --ps-solar:        #F5B301;

    /* Neutres */
    --ps-ink:          #10171F;
    --ps-slate:        #5A6B7C;
    --ps-line:         #E2E8EE;
    --ps-paper:        #FFFFFF;
    --ps-paper-2:      #F5F8FA;

    --danger:          #D7392F;
    --warn:            #E08A0B;
    --ok:              #2FA44F;
}

/* --- Thème clair --------------------------------------------------------- */
:root,
:root[data-theme="light"] {
    --bg:            var(--ps-paper-2);
    --bg-elevated:   var(--ps-paper);
    --bg-sunken:     #EDF2F6;
    --text:          var(--ps-ink);
    --text-muted:    var(--ps-slate);
    --border:        var(--ps-line);
    --border-strong: #CBD5DF;
    /* --brand : aplats et fonds. --brand-text : tout ce qui est écrit. */
    --brand:         var(--ps-yellow);
    --brand-hover:   var(--ps-yellow-600);
    --brand-soft:    var(--ps-yellow-050);
    --on-brand:      var(--ps-blue-900);
    --brand-text:    var(--ps-blue);
    --header-bg:     var(--ps-blue-800);
    --header-text:   #FFFFFF;
    --shadow-sm:     0 1px 2px rgba(16, 23, 31, .06), 0 1px 3px rgba(16, 23, 31, .08);
    --shadow-md:     0 4px 12px rgba(16, 23, 31, .08), 0 2px 4px rgba(16, 23, 31, .06);
    --shadow-lg:     0 18px 48px rgba(16, 23, 31, .16);
    --radius:        12px;
    --radius-sm:     8px;
    --radius-lg:     18px;
}

/* --- Thème sombre -------------------------------------------------------- */
:root[data-theme="dark"] {
    --bg:            #0B141D;
    --bg-elevated:   #111E2A;
    --bg-sunken:     #0A1219;
    --text:          #E7EEF4;
    --text-muted:    #90A4B6;
    --border:        #1D2F3F;
    --border-strong: #2A4054;
    --brand:         var(--ps-yellow);
    --brand-hover:   #FFF3CA;
    --brand-soft:    rgba(253, 233, 166, .14);
    --on-brand:      #082A4D;
    /* Sur fond sombre, le jaune est parfaitement lisible : il sert aussi au texte. */
    --brand-text:    var(--ps-yellow);
    --header-bg:     #0A2A4A;
    --header-text:   #E7EEF4;
    --shadow-sm:     0 1px 2px rgba(0, 0, 0, .4);
    --shadow-md:     0 4px 14px rgba(0, 0, 0, .45);
    --shadow-lg:     0 20px 50px rgba(0, 0, 0, .6);
}

/* --- Base ---------------------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }

/* L'attribut hidden doit toujours l'emporter sur un display: de composant. */
[hidden] { display: none !important; }

/*
 * Gouttière de défilement réservée en permanence.
 *
 * Sans cela, passer d'une page courte à une page longue fait apparaître la
 * barre de défilement et décale toute la mise en page de sa largeur.
 * « overflow-y: scroll » suffit à lui seul et fonctionne partout : la barre
 * est toujours dessinée, donc rien ne bouge jamais. scrollbar-gutter la
 * complète sur les navigateurs récents, notamment quand le défilement est
 * verrouillé (visionneuse ouverte).
 *
 * Aucune bascule conditionnelle ici : c'est précisément le repli vers
 * « auto » qui laissait le décalage réapparaître selon les cas.
 */
html {
    -webkit-text-size-adjust: 100%;
    scroll-behavior: smooth;
    overflow-y: scroll;
    scrollbar-gutter: stable;
}
/* Ouverture de la visionneuse : la page ne défile plus, la gouttière reste réservée. */
html.is-locked { overflow: hidden; }

body {
    margin: 0;
    /* Helvetica Neue en tête ; sous Windows la substitution naturelle est
       Arial, dont le dessin est très proche. */
    font-family: "Helvetica Neue", HelveticaNeue, Helvetica, Arial, "Segoe UI", system-ui, sans-serif;
    font-size: 15px;
    line-height: 1.6;
    color: var(--text);
    background: var(--bg);
    -webkit-font-smoothing: antialiased;
}

img { max-width: 100%; display: block; }
a { color: inherit; text-decoration: none; }
a:hover { color: var(--brand-hover); }
h1, h2, h3, h4 { margin: 0 0 .5em; line-height: 1.25; font-weight: 700; letter-spacing: -.015em; }
h1 { font-size: clamp(1.5rem, 1.1rem + 1.4vw, 2.1rem); }
h2 { font-size: 1.22rem; }
h3 { font-size: 1.02rem; }
p { margin: 0 0 1em; }
code, pre { font-family: ui-monospace, "SFMono-Regular", Menlo, Consolas, monospace; font-size: .86em; }
code { background: var(--bg-sunken); padding: .12em .42em; border-radius: 5px; }
pre.code { background: var(--ps-navy); color: #DCE8F2; padding: 14px 16px; border-radius: var(--radius-sm); overflow-x: auto; }
hr { border: 0; border-top: 1px solid var(--border); margin: 1rem 0; }
.muted { color: var(--text-muted); }
.mono { font-family: ui-monospace, Menlo, Consolas, monospace; font-size: .86em; word-break: break-all; }
.num { text-align: right; font-variant-numeric: tabular-nums; }
.ellipsis { display: inline-block; max-width: 36ch; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; vertical-align: bottom; }

:focus-visible { outline: 2px solid var(--brand-text); outline-offset: 2px; border-radius: 4px; }
/* Dans l'en-tête bleu et la visionneuse, c'est le jaune qui tranche. */
.topbar :focus-visible, .lightbox :focus-visible { outline-color: var(--ps-yellow); }

.skip-link {
    position: absolute; left: -9999px; top: 0; z-index: 999;
    background: var(--brand); color: var(--on-brand); padding: 10px 16px; border-radius: 0 0 8px 0; font-weight: 600;
}
.skip-link:focus { left: 0; }

/* --- Barre supérieure ---------------------------------------------------- */
.topbar {
    position: sticky; top: 0; z-index: 60;
    background: var(--header-bg); color: var(--header-text);
    /* Le filet jaune donne son arête à l'en-tête et met la couleur de marque
       à sa place : un accent, pas un aplat. */
    border-bottom: 2px solid var(--ps-yellow);
    /* Texte clair sur fond foncé : l'anticrénelage fin évite l'effet gras. */
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
}
.topbar__inner {
    max-width: 1680px; margin: 0 auto; padding: 10px 20px;
    display: grid; grid-template-columns: auto minmax(220px, 1fr) auto auto;
    align-items: center; gap: 18px;
}
.brand { display: inline-flex; align-items: center; gap: 10px; color: var(--header-text); flex-shrink: 0; }
.brand__logo { height: 40px; width: auto; }
.brand__fallback { font-weight: 800; letter-spacing: .1em; font-size: .95rem; color: #fff; }
.brand__fallback--dark { color: var(--ps-navy); }
.brand__sep { width: 1px; height: 20px; background: rgba(255, 255, 255, .28); }
.brand__label { font-size: .84rem; text-transform: uppercase; letter-spacing: .14em; color: rgba(255, 255, 255, .82); }

/* Recherche globale */
.searchbar { position: relative; display: flex; align-items: center; }
.searchbar__icon {
    position: absolute; left: 14px; color: var(--text-muted); display: inline-flex; pointer-events: none;
}
.searchbar input[type="search"] {
    width: 100%; padding: 11px 130px 11px 40px; border-radius: 999px;
    border: 1px solid rgba(255, 255, 255, .20); background: rgba(255, 255, 255, .10);
    color: #fff; font-size: .92rem; font-family: inherit; transition: background .15s, border-color .15s;
}
.searchbar input[type="search"]::placeholder { color: rgba(255, 255, 255, .58); }
.searchbar input[type="search"]:focus {
    background: rgba(255, 255, 255, .17); border-color: var(--brand); outline: none;
}
.searchbar__submit {
    position: absolute; right: 5px; padding: 8px 18px; border: 0; border-radius: 999px;
    background: var(--brand); color: var(--on-brand); font-weight: 650; font-size: .85rem; cursor: pointer;
    font-family: inherit; transition: background .15s;
}
.searchbar__submit:hover { background: var(--brand-hover); }

.searchbar__suggestions {
    position: absolute; top: calc(100% + 8px); left: 0; right: 0; z-index: 80;
    background: var(--bg-elevated); color: var(--text);
    border: 1px solid var(--border); border-radius: var(--radius); box-shadow: var(--shadow-lg);
    overflow: hidden; max-height: 60vh; overflow-y: auto;
}
.searchbar__suggestions a {
    display: flex; justify-content: space-between; gap: 12px; padding: 10px 14px; font-size: .9rem;
    border-bottom: 1px solid var(--border);
}
.searchbar__suggestions a:last-child { border-bottom: 0; }
.searchbar__suggestions a:hover,
.searchbar__suggestions a.is-active { background: var(--brand-soft); }
.searchbar__suggestions .sg-type { color: var(--text-muted); font-size: .76rem; text-transform: uppercase; letter-spacing: .08em; }

/* Navigation */
.topnav { display: flex; gap: 4px; }
.topnav__link {
    padding: 8px 12px; border-radius: 8px; font-size: .88rem; font-weight: 500;
    color: rgba(255, 255, 255, .88); white-space: nowrap;
}
.topnav__link:hover { background: rgba(255, 255, 255, .11); color: #fff; }
.topnav__link.is-active { background: rgba(255, 255, 255, .16); color: #fff; }
.topnav__link--admin { color: var(--brand); }

.topbar__actions { display: flex; align-items: center; gap: 8px; }

.icon-btn {
    display: inline-flex; align-items: center; justify-content: center;
    width: 36px; height: 36px; border-radius: 9px; border: 0; cursor: pointer;
    background: rgba(255, 255, 255, .08); color: inherit; transition: background .15s;
}
.icon-btn:hover { background: rgba(255, 255, 255, .18); }
.burger { display: none; }

/* Menu utilisateur */
.usermenu { position: relative; }
.usermenu__trigger {
    display: inline-flex; align-items: center; gap: 8px; padding: 5px 10px 5px 5px;
    background: rgba(255, 255, 255, .08); border: 0; border-radius: 999px; color: inherit;
    cursor: pointer; font-family: inherit; font-size: .86rem;
}
.usermenu__trigger:hover { background: rgba(255, 255, 255, .16); }
.avatar {
    width: 28px; height: 28px; border-radius: 50%; background: var(--brand); color: var(--on-brand);
    display: grid; place-items: center; font-weight: 700; font-size: .8rem;
}
.usermenu__name { max-width: 130px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.usermenu__panel {
    position: absolute; right: 0; top: calc(100% + 8px); min-width: 250px; z-index: 90;
    background: var(--bg-elevated); color: var(--text); border: 1px solid var(--border);
    border-radius: var(--radius); box-shadow: var(--shadow-lg); padding: 8px; display: grid; gap: 2px;
}
.usermenu__panel a { padding: 9px 12px; border-radius: 8px; font-size: .9rem; }
.usermenu__panel a:hover { background: var(--bg-sunken); }
.usermenu__header { padding: 10px 12px; display: grid; gap: 2px; border-bottom: 1px solid var(--border); margin-bottom: 4px; }
.usermenu__header span { font-size: .82rem; color: var(--text-muted); }
.usermenu__logout { color: var(--danger); }

/* --- Structure ----------------------------------------------------------- */
.app-main { min-height: 62vh; }
.page { max-width: 1680px; margin: 0 auto; padding: 20px 20px 64px; }
.page--narrow { max-width: 900px; }

/* En-tête de page : une seule ligne forte — titre, décompte et action — suivie
   au plus près de son contenu. Le décompte qualifie le titre, il n'occupe donc
   pas une ligne pour lui seul. */
.pagehead {
    display: flex; justify-content: space-between; align-items: center; gap: 16px 24px;
    flex-wrap: wrap; margin-bottom: 14px;
}
.pagehead__title { display: flex; align-items: baseline; gap: 4px 12px; flex-wrap: wrap; }
.pagehead__title h1 { margin: 0; }
.pagehead__sub { color: var(--text-muted); margin: 0; }
.pagehead__desc { margin: 6px 0 0; max-width: 70ch; color: var(--text-muted); }
.pagehead__actions { display: flex; gap: 8px; flex-wrap: wrap; }

/* Largeur utile commune à toutes les pages : les sections s'y alignent, quelle
   que soit leur variante. */
:root { --page-max: 1680px; --page-gutter: 20px; }

.section { max-width: var(--page-max); margin: 0 auto; padding: 34px var(--page-gutter); }

/* Une bande teintée s'étend sur toute la largeur pour que sa couleur aille
   d'un bord à l'autre ; c'est son contenu qui est bridé. Comme la section
   garde ses marges intérieures, ce contenu doit être plus étroit d'autant,
   sinon il se décale de 20 px vers la gauche par rapport aux sections
   voisines — décalage invisible en dessous de 1720 px, net au-delà. */
.section--alt { background: var(--bg-sunken); max-width: none; }
.section--alt > * {
    max-width: calc(var(--page-max) - var(--page-gutter) * 2);
    margin-left: auto; margin-right: auto;
}
.section--stats { padding-top: 26px; padding-bottom: 8px; }
.section__head {
    display: flex; justify-content: space-between; align-items: flex-end; gap: 20px;
    margin-bottom: 18px; flex-wrap: wrap;
}
.section__head p { margin: 0; color: var(--text-muted); font-size: .92rem; }
.link-more { color: var(--brand-text); font-weight: 600; font-size: .9rem; white-space: nowrap; }

.panel {
    background: var(--bg-elevated); border: 1px solid var(--border); border-radius: var(--radius);
    padding: 22px; margin-bottom: 22px; box-shadow: var(--shadow-sm);
}
.panel--accent { border-color: var(--brand); box-shadow: 0 0 0 3px var(--brand-soft); }

.layout-split { display: grid; grid-template-columns: 300px minmax(0, 1fr); gap: 26px; align-items: start; }
.layout-split__side { position: sticky; top: 76px; max-height: calc(100vh - 96px); overflow-y: auto; padding-right: 4px; }
.admin-cols { display: grid; grid-template-columns: repeat(auto-fit, minmax(340px, 1fr)); gap: 22px; }


/* --- Statistiques -------------------------------------------------------- */
.statgrid { display: grid; grid-template-columns: repeat(auto-fit, minmax(170px, 1fr)); gap: 14px; margin-bottom: 22px; }
.statgrid--compact { grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); }
.statcard {
    background: var(--bg-elevated); border: 1px solid var(--border); border-radius: var(--radius);
    padding: 16px 18px; display: grid; gap: 2px; box-shadow: var(--shadow-sm);
}
.statcard__value { font-size: 1.5rem; font-weight: 800; letter-spacing: -.02em; }
.statcard__label { font-size: .82rem; font-weight: 600; color: var(--text); }
.statcard__hint { font-size: .74rem; color: var(--text-muted); }


/* --- Formulaires --------------------------------------------------------- */
.field { display: grid; gap: 5px; margin-bottom: 2px; }
.field > span { font-size: .8rem; font-weight: 600; color: var(--text-muted); }
.field--full { grid-column: 1 / -1; }

input[type="text"], input[type="search"], input[type="email"], input[type="password"],
input[type="number"], input[type="date"], select, textarea {
    width: 100%; padding: 9px 12px; border: 1px solid var(--border-strong); border-radius: var(--radius-sm);
    background: var(--bg-elevated); color: var(--text); font-family: inherit; font-size: .9rem;
    transition: border-color .15s, box-shadow .15s;
}
input:focus, select:focus, textarea:focus {
    outline: none; border-color: var(--brand-text); box-shadow: 0 0 0 3px var(--brand-soft);
}
textarea { resize: vertical; min-height: 78px; }
input[type="color"] { padding: 3px; height: 38px; cursor: pointer; }
input[type="range"] { padding: 0; accent-color: var(--brand-text); }
input[type="checkbox"], input[type="radio"] { accent-color: var(--brand-text); width: 16px; height: 16px; }

.checkbox { display: flex; align-items: center; gap: 8px; font-size: .86rem; cursor: pointer; padding: 3px 0; }
.form-grid { display: grid; gap: 14px; }
.form-grid--2 { grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); align-items: end; }
.form-grid__title { grid-column: 1 / -1; margin: 6px 0 0; font-size: .92rem; }
.inline-row { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; }
.inline-row input, .inline-row select { width: auto; min-width: 180px; flex: 0 1 auto; }
.danger-row { display: flex; gap: 12px; align-items: center; flex-wrap: wrap; margin-top: 12px; padding-top: 12px; border-top: 1px solid var(--border); }

.savesearch { display: flex; gap: 8px; }
.savesearch input { min-width: 200px; }

/* --- Boutons ------------------------------------------------------------- */
.btn {
    display: inline-flex; align-items: center; justify-content: center; gap: 7px;
    padding: 10px 18px; border-radius: var(--radius-sm); border: 1px solid transparent;
    font-family: inherit; font-size: .89rem; font-weight: 650; cursor: pointer; white-space: nowrap;
    transition: background .15s, border-color .15s, color .15s, transform .1s;
}
.btn:active { transform: translateY(1px); }
.btn--primary { background: var(--brand); color: var(--on-brand); }
.btn--primary:hover { background: var(--brand-hover); color: var(--on-brand); }
.btn--ghost { background: var(--bg-elevated); border-color: var(--border-strong); color: var(--text); }
.btn--ghost:hover { border-color: var(--ps-yellow-700); color: var(--text); background: var(--brand-soft); }
.btn--ghost.is-on { color: var(--danger); border-color: var(--danger); }
.btn--danger { background: var(--danger); color: #fff; }
.btn--danger:hover { background: #B92E25; color: #fff; }
.btn--ms { background: #fff; color: #1B1B1B; border-color: #D0D5DB; }
.btn--ms:hover { background: #F3F4F6; color: #1B1B1B; }
.btn--lg { padding: 13px 26px; font-size: .95rem; }
.btn--sm { padding: 6px 12px; font-size: .8rem; }
.btn--block { width: 100%; }
.btn[disabled] { opacity: .5; cursor: not-allowed; }

.sticky-save {
    position: sticky; bottom: 0; padding: 14px 0; background: linear-gradient(to top, var(--bg) 60%, transparent);
    display: flex; justify-content: flex-end;
}

/* --- Tableaux ------------------------------------------------------------ */
.table { width: 100%; border-collapse: collapse; font-size: .86rem; }
.table th, .table td { padding: 9px 12px; text-align: left; border-bottom: 1px solid var(--border); vertical-align: top; }
.table th { font-size: .74rem; text-transform: uppercase; letter-spacing: .07em; color: var(--text-muted); font-weight: 650; }
.table--striped tbody tr:nth-child(odd) { background: var(--bg-sunken); }
.table tbody tr:hover { background: var(--brand-soft); }

.badge {
    display: inline-block; padding: 2px 8px; border-radius: 999px; font-size: .7rem; font-weight: 650;
    background: var(--bg-sunken); color: var(--text-muted); border: 1px solid var(--border);
}
.badge--role { background: var(--brand-soft); color: var(--brand-hover); border-color: transparent; }
.badge--done, .badge--running { background: rgba(47, 164, 79, .14); color: var(--ok); }
.badge--failed, .badge--cancelled { background: rgba(215, 57, 47, .12); color: var(--danger); }
.badge--pending { background: rgba(224, 138, 11, .14); color: var(--warn); }
.badge--ai { background: var(--brand-soft); color: var(--brand-hover); }

.simplelist { list-style: none; margin: 0; padding: 0; display: grid; gap: 1px; }
.simplelist li {
    display: flex; justify-content: space-between; gap: 12px; padding: 8px 0;
    border-bottom: 1px solid var(--border); font-size: .86rem;
}
.simplelist li:last-child { border-bottom: 0; }

.healthlist { list-style: none; margin: 0; padding: 0; display: grid; gap: 8px; }
.healthlist__item { display: flex; gap: 11px; align-items: flex-start; font-size: .86rem; }
.healthlist__item > div { display: grid; }
.healthlist__item span:last-child { color: var(--text-muted); font-size: .8rem; }
.healthlist__dot { width: 9px; height: 9px; border-radius: 50%; margin-top: 7px; flex-shrink: 0; background: var(--text-muted); }
.healthlist__item.is-ok .healthlist__dot { background: var(--ok); }
.healthlist__item.is-warn .healthlist__dot { background: var(--warn); }
.healthlist__item.is-error .healthlist__dot { background: var(--danger); }
.healthlist__item.is-off .healthlist__dot { background: var(--border-strong); }

.barchart { display: flex; align-items: flex-end; gap: 6px; min-height: 170px; padding-top: 12px; }
.barchart__col { flex: 1; display: flex; flex-direction: column; justify-content: flex-end; gap: 6px; text-align: center; }
.barchart__bar {
    display: block; height: var(--h); min-height: 4px; background: var(--brand);
    border: 1px solid var(--ps-yellow-700); border-radius: 4px 4px 0 0;
    transition: opacity .15s;
}
.barchart__col:hover .barchart__bar { opacity: .75; }
.barchart__label { font-size: .68rem; color: var(--text-muted); }

/* --- Pagination ---------------------------------------------------------- */
.pagination { display: flex; justify-content: space-between; align-items: center; gap: 16px; margin-top: 26px; flex-wrap: wrap; }
.pagination__summary { font-size: .84rem; color: var(--text-muted); margin: 0; }
.pagination__list { list-style: none; display: flex; gap: 4px; margin: 0; padding: 0; }
.pagination__list a, .pagination__list span {
    display: inline-flex; align-items: center; justify-content: center; min-width: 36px; height: 36px;
    padding: 0 10px; border-radius: 8px; border: 1px solid var(--border); background: var(--bg-elevated);
    font-size: .86rem; font-variant-numeric: tabular-nums;
}
.pagination__list a:hover { border-color: var(--ps-yellow-700); background: var(--brand-soft); }
.pagination__list .is-current { background: var(--brand); color: var(--on-brand); border-color: var(--brand); font-weight: 700; }
.pagination__list .is-disabled, .pagination__list .is-gap { opacity: .4; border-color: transparent; background: none; }

/* --- Fil d'Ariane -------------------------------------------------------- */
.breadcrumb { display: flex; gap: 7px; flex-wrap: wrap; font-size: .84rem; color: var(--text-muted); margin-bottom: 8px; }
.breadcrumb a:hover { color: var(--brand-hover); }
.breadcrumb .is-current { color: var(--text); font-weight: 600; }

/* --- Messages ------------------------------------------------------------ */
.flash-stack { position: fixed; top: 70px; right: 20px; z-index: 95; display: grid; gap: 8px; max-width: 420px; }
.flash-stack--inline, .flash-stack--auth { position: static; max-width: none; margin-bottom: 18px; }
.flash {
    display: flex; align-items: center; gap: 10px; padding: 12px 16px; border-radius: var(--radius-sm);
    background: var(--bg-elevated); border-left: 4px solid var(--brand); box-shadow: var(--shadow-md);
    animation: flash-in .25s ease-out;
}
.flash p { margin: 0; font-size: .88rem; }
.flash--error { border-left-color: var(--danger); }
.flash--warning { border-left-color: var(--warn); }
.flash--info { border-left-color: var(--ps-navy-600); }
.flash__close { margin-left: auto; background: none; border: 0; cursor: pointer; color: var(--text-muted); font-size: 1.2rem; line-height: 1; }
@keyframes flash-in { from { opacity: 0; transform: translateY(-8px); } to { opacity: 1; transform: none; } }

.callout {
    background: var(--brand-soft); border: 1px solid var(--brand); border-radius: var(--radius);
    padding: 14px 18px; margin: 14px 0;
}
.callout--warn { background: rgba(224, 138, 11, .1); border-color: var(--warn); }
.callout p { margin: 4px 0 0; font-size: .86rem; }
.copyrow { display: flex; gap: 8px; align-items: center; margin-top: 10px; flex-wrap: wrap; }
.copyrow code { flex: 1; min-width: 200px; word-break: break-all; }
.testoutput {
    margin-top: 12px; background: var(--ps-navy); color: #DCE8F2; padding: 14px; border-radius: var(--radius-sm);
    max-height: 340px; overflow: auto; font-size: .76rem; white-space: pre-wrap;
}


/* --- Connexion ----------------------------------------------------------- */
.auth-body { margin: 0; min-height: 100vh; background: var(--ps-navy); }
.loginpage { display: grid; grid-template-columns: 1.15fr 1fr; min-height: 100vh; }
/* Le panneau de gauche porte une photographie de réalisation. Le bleu reste
   déclaré en couleur de fond : si l'image tarde ou ne se charge pas, la page
   garde son allure au lieu de virer au blanc. */
.loginpage__visual {
    position: relative; overflow: hidden;
    background-color: var(--ps-navy);
    background-image: url("https://www.photosol.fr/wp-content/uploads/2024/12/bandeau-realisations-2.jpg");
    background-size: cover;
    background-position: center;
    background-repeat: no-repeat;
}

/* Voile bleu par-dessus la photographie : sans lui, la citation en bas et la
   trame deviennent illisibles dès que l'image est claire. Dense en bas, où se
   trouve le texte ; ouvert en haut, pour laisser voir la centrale. */
.loginpage__visual::after {
    content: ""; position: absolute; inset: 0; z-index: 1;
    background: linear-gradient(
        to bottom,
        rgba(8, 42, 77, .34) 0%,
        rgba(10, 55, 101, .52) 45%,
        rgba(8, 42, 77, .86) 100%);
}

/* La trame et la lueur passent au second plan : discrètes sur une photo,
   elles gardent la signature visuelle sans la surcharger. */
.loginpage__grid {
    position: absolute; inset: 0; z-index: 2;
    background-image:
        linear-gradient(rgba(255, 204, 0, .10) 1px, transparent 1px),
        linear-gradient(90deg, rgba(255, 204, 0, .10) 1px, transparent 1px);
    background-size: 46px 46px;
    transform: perspective(700px) rotateX(58deg) scale(2.1); transform-origin: center 32%;
    mask-image: linear-gradient(to bottom, transparent, #000 35%, transparent 92%);
}
.loginpage__glow {
    position: absolute; left: 50%; top: 18%; width: 460px; height: 460px; transform: translateX(-50%); z-index: 2;
    background: radial-gradient(circle, rgba(245, 179, 1, .18), transparent 62%); filter: blur(28px);
}
.loginpage__quote {
    position: absolute; left: 48px; right: 48px; bottom: 56px; margin: 0; z-index: 3;
    color: #fff; text-shadow: 0 1px 12px rgba(0, 20, 40, .55);
    font-size: 1.28rem; line-height: 1.55; font-weight: 500; max-width: 34ch;
}
.loginpage__quote::before { content: ""; display: block; width: 44px; height: 3px; background: var(--ps-yellow); margin-bottom: 18px; }
/* Un titre et sa suite, et non plus une phrase unique : le même couple que
   sur l'accueil, pour que la connexion et la page d'arrivée se répondent. */
.loginpage__quote-titre {
    margin: 0 0 6px; font-size: 1.85rem; font-weight: 700;
    letter-spacing: -.02em; line-height: 1.2;
}
.loginpage__quote-lead { margin: 0; font-size: 1.05rem; font-weight: 400; opacity: .92; }

.loginpage__panel { display: grid; place-items: center; padding: 32px; background: #0B1822; }
.loginpage__box { width: 100%; max-width: 380px; color: #E7EEF4; }
.loginpage__logo { margin-bottom: 26px; width: min(360px, 100%); height: auto; }
.loginpage__box h1 { font-size: 1.55rem; margin-bottom: 4px; }
.loginpage__sub { color: #8FA5B8; margin-bottom: 26px; font-size: .9rem; }
.loginpage__box .field > span { color: #8FA5B8; }
.loginpage__box input {
    background: rgba(255, 255, 255, .06); border-color: rgba(255, 255, 255, .14); color: #fff;
}
.loginpage__box .field { margin-bottom: 14px; }
.loginpage__sep { display: flex; align-items: center; gap: 12px; margin: 20px 0; color: #55697B; font-size: .8rem; }
.loginpage__sep::before, .loginpage__sep::after { content: ""; flex: 1; height: 1px; background: rgba(255, 255, 255, .12); }
.loginpage__legal { margin-top: 26px; font-size: .76rem; color: #55697B; line-height: 1.5; }

/* --- Installateur -------------------------------------------------------- */
.installpage { min-height: 100vh; display: grid; place-items: start center; padding: 40px 20px 80px; }
.installpage__box {
    width: 100%; max-width: 760px; color: #E7EEF4;
    background: #0B1822; border: 1px solid rgba(255, 255, 255, .1);
    border-radius: var(--radius-lg); padding: 32px;
}
.installpage__box--narrow { max-width: 520px; }
.installpage__box h1 { font-size: 1.5rem; }
.installpage__box .field > span { color: #8FA5B8; }
.installpage__box input, .installpage__box select {
    background: rgba(255, 255, 255, .06); border-color: rgba(255, 255, 255, .14); color: #fff;
}
.installpage__box code { background: rgba(255, 255, 255, .08); color: #B7E06B; }
.installpage__box .healthlist__item span:last-child { color: #8FA5B8; }
.installpage__box .filters__hint { color: #7E93A6; }
.installpage__box .callout { background: rgba(224, 138, 11, .12); }

.install-section { margin: 26px 0; padding-top: 22px; border-top: 1px solid rgba(255, 255, 255, .1); }
.install-section:first-of-type { border-top: 0; padding-top: 0; }
.install-section h2 { font-size: 1rem; text-transform: uppercase; letter-spacing: .07em; color: #8FA5B8; }
.install-advanced {
    margin: 22px 0; padding: 14px 16px; border: 1px solid rgba(255, 255, 255, .12); border-radius: var(--radius-sm);
}
.install-advanced > summary { cursor: pointer; font-weight: 600; font-size: .88rem; }
.install-advanced > *:not(summary) { margin-top: 14px; }

/* --- Administration ------------------------------------------------------ */
.admin-shell {
    display: grid; grid-template-columns: 236px minmax(0, 1fr); max-width: 1680px; margin: 0 auto;
    min-height: calc(100vh - 57px);
    background: linear-gradient(to right, var(--bg-elevated) 0 236px, transparent 236px);
}
.admin-sidebar {
    padding: 22px 14px; border-right: 1px solid var(--border); position: sticky; top: 57px;
    height: calc(100vh - 57px); overflow-y: auto; background: var(--bg-elevated);
}
.admin-sidebar__title {
    font-size: .7rem; text-transform: uppercase; letter-spacing: .12em; color: var(--text-muted);
    font-weight: 700; margin: 0 10px 12px;
}
.admin-sidebar nav { display: grid; gap: 2px; }
.admin-sidebar nav a { padding: 8px 11px; border-radius: 8px; font-size: .88rem; }
.admin-sidebar nav a:hover { background: var(--bg-sunken); }
.admin-sidebar nav a.is-active { background: var(--brand); color: var(--on-brand); font-weight: 600; }
.admin-sidebar__foot { margin-top: 22px; padding-top: 14px; border-top: 1px solid var(--border); font-size: .84rem; }
.admin-content { padding: 24px 26px 64px; min-width: 0; }
.admin-content__head { margin-bottom: 18px; }
.admin-content__head h1 { margin: 0; }

/* --- Pages d'erreur ------------------------------------------------------ */
.errorpage { display: grid; place-items: center; gap: 8px; text-align: center; padding: 100px 20px; }
.errorpage__code { font-size: 4.5rem; font-weight: 800; color: var(--brand-text); margin: 0; line-height: 1; }
.errorpage p { color: var(--text-muted); max-width: 46ch; }
.errorpage .btn { margin-top: 14px; }

.minimal-header {
    display: flex; align-items: center; gap: 14px; padding: 14px 22px;
    border-bottom: 1px solid var(--border); background: var(--bg-elevated);
}
.minimal-header__title { color: var(--text-muted); font-size: .9rem; }

/* --- Pied de page -------------------------------------------------------- */
.appfooter { border-top: 1px solid var(--border); background: var(--bg-elevated); margin-top: 40px; }
.appfooter__inner {
    max-width: 1680px; margin: 0 auto; padding: 26px 20px;
    display: flex; justify-content: space-between; align-items: center; gap: 18px; flex-wrap: wrap;
}
.appfooter p { margin: 0; font-size: .84rem; }
.appfooter__brand { font-weight: 600; }
.appfooter__note { color: var(--text-muted); }
.appfooter__links { display: flex; gap: 16px; font-size: .84rem; flex-wrap: wrap; }


/* ---- Onglets (journal d'audit) ------------------------------------------ */
.tabs { display: flex; gap: 4px; margin-bottom: 16px; border-bottom: 1px solid var(--border); }
.tabs__item {
    display: inline-flex; align-items: center; gap: 7px;
    padding: 9px 16px; border-radius: 10px 10px 0 0;
    font-weight: 600; font-size: .88rem; color: var(--text-muted);
    border: 1px solid transparent; border-bottom: 0; margin-bottom: -1px;
}
.tabs__item:hover { color: var(--text); background: var(--bg-sunken); }
.tabs__item.is-active {
    color: var(--text); background: var(--bg-elevated);
    border-color: var(--border); border-bottom: 1px solid var(--bg-elevated);
}
.tabs__badge {
    display: inline-flex; align-items: center; justify-content: center; min-width: 20px;
    padding: 1px 6px; border-radius: 999px; font-size: .7rem;
    background: rgba(215, 57, 47, .14); color: var(--danger);
}


.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;
}

/* =========================================================================
   Barre supérieure : fin des chevauchements
   =========================================================================

   Un élément de grille refuse par défaut de descendre sous la largeur de son
   contenu : plutôt que de se comprimer, il déborde de sa colonne et vient se
   peindre par-dessus la suivante. Le bloc de marque faisait exactement cela,
   et comme le champ de recherche est translucide, on lisait « PHOTOTHÈQUE »
   au travers. Mesuré : 126 px de recouvrement entre 1090 et 1300 px, et rien
   à 1440 px - d'où un défaut qui ne se voit que sur certaines largeurs.

   Ces règles viennent après celles qu'elles corrigent : à spécificité égale,
   la dernière l'emporte. Rien à modifier plus haut dans le fichier.
   ------------------------------------------------------------------------- */

/* 1. Chaque bloc de l'en-tête a le droit de se comprimer plutôt que de
      déborder sur son voisin. */
.topbar__inner > * { min-width: 0; }

/* 2. La marque cède de la place ; le logo, lui, garde sa taille. */
.brand { flex-shrink: 1; min-width: 0; }
.brand__logo { flex: none; }

/* 3. Le libellé se tronque proprement au lieu de glisser sous le champ. */
.brand__label {
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    min-width: 0;
}

/* 4. En dessous de 1370 px, le libellé n'a plus la place de s'afficher en
      entier : on le retire plutôt que d'afficher « PHOTOT… ». Seuil mesuré,
      non deviné : le chevauchement apparaît à 1360 px (8 px), 1350 (18) et
      1341 (27). La règle d'origine attendait 860 px, bien après. */
@media (max-width: 1370px) {
    .brand__label, .brand__sep { display: none; }
}

/* 5. La barre complète - marque, recherche, navigation, menu utilisateur -
      réclame environ 1225 px pour tenir sur une ligne. À 1200 px, la
      navigation demandait 499 px pour une colonne de 414 et débordait de
      85 px sur le menu utilisateur : « Administration » passait sous
      l'avatar. Elle bascule donc dans le menu hamburger dès 1240 px.

      Ce seuil est volontairement séparé du bloc « max-width: 1080px »
      existant, qui commande aussi le tiroir des filtres et la mise en page
      de l'administration : ceux-là n'ont aucune raison de changer ici.

      La borne basse n'est pas décorative. Ce bloc étant ajouté en fin de
      fichier, il passe après celui de « max-width: 720px » et l'emporterait
      sur lui à spécificité égale : la disposition mobile, où la recherche
      occupe sa propre ligne, serait écrasée et la page déborderait
      horizontalement. On ne couvre donc que l'intervalle laissé vacant. */
@media (min-width: 721px) and (max-width: 1240px) {
    .topbar__inner { grid-template-columns: auto 1fr auto; }
    .topnav { display: none; }
    .burger { display: inline-flex; }
    .topbar.is-open .topnav {
        display: flex; flex-direction: column; grid-column: 1 / -1; padding-top: 10px;
        border-top: 1px solid rgba(255, 255, 255, .1); margin-top: 8px;
    }
}



/* ==========================================================================
   PARTIE 2 — COMPOSANTS MODELFLOW
   Dessinés avec les jetons de la charte ci-dessus : le jaune en aplat (texte
   bleu profond dessus), le bleu Photosol pour le texte et les petits accents,
   le bleu marine pour les bandeaux. Jamais de jaune en texte sur du blanc.
   ========================================================================== */

:root {
    /* Couleurs de séries des graphiques, tirées du nuancier Photosol. */
    --serie-1: var(--ps-blue);
    --serie-2: #0094CD;
    --serie-3: var(--ps-yellow-700);
    --serie-4: #367A81;
    --serie-5: #90C685;
    --serie-6: #ED7575;
    --ok-text: #1E7A38;
    --warn-text: #9A5B00;
    --danger-text: #B42318;
}
:root[data-theme="dark"] { --ok-text: #6FD08C; --warn-text: #F5B54A; --danger-text: #FF8A80; }

.num, .tnum, td.num, th.num { font-variant-numeric: tabular-nums; text-align: right; }
small { color: var(--text-muted); }
.provenance { font-size: .74rem; color: var(--text-muted); }

/* --- Bandeau « espace de travail » --------------------------------------- */
.contextbar { background: var(--bg-elevated); border-bottom: 1px solid var(--border); }
.contextbar__inner {
    max-width: 1680px; margin: 0 auto; padding: 8px 20px;
    display: flex; align-items: center; gap: 10px 18px; flex-wrap: wrap;
}
.contextbar__label { font-size: .72rem; text-transform: uppercase; letter-spacing: .12em; color: var(--text-muted); font-weight: 700; }
.espace { display: inline-flex; padding: 3px; gap: 3px; border-radius: 999px; background: var(--bg-sunken); border: 1px solid var(--border); }
.espace__btn {
    display: inline-flex; align-items: center; gap: 8px; padding: 6px 14px; border-radius: 999px;
    font-size: .84rem; font-weight: 600; color: var(--text-muted); white-space: nowrap;
}
.espace__btn::before { content: ""; width: 8px; height: 8px; border-radius: 50%; background: var(--accent, var(--ps-blue)); }
.espace__btn:hover { color: var(--text); background: var(--bg-elevated); }
.espace__btn.is-active { background: var(--brand); color: var(--on-brand); box-shadow: var(--shadow-sm); }
.contextbar__nature { margin: 0; font-size: .82rem; color: var(--text-muted); }

/* Marque : le libellé de l'application, comme « Photothèque » sur la Médiathèque. */
.topnav__link--admin.is-active { color: var(--brand); }

/* --- En-tête de page ------------------------------------------------------ */
.page-head {
    display: flex; justify-content: space-between; align-items: flex-end; gap: 16px 24px;
    flex-wrap: wrap; margin-bottom: 18px;
}
.page-head h1 { margin: 0; }
.page-head .kicker {
    display: block; text-transform: uppercase; letter-spacing: .14em; font-size: .72rem; font-weight: 700;
    color: var(--brand-text); margin-bottom: 6px;
}
.page-head .sub { margin: 6px 0 0; max-width: 90ch; color: var(--text-muted); font-size: .92rem; }
.page-actions { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; }
h2 { margin: 30px 0 12px; }
h2:first-child { margin-top: 0; }
h3 { margin: 18px 0 8px; }

.perim-tag {
    display: inline-flex; align-items: center; gap: 8px; padding: 5px 12px; border-radius: 999px;
    font-size: .8rem; font-weight: 600; background: var(--bg-elevated); border: 1px solid var(--border);
}
.perim-tag::before { content: ""; width: 8px; height: 8px; border-radius: 50%; background: var(--accent, var(--ps-blue)); }

/* --- Bandeau de chiffres de tête (même langage que le héros de la Médiathèque) */
.hero {
    position: relative; overflow: hidden; border-radius: var(--radius-lg); margin-bottom: 22px;
    padding: 22px 24px 24px; color: #fff; background: var(--ps-navy);
    background-image: linear-gradient(105deg, rgba(8, 42, 77, .97) 0%, rgba(10, 55, 101, .92) 45%, rgba(16, 70, 124, .86) 100%);
    box-shadow: var(--shadow-md); min-height: 0;
}
.hero::after { content: ""; position: absolute; left: 24px; bottom: 0; width: 56px; height: 3px; background: var(--ps-yellow); }
.hero .kpi-label { color: var(--ps-yellow); }
.hero-num { font-size: clamp(2.4rem, 1.6rem + 3vw, 3.8rem); font-weight: 800; letter-spacing: -.03em; line-height: 1.05; font-variant-numeric: tabular-nums; }
.hero-num small { font-size: .34em; font-weight: 600; letter-spacing: 0; color: rgba(255, 255, 255, .8); margin-left: 8px; }
.hero-line { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: 12px; margin-top: 18px; }
.hero-line > div { padding: 12px 14px; border-radius: var(--radius-sm); background: rgba(255, 255, 255, .08); border: 1px solid rgba(255, 255, 255, .14); }
.hero .kpi-val { color: #fff; }
.hero .kpi-val.pos { color: #8FE3A6; } .hero .kpi-val.neg { color: #FFB4AE; }
.hero .kpi-sub { color: rgba(255, 255, 255, .72); }

/* --- Indicateurs (cartes de la Médiathèque) ------------------------------ */
.kpi-label { display: block; font-size: .74rem; text-transform: uppercase; letter-spacing: .07em; color: var(--text-muted); font-weight: 650; }
.kpi-val { display: block; font-size: 1.45rem; font-weight: 800; letter-spacing: -.02em; line-height: 1.25; font-variant-numeric: tabular-nums; color: var(--text); }
.kpi-val.pos { color: var(--ok-text); } .kpi-val.neg { color: var(--danger-text); }
.kpi-sub { display: block; font-size: .76rem; color: var(--text-muted); }
.kpi-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(170px, 1fr)); gap: 14px; margin-bottom: 22px; }
.kpi-grid > div, .live-kpis > div {
    background: var(--bg-elevated); border: 1px solid var(--border); border-radius: var(--radius);
    padding: 14px 16px; box-shadow: var(--shadow-sm); display: grid; gap: 2px; align-content: start;
}
.kpi-grid .kpi-val { font-size: 1.3rem; }

/* --- Tableaux ------------------------------------------------------------- */
.table-wrap {
    overflow-x: auto; background: var(--bg-elevated); border: 1px solid var(--border);
    border-radius: var(--radius); box-shadow: var(--shadow-sm); margin-bottom: 18px;
}
table.ps { width: 100%; border-collapse: collapse; font-size: .86rem; }
table.ps th, table.ps td { padding: 9px 12px; text-align: left; border-bottom: 1px solid var(--border); vertical-align: top; }
table.ps th {
    font-size: .72rem; text-transform: uppercase; letter-spacing: .07em; color: var(--text-muted); font-weight: 650;
    background: var(--bg-elevated); position: sticky; top: 0; z-index: 1; white-space: nowrap;
}
table.ps th.num, table.ps td.num { text-align: right; }
table.ps tbody tr:hover { background: var(--brand-soft); }
table.ps tbody tr:last-child td { border-bottom: 0; }
table.ps tr.total td { font-weight: 700; background: var(--bg-sunken); border-top: 1px solid var(--border-strong); }
table.ps tr.section td { background: var(--ps-blue-050); color: var(--ps-blue-800); font-weight: 700; }
:root[data-theme="dark"] table.ps tr.section td { background: rgba(255, 204, 0, .08); color: var(--ps-yellow); }
table.ps td.pos, .pos { color: var(--ok-text); } table.ps td.neg, .neg { color: var(--danger-text); }
table.ps td.row-label { white-space: nowrap; } table.ps td.row-sub { padding-left: 28px; color: var(--text-muted); }
table.ps th.sortable { cursor: pointer; } table.ps th.sortable:hover { color: var(--brand-text); }
table.ps th.sorted-asc::after { content: " ▲"; } table.ps th.sorted-desc::after { content: " ▼"; }
table.ps.compact th, table.ps.compact td { padding: 6px 9px; font-size: .8rem; }
.bp-table td:first-child, .bp-table th:first-child { position: sticky; left: 0; background: var(--bg-elevated); z-index: 2; min-width: 260px; }
.bp-table th:first-child { z-index: 3; }
.bp-table tr.section td:first-child { background: var(--ps-blue-050); }
:root[data-theme="dark"] .bp-table tr.section td:first-child { background: #1A2A1F; }

/* --- Badges ---------------------------------------------------------------- */
.badge { text-transform: none; letter-spacing: 0; }
.badge-green { background: rgba(47, 164, 79, .12); color: var(--ok-text); border-color: transparent; }
.badge-red { background: rgba(215, 57, 47, .10); color: var(--danger-text); border-color: transparent; }
.badge-yellow { background: var(--brand-soft); color: var(--warn-text); border-color: var(--ps-yellow-600); }
.badge-blue { background: var(--ps-blue-050); color: var(--ps-blue); border-color: transparent; }
.badge-teal { background: rgba(54, 122, 129, .12); color: #2B6168; border-color: transparent; }
.badge-grey { }
.statut-ferme { color: var(--ok-text); } .statut-estime { color: var(--warn-text); } .statut-inconnu { color: var(--danger-text); }
.pill {
    display: inline-flex; align-items: center; gap: 8px; padding: 5px 12px; border-radius: 999px;
    background: var(--bg-elevated); border: 1px solid var(--border); font-size: .82rem; color: var(--text-muted);
}
.pill strong { color: var(--text); }

/* --- Boutons : correspondance avec ceux de la Médiathèque ----------------- */
.btn:not([class*="btn--"]):not([class*="btn-"]), .btn.btn-sm:not(.btn-ghost):not(.btn-secondary):not(.btn-danger):not([class*="btn--"]),
.btn.btn-block:not(.btn-ghost):not(.btn-secondary):not(.btn-danger):not([class*="btn--"]) { background: var(--brand); color: var(--on-brand); }
.btn:not([class*="btn--"]):not([class*="btn-"]):hover, .btn.btn-sm:not(.btn-ghost):not(.btn-secondary):not(.btn-danger):not([class*="btn--"]):hover { background: var(--brand-hover); color: var(--on-brand); }
.btn { text-decoration: none; }
.btn:disabled, .btn[disabled] { opacity: .5; cursor: not-allowed; }
.btn-secondary, .btn-ghost { background: var(--bg-elevated); border-color: var(--border-strong); color: var(--text); }
.btn-secondary:hover, .btn-ghost:hover { border-color: var(--ps-yellow-700); color: var(--text); background: var(--brand-soft); }
.btn-danger { background: var(--danger); color: #fff; } .btn-danger:hover { background: #B92E25; color: #fff; }
.btn-sm { padding: 6px 12px; font-size: .8rem; }
.btn-block { width: 100%; }
.btn-ms { background: #fff; color: #1B1B1B; border-color: #D0D5DB; } .btn-ms:hover { background: #F3F4F6; color: #1B1B1B; }
.form-actions { display: flex; gap: 8px; margin-top: 16px; align-items: center; flex-wrap: wrap; }

/* --- Formulaires ----------------------------------------------------------- */
.form-grid { grid-template-columns: repeat(auto-fill, minmax(230px, 1fr)); gap: 12px 18px; }
.field > label { font-size: .8rem; font-weight: 600; color: var(--text-muted); display: flex; justify-content: space-between; gap: 8px; }
.field .unit { font-weight: 400; color: var(--text-muted); font-size: .74rem; }
input[type="file"] { font-family: inherit; font-size: .86rem; }
input.changed, .changed input { border-color: var(--ps-yellow-700); background: var(--brand-soft); }
input.invalid { border-color: var(--danger); }
fieldset {
    background: var(--bg-elevated); border: 1px solid var(--border); border-radius: var(--radius);
    padding: 18px 20px 20px; margin: 0 0 18px; box-shadow: var(--shadow-sm); min-width: 0;
}
fieldset legend { font-weight: 700; font-size: .95rem; padding: 0 6px; }
.checks { display: flex; gap: 16px; flex-wrap: wrap; } .checks label { display: inline-flex; gap: 8px; align-items: center; font-size: .86rem; }
details.section {
    background: var(--bg-elevated); border: 1px solid var(--border); border-radius: var(--radius-sm);
    padding: 10px 14px; margin-bottom: 8px;
}
details.section > summary { cursor: pointer; font-weight: 650; font-size: .9rem; list-style: none; display: flex; justify-content: space-between; align-items: center; }
details.section > summary::-webkit-details-marker { display: none; }
details.section > summary::after { content: "+"; color: var(--text-muted); font-weight: 400; }
details.section[open] > summary::after { content: "−"; }
details.section[open] > summary { margin-bottom: 10px; }

/* --- Filtres (en ligne, au-dessus des listes) ------------------------------ */
.filters { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 12px; padding: 14px 16px; margin-bottom: 18px; }
.filters .field { min-width: 150px; } .filters .field.wide { min-width: 260px; }
.chips { display: flex; gap: 6px; flex-wrap: wrap; }
.chip {
    display: inline-flex; align-items: center; padding: 4px 12px; border-radius: 999px; font-size: .8rem;
    border: 1px solid var(--border-strong); background: var(--bg-elevated); color: var(--text); cursor: pointer;
}
.chip:hover { border-color: var(--ps-yellow-700); background: var(--brand-soft); color: var(--text); }
.chip.active { background: var(--brand); border-color: var(--brand); color: var(--on-brand); font-weight: 650; }

/* --- Messages et encarts --------------------------------------------------- */
.flash { color: var(--text); }
.flash-success { border-left-color: var(--ok); } .flash-error { border-left-color: var(--danger); }
.flash-warning { border-left-color: var(--warn); } .flash-info { border-left-color: var(--ps-navy-600); }
.flash-stack--inline .flash, .login-flash .flash { box-shadow: none; border: 1px solid var(--border); border-left-width: 4px; }
.note { background: var(--brand-soft); border: 1px solid var(--brand); border-radius: var(--radius-sm); padding: 10px 14px; margin: 12px 0; font-size: .88rem; max-width: 100ch; }
.note-warn { background: rgba(224, 138, 11, .10); border-color: var(--warn); }
.empty { padding: 40px; text-align: center; color: var(--text-muted); border: 2px dashed var(--border-strong); border-radius: var(--radius); background: var(--bg-sunken); }
.journal {
    background: var(--ps-navy); color: #DCE8F2; padding: 14px 16px; border-radius: var(--radius-sm);
    max-height: 340px; overflow: auto; font: .78rem/1.5 ui-monospace, Menlo, Consolas, monospace; white-space: pre-wrap;
}

/* --- Mises en page ------------------------------------------------------------ */
.cols { display: grid; gap: 22px; } .cols-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); } .cols-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.cols-sim { grid-template-columns: 380px minmax(0, 1fr); align-items: start; }
.sticky { position: sticky; top: 76px; }
.simul-panel {
    background: var(--bg-elevated); border: 1px solid var(--border); border-radius: var(--radius);
    padding: 18px; box-shadow: var(--shadow-sm); max-height: calc(100vh - 96px); overflow-y: auto;
}
.simul-panel h3 { margin-top: 0; }
.simul-panel .field { margin-bottom: 8px; }
.simul-panel .usine { color: var(--text-muted); font-weight: 400; font-size: .72rem; }
.live-kpis { display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); gap: 12px; margin-bottom: 18px; }
.live-kpis .kpi-val { font-size: 1.3rem; }
.delta { display: block; font-size: .76rem; font-weight: 700; min-height: 1em; font-variant-numeric: tabular-nums; }
.delta.pos { color: var(--ok-text); } .delta.neg { color: var(--danger-text); } .delta.zero { color: var(--text-muted); }

/* Onglets : boutons de la fiche projet, au dessin des onglets de la Médiathèque. */
.tabs button {
    display: inline-flex; align-items: center; gap: 7px; padding: 9px 16px; border-radius: 10px 10px 0 0;
    font: 600 .88rem/1.3 inherit; font-family: inherit; color: var(--text-muted); background: none; cursor: pointer;
    border: 1px solid transparent; border-bottom: 0; margin-bottom: -1px;
}
.tabs button:hover { color: var(--text); background: var(--bg-sunken); }
.tabs button.active { color: var(--text); background: var(--bg-elevated); border-color: var(--border); border-bottom: 1px solid var(--bg-elevated); box-shadow: inset 0 3px 0 var(--brand); }
.tabs { flex-wrap: wrap; margin-top: 18px; }
.tab-panel { display: none; } .tab-panel.active { display: block; }

/* --- Graphiques ---------------------------------------------------------------- */
.chart {
    background: var(--bg-elevated); border: 1px solid var(--border); border-radius: var(--radius);
    padding: 12px; box-shadow: var(--shadow-sm);
}
.chart svg { width: 100%; height: auto; display: block; min-height: 180px; }
.chart svg text { fill: var(--text-muted); }
.chart svg line { stroke: var(--border); }
.chart-title { font-size: .74rem; text-transform: uppercase; letter-spacing: .07em; color: var(--text-muted); font-weight: 650; margin: 2px 0 8px 2px; }
.legend { display: flex; gap: 14px; flex-wrap: wrap; font-size: .78rem; color: var(--text-muted); margin: 8px 2px 0; }
.legend i { display: inline-block; width: 10px; height: 10px; border-radius: 3px; margin-right: 5px; vertical-align: middle; }
.bar-h { display: flex; align-items: center; gap: 10px; font-size: .84rem; padding: 3px 0; }
.bar-h .track { flex: 1; height: 10px; background: var(--bg-sunken); border-radius: 999px; overflow: hidden; }
.bar-h .fill { height: 100%; background: var(--brand); border-right: 1px solid var(--ps-yellow-700); }
.stack { display: flex; height: 14px; border-radius: 999px; overflow: hidden; background: var(--bg-sunken); }
.stack span { display: block; height: 100%; }

/* --- Cartes de l'administration ------------------------------------------------- */
.card-list { display: grid; grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); gap: 14px; }
.card-list > a {
    display: block; padding: 16px 18px; background: var(--bg-elevated); border: 1px solid var(--border);
    border-radius: var(--radius); box-shadow: var(--shadow-sm); color: var(--text-muted); font-size: .86rem;
    transition: border-color .15s, transform .15s;
}
.card-list > a:hover { border-color: var(--ps-yellow-700); transform: translateY(-2px); color: var(--text-muted); }
.card-list strong { display: block; color: var(--text); font-size: .95rem; margin-bottom: 4px; }
.perm-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); gap: 6px 24px; }
.perm-grid label { display: flex; gap: 8px; align-items: flex-start; font-size: .86rem; padding: 3px 0; }
.perm-groupe { grid-column: 1 / -1; font-weight: 700; margin: 14px 0 4px; padding-top: 10px; border-top: 1px solid var(--border); }
.admin-sidebar__group { margin: 16px 10px 8px; }
.admin-sidebar__group:first-child { margin-top: 0; }

/* --- Pages d'erreur dans l'application ----------------------------------------- */
.errorpage { padding: 70px 20px; }

/* --- Impression / PDF du navigateur ---------------------------------------------- */
.print-footer, .print-only { display: none; }
@media print {
    .topbar, .contextbar, .appfooter, .admin-sidebar, .page-actions, .filters, .simul-panel, .tabs, .no-print, .flash-stack { display: none !important; }
    body { background: #fff; color: #000; font-size: 10.5pt; }
    .page, .admin-content { padding: 0; max-width: none; }
    .admin-shell { display: block; background: none; }
    .table-wrap, .kpi-grid > div, .chart, fieldset { box-shadow: none; }
    table.ps th { position: static; }
    .cols-sim { grid-template-columns: 1fr; }
    .tab-panel { display: block !important; break-inside: avoid; }
    .hero { color: #000; background: #fff; border: 1px solid #ccc; box-shadow: none; }
    .hero .kpi-val, .hero-num { color: #000; } .hero .kpi-label { color: var(--ps-blue); }
    .print-footer, .print-only { display: block; }
}

/* --- Responsive ---------------------------------------------------------------- */
@media (max-width: 1240px) {
    .topbar__inner { grid-template-columns: auto 1fr auto; }
}
@media (max-width: 1080px) {
    .topnav { display: none; }
    .burger { display: inline-flex; }
    .topbar.is-open .topnav {
        display: flex; flex-direction: column; grid-column: 1 / -1; padding-top: 10px;
        border-top: 1px solid rgba(255, 255, 255, .1); margin-top: 8px;
    }
    .cols-2, .cols-3, .cols-sim { grid-template-columns: 1fr; }
    .sticky, .simul-panel { position: static; max-height: none; }
    .admin-shell { grid-template-columns: 1fr; background: none; }
    .admin-sidebar { position: static; height: auto; border-right: 0; border-bottom: 1px solid var(--border); }
    .admin-sidebar nav { grid-auto-flow: column; grid-auto-columns: max-content; overflow-x: auto; }
    .admin-sidebar__group { display: none; }
    .loginpage { grid-template-columns: 1fr; }
    .loginpage__visual { display: none; }
}
@media (max-width: 860px) { .brand__label, .brand__sep { display: none; } .contextbar__nature { display: none; } }
@media (max-width: 720px) {
    .topbar__inner { grid-template-columns: 1fr auto; }
    .flash-stack { top: auto; bottom: 14px; left: 14px; right: 14px; max-width: none; }
    .usermenu__name { display: none; }
    .page { padding-left: 14px; padding-right: 14px; }
    .appfooter__inner { flex-direction: column; align-items: flex-start; }
    .hero-num { font-size: 2.4rem; }
}
@media (prefers-reduced-motion: reduce) {
    *, *::before, *::after { animation-duration: .01ms !important; transition-duration: .01ms !important; }
    html { scroll-behavior: auto; }
}

/* --- Compléments de gabarit ---------------------------------------------------- */
.usermenu__panel form { margin: 0; }
.usermenu__panel form button {
    width: 100%; text-align: left; padding: 9px 12px; border-radius: 8px; font: inherit; font-size: .9rem;
    background: none; border: 0; cursor: pointer;
}
.usermenu__panel form button:hover { background: var(--bg-sunken); }
.admin-sidebar nav + .admin-sidebar__title { margin-top: 22px; }
.admin.app .contextbar { position: relative; z-index: 2; }
.admin-shell .admin-sidebar { top: 57px; }
.installpage__box .field > label { color: #8FA5B8; }
.installpage__box .install-section-title { font-size: 1rem; text-transform: uppercase; letter-spacing: .07em; color: #8FA5B8; }
.installpage__box .muted { color: #8FA5B8; }
@media (max-width: 1080px) {
    .topbar .brand { grid-row: 1; grid-column: 1; }
    .topbar__actions { grid-row: 1; grid-column: -2 / -1; }
    .topbar.is-open .topnav { grid-row: 2; }
}

/* ==========================================================================
   RYTHME VERTICAL : un seul jeu d'espacements pour toutes les pages.
   Titre de section → 12 px → contenu ; section → 36 px → section suivante.
   Dans une grille à colonnes, les titres partent tous de la même ligne.
   ========================================================================== */
:root { --space-section: 36px; --space-title: 12px; --space-block: 18px; }

.page > h2, .admin-content > h2, .page > .cols, .admin-content > .cols { margin-top: var(--space-section); }
h2 { margin: var(--space-section) 0 var(--space-title); line-height: 1.25; }
h2 + .sub, h2 + p.muted { margin: calc(-1 * var(--space-title) + 4px) 0 var(--space-title); }
.page-head + h2, .filters + h2, .hero + h2, .kpi-grid + h2, .page-head + .cols, .filters + .cols, .hero + .cols, .kpi-grid + .cols { margin-top: 8px; }

.cols { margin-bottom: 0; align-items: start; }
.cols > * { min-width: 0; }
.cols > * > h2:first-child, .cols > * > h3:first-child, .cols > * > .chart-title:first-child { margin-top: 0; }
.cols > * > .table-wrap:last-child, .cols > * > .chart:last-child { margin-bottom: 0; }

.table-wrap { margin: 0 0 var(--space-block); }
.table-wrap + .table-note, .table-wrap + .stack + .table-note { margin-top: -6px; }
.table-note { font-size: .82rem; color: var(--text-muted); margin: 8px 0 0; line-height: 1.5; }
.stack--legend { margin: -6px 0 8px; }
.block { margin-top: var(--space-block); }
.chart-title--spaced { margin-top: var(--space-block); }
.hero, .kpi-grid, .filters, .live-kpis { margin-bottom: var(--space-block); }
.hero + .cols, .kpi-grid + .cols { margin-top: var(--space-section); }

/* Tableau sans ligne (périmètre vide) : un message plutôt qu'une en-tête seule. */
table.ps td.empty-row { text-align: center; color: var(--text-muted); padding: 18px 12px; font-style: italic; }

/* ==========================================================================
   RESPONSIVE : vérifié à 1440, 1024, 768 et 390 px de large.
   ========================================================================== */
html, body { max-width: 100%; overflow-x: hidden; }
img, svg, canvas { max-width: 100%; }
.page-head > div:first-child { min-width: 0; flex: 1 1 420px; }
.page-head h1 { overflow-wrap: anywhere; }
@media (max-width: 1400px) { .cols-3 { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 1080px) {
    :root { --space-section: 28px; }
    .page { padding: 16px 16px 48px; }
    .admin-content { padding: 18px 16px 48px; }
    .page-actions { width: 100%; }
    .filters { align-items: stretch; }
    .filters .field, .filters .field.wide { min-width: 0; flex: 1 1 160px; }
    .filters .btn { align-self: flex-end; }
    .contextbar__inner { padding: 8px 16px; }
}
@media (max-width: 720px) {
    :root { --space-section: 24px; }
    .cols-3 { grid-template-columns: 1fr; }
    h1 { font-size: 1.45rem; }
    h2 { font-size: 1.1rem; }
    .page-actions .btn { flex: 1 1 auto; justify-content: center; }
    .kpi-grid, .live-kpis { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; }
    .kpi-grid .kpi-val, .live-kpis .kpi-val { font-size: 1.1rem; }
    .hero { padding: 18px 16px 20px; }
    .hero-line { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px; }
    .hero-line > div { padding: 10px; }
    .hero .kpi-val { font-size: 1.15rem; }
    table.ps { font-size: .8rem; }
    table.ps th, table.ps td { padding: 7px 9px; }
    .bp-table td:first-child, .bp-table th:first-child { min-width: 150px; max-width: 170px; white-space: normal; }
    .bar-h span[style*="min-width"] { min-width: 0 !important; flex: 0 1 auto; }
    .tabs { overflow-x: auto; flex-wrap: nowrap; scrollbar-width: thin; }
    .tabs button { white-space: nowrap; }
    .espace { width: 100%; }
    .espace__btn { flex: 1 1 0; justify-content: center; padding: 6px 10px; }
    .contextbar__label { display: none; }
    .admin-content { padding: 16px 14px 40px; }
    .card-list, .perm-grid { grid-template-columns: 1fr; }
    .simul-panel { padding: 14px; }
    .legend { gap: 8px 12px; }
    fieldset { padding: 14px; }
    .form-grid { grid-template-columns: 1fr; }
}
@media (max-width: 420px) {
    .kpi-grid, .live-kpis, .hero-line { grid-template-columns: 1fr; }
    .brand__logo { width: 150px; height: auto; }
}
@media (max-width: 720px) {
    table.ps td, table.ps th { white-space: nowrap; }
    table.ps td.wrap, table.ps td .journal { white-space: normal; }
    .table-wrap { -webkit-overflow-scrolling: touch; }
    .filters .btn { flex: 1 1 100%; }
}
.panel-form { display: grid; gap: 10px; max-width: 460px; }
.panel-form .form-actions { margin-top: 4px; }
code.totp-key { font-size: 1.05rem; letter-spacing: .08em; padding: 4px 8px; border-radius: 6px; background: var(--bg-sunken); }

/* --- Fenêtre (partage par e-mail) ---------------------------------------------- */
.dialog {
    width: min(560px, calc(100vw - 32px)); max-height: calc(100vh - 32px); padding: 0; border: 1px solid var(--border);
    border-radius: var(--radius-lg); background: var(--bg-elevated); color: var(--text); box-shadow: var(--shadow-lg);
}
.dialog::backdrop { background: rgba(8, 42, 77, .55); }
.dialog__body { display: grid; gap: 14px; padding: 20px 22px 18px; }
.dialog__head { display: flex; justify-content: space-between; align-items: center; gap: 12px; border-bottom: 2px solid var(--brand); padding-bottom: 10px; }
.dialog__head h2 { margin: 0; font-size: 1.15rem; }
.dialog__foot { display: flex; justify-content: flex-end; gap: 8px; flex-wrap: wrap; padding-top: 4px; }
.dialog textarea { width: 100%; resize: vertical; font: inherit; }
.icon-btn--plain { background: none; border: 0; color: var(--text-muted); font-size: 1.5rem; line-height: 1; cursor: pointer; }
.form-grid--2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
@media (max-width: 520px) { .form-grid--2 { grid-template-columns: 1fr; } .dialog__body { padding: 16px; } }

/* --- Fenêtre d'attente (imports, publication, recalculs) ------------------------- */
.loader-overlay {
    position: fixed; inset: 0; z-index: 200; display: grid; place-items: center; padding: 20px;
    background: rgba(8, 42, 77, .62); backdrop-filter: blur(2px);
}
.loader-overlay[hidden] { display: none; }
.loader-box {
    width: min(440px, 100%); text-align: center; padding: 28px 26px 22px; border-radius: var(--radius-lg);
    background: var(--bg-elevated); color: var(--text); box-shadow: var(--shadow-lg); border-top: 4px solid var(--brand);
}
.loader-spin {
    display: inline-block; width: 46px; height: 46px; border-radius: 50%;
    border: 4px solid var(--ps-blue-050); border-top-color: var(--ps-blue); border-right-color: var(--brand);
    animation: mf-tourne .9s linear infinite;
}
:root[data-theme="dark"] .loader-spin { border-color: rgba(255, 255, 255, .12); border-top-color: var(--ps-yellow); border-right-color: #6FA8E0; }
.loader-title { margin: 14px 0 4px; font-weight: 750; font-size: 1.05rem; }
.loader-detail { margin: 0; color: var(--text-muted); font-size: .88rem; line-height: 1.5; }
.loader-time { margin: 10px 0 0; font-variant-numeric: tabular-nums; color: var(--brand-text); font-weight: 650; min-height: 1.2em; }
.loader-bar { position: relative; height: 4px; margin-top: 14px; border-radius: 999px; overflow: hidden; background: var(--bg-sunken); }
.loader-bar span { position: absolute; inset: 0 auto 0 -40%; width: 40%; background: var(--brand); border-radius: 999px; animation: mf-glisse 1.4s ease-in-out infinite; }
@keyframes mf-tourne { to { transform: rotate(360deg); } }
@keyframes mf-glisse { to { left: 100%; } }
body.is-loading { cursor: progress; }
.loader-avert {
    margin: 12px 0 0; padding: 8px 10px; border-radius: var(--radius-sm, 6px); font-size: .84rem; font-weight: 650;
    background: var(--ps-yellow-050, #FFF6D6); color: #6B4E00; border: 1px solid rgba(214, 160, 0, .35);
}
.loader-avert:empty, .loader-note:empty { display: none; }
:root[data-theme="dark"] .loader-avert { background: rgba(255, 200, 0, .12); color: #FFD966; border-color: rgba(255, 200, 0, .3); }
.loader-note { margin: 10px 0 0; font-size: .84rem; color: var(--text-muted); line-height: 1.45; }
.loader-actions { margin-top: 14px; }
.loader-overlay.is-erreur .loader-spin, .loader-overlay.is-erreur .loader-bar { display: none; }
.loader-overlay.is-erreur .loader-box { border-top-color: var(--danger, #C62828); }

/* Pages lentes : fine barre en haut de l'écran, et un mot au-delà de 3 secondes. */
.nav-progress { position: fixed; top: 0; left: 0; right: 0; z-index: 190; pointer-events: none; }
.nav-progress[hidden] { display: none; }
.nav-progress span { display: block; height: 3px; width: 100%; background: linear-gradient(90deg, transparent, var(--brand), var(--ps-yellow, #FFC800), transparent); background-size: 50% 100%; background-repeat: no-repeat; animation: mf-avance 1.1s linear infinite; }
.nav-progress p { display: none; position: fixed; top: 10px; left: 50%; transform: translateX(-50%); margin: 0; padding: 6px 14px; border-radius: 999px; background: var(--bg-elevated); color: var(--text); box-shadow: var(--shadow-lg); font-size: .84rem; font-weight: 600; }
.nav-progress.lent p { display: block; }
@keyframes mf-avance { from { background-position: -50% 0; } to { background-position: 150% 0; } }
@media (prefers-reduced-motion: reduce) { .loader-spin, .loader-bar span, .nav-progress span { animation-duration: 3s !important; animation-iteration-count: infinite !important; } }

/* Bandeau « lecture seule » de la page des imports. */
.callout--lecture { border-left: 4px solid var(--ps-blue); background: var(--ps-blue-050); color: var(--text); margin-bottom: 18px; }
:root[data-theme="dark"] .callout--lecture { background: rgba(0, 79, 159, .18); }

/* ───── Registres de décisions ───── */
.panel-form--large { max-width: none; }
.inline-form { display: flex; gap: 6px; align-items: center; flex-wrap: wrap; min-width: 220px; }
.inline-form input[type=text] { flex: 1 1 140px; min-width: 120px; padding: 4px 8px; font-size: .82rem; }
.field[hidden], [data-si][hidden] { display: none !important; }
.reprise-etat { display: inline-block; min-width: 9ch; }
.retrait > summary { list-style: none; cursor: pointer; white-space: nowrap; }
.retrait > summary::-webkit-details-marker { display: none; }
.retrait[open] > summary { margin-bottom: 6px; }
td.col-motif { min-width: 280px; }
td.col-decision { min-width: 140px; max-width: 240px; white-space: normal; }
.reprise-etat, td > .badge { white-space: nowrap; }
table.ps td.num { white-space: nowrap; }
