/* =====================================================================
   Orbio-DOT-Web — Design system
   Identité propre au Department of Tax : bleu marine institutionnel + or,
   volontairement distincte du violet/or habituel de l'écosystème Orbio.
   CSS pur, pas de framework, un seul fichier (comme les autres sites Orbio).
   ===================================================================== */

:root {
    color-scheme: dark;

    /* Fond */
    --bg: #0a0e1a;
    --bg-2: #0d1220;
    --panel: #111827;
    --panel-2: #161d2e;
    --border: #22304a;
    --border-soft: #1a2338;

    /* Texte */
    --text: #eef1f6;
    --muted: #93a0b8;
    --faint: #64708a;

    /* Or institutionnel — désaturé, pas le violet Orbio classique */
    --gold: #c9a227;
    --gold-2: #e6c565;
    --gold-ink: #201803;

    /* Sémantique */
    --ok: #3fce8f;
    --warn: #e0a72e;
    --danger: #d9534f;
    --danger-2: #f27a76;

    /* Forme */
    --radius: 10px;
    --radius-sm: 6px;
    --shadow: 0 10px 30px -12px rgba(0, 0, 0, .6);
    --grad-navy: linear-gradient(135deg, #13203a, #0a0e1a);
    --grad-gold: linear-gradient(135deg, var(--gold), var(--gold-2));
    --maxw: 1120px;

    /* Typo */
    --font-serif: Georgia, "Times New Roman", "Cambria", serif;
    --font-sans: "Segoe UI", system-ui, -apple-system, Roboto, Helvetica, Arial, sans-serif;
}

/* --------------------------------------------------------------- reset */
*, *::before, *::after { box-sizing: border-box; }
html, body { margin: 0; padding: 0; }
body {
    background: var(--bg);
    color: var(--text);
    font-family: var(--font-sans);
    line-height: 1.55;
    -webkit-font-smoothing: antialiased;
    /* Ancre le footer en bas du viewport sur les pages courtes (ex. galerie/organigramme/articles
       vides) au lieu de laisser un grand vide sous lui — sans wrapper supplémentaire à ajouter
       dans chaque template. */
    min-height: 100vh;
    display: flex;
    flex-direction: column;
}
body > footer { margin-top: auto; }
h1, h2, h3, h4, .brand, .kicker-serif {
    font-family: var(--font-serif);
    font-weight: 700;
    letter-spacing: .01em;
    margin: 0 0 .5em;
}
p { margin: 0 0 1em; }
a { color: inherit; text-decoration: none; }
img { max-width: 100%; display: block; }
button { font: inherit; }
::selection { background: var(--gold); color: var(--gold-ink); }

@media (prefers-reduced-motion: reduce) {
    * { animation-duration: .001ms !important; transition-duration: .001ms !important; }
}

/* ------------------------------------------------------------- layout */
.container {
    max-width: var(--maxw);
    margin: 0 auto;
    padding: 0 24px;
}
.section { padding: 64px 0; }
.section-tight { padding: 32px 0; }

/* Révélation au scroll (générique, JS dans app.js) : masqué avant intersection avec le
   viewport, dévoilé une seule fois avec un fondu + léger glissement. Neutralisé si
   IntersectionObserver est absent ou en mouvement réduit (app.js ajoute alors .in-view
   immédiatement), donc jamais de contenu bloqué invisible. */
.reveal { opacity: 0; transform: translateY(28px); transition: opacity .7s ease, transform .7s ease; }
.reveal.in-view { opacity: 1; transform: translateY(0); }

.kicker {
    display: inline-block;
    text-transform: uppercase;
    letter-spacing: .14em;
    font-size: 12px;
    font-weight: 700;
    color: var(--gold-2);
    border-bottom: 2px solid var(--gold);
    padding-bottom: 6px;
    margin-bottom: 18px;
}
/* Variante page d'accueil : le trait doré se "dessine" de gauche à droite dès que le kicker
   entre dans le champ + son .reveal parent devient visible (au lieu d'un simple ::after
   statique, pour ne rien changer au .kicker de base utilisé partout ailleurs sur le site). */
.kicker-draw { position: relative; border-bottom-color: transparent; }
.kicker-draw::after {
    content: ""; position: absolute; left: 0; bottom: -2px; height: 2px; width: 100%;
    background: var(--gold); transform: scaleX(0); transform-origin: left;
    transition: transform .6s ease .15s;
}
.reveal.in-view .kicker-draw::after { transform: scaleX(1); }

.grid { display: grid; gap: 20px; }
.grid-3 { grid-template-columns: repeat(3, 1fr); }
.grid-2 { grid-template-columns: repeat(2, 1fr); }
@media (max-width: 900px) {
    .grid-3, .grid-2 { grid-template-columns: 1fr; }
}

/* Même piège que .stat-tile plus bas : les pistes 1fr de .grid-2/.grid-3 ont un minimum implicite
   basé sur le min-content de leurs enfants (ex. panels MDT/Documents en vue d'ensemble) — sans
   min-width: 0, ces pistes refusent de rétrécir et débordent horizontalement au lieu de se
   partager proportionnellement l'espace disponible. */
.grid-2 > *, .grid-3 > * { min-width: 0; }

/* Bandeau du mode aperçu (façon Discord "View As Role") — sticky top:0 au-dessus de .topbar
   (elle-même sticky), pour que le bouton "Quitter l'aperçu" reste TOUJOURS visible même en
   scrollant, comme explicitement demandé. Hauteur figée à --preview-banner-h (une seule ligne,
   texte tronqué sinon) : sans cette contrainte, deux éléments sticky top:0 consécutifs se
   chevauchent au lieu de s'empiler proprement. .topbar (et tout ce qui suppose la topbar collée
   à 0, ex. la sidebar hors-canevas mobile) est donc décalé de cette même hauteur via le
   combinateur de frère général (~), qui ne s'applique QUE quand .preview-banner précède
   effectivement dans le DOM (mode aperçu inactif = aucun effet, sélecteur jamais qualifié). */
:root { --preview-banner-h: 44px; }
.preview-banner {
    position: sticky; top: 0; z-index: 41;
    display: flex; align-items: center; gap: 10px; height: var(--preview-banner-h);
    padding: 0 24px; background: var(--warn); color: #241a02; font-weight: 600; font-size: 14px;
    overflow: hidden;
}
.preview-banner .ic { width: 18px; height: 18px; flex: none; }
.preview-banner span:nth-child(2) { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.preview-banner form { margin-left: auto; flex: none; }
.preview-banner ~ .topbar { top: var(--preview-banner-h); }
.preview-banner ~ .dash-layout { min-height: calc(100vh - 63px - var(--preview-banner-h)); }

/* ------------------------------------------------------------------ nav */
.topbar {
    position: sticky;
    top: 0;
    z-index: 40;
    background: var(--bg);
    border-bottom: 1px solid var(--border-soft);
}
.nav {
    max-width: var(--maxw);
    margin: 0 auto;
    padding: 16px 24px;
    display: flex;
    align-items: center;
    gap: 28px;
}
.brand { display: flex; align-items: center; gap: 12px; font-size: 20px; color: var(--text); }
.brand-mark {
    width: 42px; height: 42px;
    border-radius: 50%;
    object-fit: contain;
    flex: none;
}
.brand small { display: block; font-family: var(--font-sans); font-weight: 400; font-size: 10px; color: var(--muted); letter-spacing: .12em; }

.nav-links { display: flex; gap: 26px; margin-left: 12px; flex: 1; }
.nav-links a {
    font-size: 13px;
    font-weight: 600;
    letter-spacing: .03em;
    text-transform: uppercase;
    color: var(--muted);
    padding: 6px 2px;
    border-bottom: 2px solid transparent;
}
.nav-links a:hover, .nav-links a.active { color: var(--text); border-color: var(--gold); }

.nav-user { display: flex; align-items: center; gap: 10px; }
.nav-avatar { width: 28px; height: 28px; border-radius: 50%; border: 1px solid var(--border); }

/* Empilement des avatars des autres membres présents sur exactement cette page (fragment navbar,
   alimenté par GlobalModelAttributes.presentsIci — disponible sur toutes les pages). L'icône
   .page-presence-hint reste visible en permanence (pas seulement au survol) : sans elle, un
   nouveau membre voit apparaître des avatars inconnus sans comprendre pourquoi. Survol (icône ou
   avatar) : tooltip CSS pur via attr(data-tooltip), pas de JS nécessaire ; survol d'un avatar en
   plus : léger zoom. */
.page-presence { display: flex; align-items: center; gap: 8px; }
.page-presence-hint {
    position: relative; display: flex; align-items: center; justify-content: center;
    width: 22px; height: 22px; border-radius: 50%; flex: none;
    background: var(--panel-2); border: 1px solid var(--border-soft); color: var(--muted); cursor: help;
}
.page-presence-hint .ic { width: 13px; height: 13px; }
.page-presence-avatars { display: flex; align-items: center; }
.page-presence-avatar {
    position: relative; margin-left: -10px; padding: 0; border: none; background: none; cursor: pointer;
    width: 28px; height: 28px; border-radius: 50%; flex: none;
}
.page-presence-avatar:first-child { margin-left: 0; }
.page-presence-avatar img {
    width: 100%; height: 100%; border-radius: 50%; display: block; object-fit: cover;
    border: 2px solid var(--bg); transition: transform .15s ease;
}
.page-presence-avatar:hover, .page-presence-avatar:focus-visible { z-index: 5; }
.page-presence-avatar:hover img, .page-presence-avatar:focus-visible img { transform: scale(1.35); }
.page-presence [data-tooltip]::after {
    content: attr(data-tooltip);
    position: absolute; top: calc(100% + 8px); left: 50%; transform: translateX(-50%);
    background: var(--panel-2); border: 1px solid var(--border-soft); border-radius: var(--radius-sm);
    padding: 6px 10px; font-size: 12px; color: var(--text); white-space: nowrap;
    opacity: 0; pointer-events: none; transition: opacity .15s ease; box-shadow: var(--shadow); z-index: 20;
}
.page-presence [data-tooltip]:hover::after, .page-presence [data-tooltip]:focus-visible::after { opacity: 1; }

.nav-toggle {
    display: none;
    flex-direction: column; justify-content: center; gap: 5px;
    width: 34px; height: 34px; padding: 0;
    background: none; border: none; cursor: pointer; flex: none;
}
.nav-toggle span { display: block; width: 100%; height: 2px; background: var(--text); border-radius: 2px; }
@media (max-width: 900px) {
    .nav { flex-wrap: wrap; row-gap: 12px; }
    .nav-toggle { display: flex; margin-left: auto; order: 2; }
    .nav-user { order: 3; }
    .nav-links {
        display: none; order: 4; flex-basis: 100%;
        flex-direction: column; gap: 2px; margin-left: 0;
    }
    .nav-links.open { display: flex; }
    .nav-links a { padding: 10px; border-bottom: none; border-radius: var(--radius-sm); }
    .nav-links a:hover, .nav-links a.active { background: var(--panel-2); }
}

/* dropdown générique (<details class="dropdown">) */
details.dropdown { position: relative; }
details.dropdown summary {
    list-style: none;
    display: flex; align-items: center; gap: 9px;
    padding: 6px 10px 6px 6px;
    border-radius: 999px;
    border: 1px solid var(--border-soft);
    cursor: pointer;
}
details.dropdown summary:hover { border-color: var(--border); background: var(--panel); }
details.dropdown summary::-webkit-details-marker { display: none; }
details.dropdown[open] summary { border-color: var(--gold); }
details.dropdown .caret { font-size: 10px; color: var(--muted); transition: transform .2s ease; }
details.dropdown[open] .caret { transform: rotate(180deg); }

details.dropdown .dd-menu {
    position: absolute;
    top: calc(100% + 10px);
    right: 0;
    min-width: 230px;
    background: var(--panel);
    border: 1px solid var(--border-soft);
    border-radius: var(--radius);
    box-shadow: var(--shadow);
    padding: 8px;
    display: flex;
    flex-direction: column;
    z-index: 50;
}
/* <details> n'anime pas nativement son ouverture — rejouée à chaque affichage puisque le
   contenu est retiré du rendu à la fermeture (comportement natif de <details>). */
details.dropdown[open] .dd-menu { animation: dd-menu-in .16s ease; }
@keyframes dd-menu-in {
    from { opacity: 0; transform: translateY(-6px); }
    to { opacity: 1; transform: translateY(0); }
}
.dd-user {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 10px 10px 12px;
    margin-bottom: 6px;
    border-bottom: 1px solid var(--border-soft);
}
.dd-user img { width: 34px; height: 34px; border-radius: 50%; border: 1px solid var(--border); flex: none; }
.dd-user span { font-size: 14px; font-weight: 600; }
details.dropdown .dd-menu a,
details.dropdown .dd-menu button {
    display: flex;
    align-items: center;
    gap: 10px;
    width: 100%;
    padding: 9px 10px;
    border-radius: var(--radius-sm);
    font-size: 14px;
    font-weight: 500;
    color: var(--muted);
    background: none;
    border: none;
    text-align: left;
    cursor: pointer;
}
details.dropdown .dd-menu a .ic,
details.dropdown .dd-menu button .ic { width: 17px; height: 17px; margin-bottom: 0; color: var(--faint); }
details.dropdown .dd-menu a:hover,
details.dropdown .dd-menu button:hover { background: var(--panel-2); color: var(--text); }
details.dropdown .dd-menu button:hover .ic { color: var(--danger-2); }
details.dropdown .dd-menu form { display: contents; }

/* ------------------------------------------------------------ fenêtre modale */
/* Générique (<div class="modal-overlay" data-modal>) : ouverture via [data-modal-open="id"],
   fermeture via [data-modal-close], clic sur le fond, ou Échap (voir app.js). */
.modal-overlay {
    display: none;
    position: fixed;
    inset: 0;
    background: rgba(5, 8, 15, .72);
    z-index: 200;
    align-items: flex-start;
    justify-content: center;
    padding: 40px 24px;
    overflow-y: auto;
}
.modal-overlay.open { display: flex; }
.modal-box {
    background: var(--panel);
    border: 1px solid var(--border-soft);
    border-radius: var(--radius);
    box-shadow: var(--shadow);
    width: 100%;
    max-width: 640px;
    padding: 24px;
    animation: modal-in .18s ease;
}
/* Rejoue à chaque ouverture (display:none -> flex sur .modal-overlay.open déclenche un nouveau
   rendu de .modal-box, donc l'animation repart), même esprit que dd-menu-in pour les dropdowns. */
@keyframes modal-in {
    from { opacity: 0; transform: translateY(-8px) scale(.98); }
    to { opacity: 1; transform: translateY(0) scale(1); }
}
.modal-head { display: flex; align-items: center; justify-content: space-between; gap: 16px; margin-bottom: 18px; }
.modal-head h2 { margin: 0; }
.modal-close {
    background: none; border: none; color: var(--muted); cursor: pointer;
    font-size: 22px; line-height: 1; padding: 4px; flex: none;
}
.modal-close:hover { color: var(--text); }

/* --------------------------------------------------------------- boutons */
.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    padding: 11px 20px;
    border-radius: var(--radius-sm);
    border: 1px solid var(--border);
    background: var(--panel-2);
    color: var(--text);
    font-weight: 600;
    font-size: 14px;
    cursor: pointer;
    transition: transform .15s ease, box-shadow .15s ease, background .15s ease;
}
.btn:hover { transform: translateY(-1px); box-shadow: var(--shadow); }
.btn.gold { background: var(--grad-gold); color: var(--gold-ink); border-color: transparent; }
.btn.outline { background: transparent; }
.btn.danger { background: var(--danger); border-color: transparent; color: #fff; }
.btn.small { padding: 8px 14px; font-size: 13px; }
.btn:disabled { opacity: .5; cursor: not-allowed; transform: none; }

/* Bouton "retour" en haut d'une page de détail — respire davantage que le simple 16px utilisé
   ailleurs, pour ne pas coller au kicker/titre qui suit juste en dessous. Le kicker qui suit est
   lui-même en inline-block : sans display:flex ici (bloc, mais toujours de la largeur de son
   contenu grâce à width:fit-content), les deux restaient côte à côte sur la même ligne au lieu
   que le kicker passe à la ligne suivante. */
.btn-back { display: flex; width: fit-content; margin-bottom: 28px; }

/* Formulaire "Supprimer" affiché juste après un lien "Modifier" dans une cellule de tableau
   (display:inline pour rester sur la même ligne) — sans marge, les deux boutons se touchaient. */
.action-form { display: inline; margin-left: 8px; }

/* --------------------------------------------------------------- panels */
.panel {
    background: var(--panel);
    border: 1px solid var(--border-soft);
    border-radius: var(--radius);
    padding: 22px;
}
.panel-2 { background: var(--panel-2); }
.card {
    background: var(--panel);
    border: 1px solid var(--border-soft);
    border-radius: var(--radius);
    padding: 20px;
    transition: border-color .15s ease, background .15s ease, transform .2s ease, box-shadow .2s ease;
}
.card:hover { border-color: var(--gold); background: var(--panel-2); transform: translateY(-4px); box-shadow: 0 14px 28px -16px rgba(201, 162, 39, .4); }
.card-eyebrow { font-size: 12px; letter-spacing: .08em; text-transform: uppercase; color: var(--gold-2); margin-bottom: 8px; }
.card h3 { font-size: 17px; margin-bottom: 8px; }
.card p { color: var(--muted); font-size: 14px; margin-bottom: 0; }
/* Vignette de couverture d'un article (aperçu, home/liste) — bleed jusqu'aux bords de .card
   (marge négative = son padding) avec coins arrondis assortis en haut seulement. */
.card-thumb {
    display: block; width: calc(100% + 40px); margin: -20px -20px 14px -20px;
    aspect-ratio: 16 / 9; object-fit: cover; border-radius: var(--radius) var(--radius) 0 0;
}
/* Bandeau "Notre mission" (accueil) : texte à gauche, CTA à droite, sur toute la largeur
   de la section (plutôt qu'un panneau latéral qui laissait les communiqués à l'étroit). */
.mission-panel { display: flex; align-items: center; justify-content: space-between; gap: 28px; flex-wrap: wrap; margin-top: 28px; }
.mission-panel-text { max-width: 720px; }
.mission-panel-text p { margin-bottom: 8px; }
.mission-panel-text p:last-of-type { margin-bottom: 0; }

/* ---------------------------------------------------------------- hero */
.hero {
    position: relative;
    padding: 64px 0 56px;
    background: var(--bg-2);
    border-bottom: 3px solid var(--gold);
    overflow: hidden;
}
.hero-seal {
    position: absolute;
    top: 50%; right: 4%;
    width: 320px; height: 320px;
    transform: translateY(-50%);
    opacity: .12;
    filter: grayscale(1) brightness(2);
    pointer-events: none;
    animation: seal-pulse 7s ease-in-out infinite;
}
/* Pulsation très subtile du sceau en filigrane — évoque un radar/contrôle en arrière-plan
   plutôt qu'un simple élément statique, sans distraire du texte au premier plan. */
@keyframes seal-pulse {
    0%, 100% { opacity: .12; }
    50% { opacity: .2; }
}
.hero-inner { position: relative; max-width: 640px; animation: hero-in .7s ease both; }
@keyframes hero-in {
    from { opacity: 0; transform: translateY(18px); }
    to { opacity: 1; transform: translateY(0); }
}
.hero h1 { font-size: 38px; line-height: 1.2; }
.hero .accent { color: var(--gold-2); }
.hero .lead { color: var(--muted); font-size: 16px; max-width: 540px; }
.hero-actions { display: flex; gap: 14px; margin-top: 26px; }
@media (max-width: 900px) { .hero-seal { display: none; } }

/* Grille de services officielle façon site .gov (page d'accueil) — colonnes figées à 6 pour
   tenir sur une seule ligne en desktop (repli à 3 puis 1 sur tablette/mobile). */
/* Conteneur élargi pour "Nos services" seulement : au-delà de 6 tuiles, .container standard
   (--maxw) devenait trop étroit pour garder une seule ligne sans rogner le texte des cartes —
   quitte à empiéter sur les marges latérales habituelles, uniquement pour cette section. */
.container-services { max-width: 1400px; }
.service-grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 1px; background: var(--border-soft); border: 1px solid var(--border-soft); border-radius: var(--radius); overflow: hidden; }
.service-card {
    background: var(--panel);
    padding: 22px 14px;
    display: block;
    transition: background .15s ease, box-shadow .2s ease;
}
/* Anneau intérieur plutôt qu'une élévation (translateY) : .service-grid a overflow:hidden pour
   ses coins arrondis, une carte qui "sort" du cadre au survol serait rognée en haut de grille. */
.service-card:hover { background: var(--panel-2); box-shadow: inset 0 0 0 1px var(--gold); }
.service-card h3 { font-size: 14px; margin-bottom: 6px; }
.service-card p { font-size: 12px; color: var(--muted); margin-bottom: 0; }
@media (max-width: 1200px) { .service-grid { grid-template-columns: repeat(4, 1fr); } }
@media (max-width: 700px) { .service-grid { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 420px) { .service-grid { grid-template-columns: 1fr; } }

/* Code Fédéral (page publique) : sommaire sticky + colonne principale, encadré "derniers modifiés",
   une carte par article avec bloc sanction distinct (reproduit le bloc "SANCTION | ..." du document
   de référence). Réutilise .tag-badge/--tag-color (fragments :: niveauCodeBadge) pour les couleurs
   par niveau de gravité. */
.code-federal-recents { display: flex; flex-wrap: wrap; gap: 10px; margin: 24px 0 32px; }
.code-federal-recents a {
    display: flex; align-items: center; gap: 8px;
    background: var(--panel); border: 1px solid var(--border-soft); border-radius: 999px;
    padding: 8px 16px; font-size: 13px; color: var(--muted);
}
.code-federal-recents a:hover { border-color: var(--gold); color: var(--text); }
.code-federal-recents .date { color: var(--faint); font-size: 12px; }

/* Barre de filtre (tri par niveau + recherche texte) — réutilisée telle quelle côté public
   (fragment code-federal.html) et côté gestion admin (dashboard/code-federal/liste.html), filtrage
   100% client (voir app.js, bloc [data-cf-groupes]). */
.code-federal-filtres { display: flex; flex-wrap: wrap; gap: 14px; align-items: center; margin: 24px 0; }
.code-federal-search {
    flex: 1 1 260px; max-width: 360px; padding: 9px 14px;
    background: var(--panel); border: 1px solid var(--border-soft); border-radius: var(--radius-sm);
    color: var(--text);
}
.code-federal-niveau-tabs { display: flex; flex-wrap: wrap; gap: 8px; }
.code-federal-niveau-tab {
    padding: 7px 14px; border-radius: 999px; border: 1px solid var(--border-soft);
    background: var(--panel); color: var(--muted); font-size: 13px; font-weight: 600; cursor: pointer;
}
.code-federal-niveau-tab:hover { border-color: var(--gold); color: var(--text); }
.code-federal-niveau-tab.active { background: var(--grad-gold); color: var(--gold-ink); border-color: transparent; }
.code-federal-masque { display: none !important; }

.code-federal-layout { display: flex; gap: 32px; align-items: flex-start; }
.code-federal-toc {
    flex: 0 0 260px; position: sticky; top: 90px; max-height: calc(100vh - 120px); overflow-y: auto;
    background: var(--panel); border: 1px solid var(--border-soft); border-radius: var(--radius);
    padding: 18px;
}
.code-federal-toc-niveau { margin-bottom: 14px; }
.code-federal-toc-niveau:last-child { margin-bottom: 0; }
.code-federal-toc-niveau > a { display: block; font-weight: 600; font-size: 13px; margin-bottom: 6px; }
.code-federal-toc-articles { display: flex; flex-direction: column; gap: 4px; padding-left: 10px; border-left: 2px solid var(--border-soft); }
.code-federal-toc-articles a { font-size: 12px; color: var(--muted); }
.code-federal-toc-articles a:hover { color: var(--gold-2); }
.code-federal-main { flex: 1; min-width: 0; }
.code-federal-chapitre { margin-bottom: 40px; }
.code-federal-chapitre h2 { margin-bottom: 20px; }
.code-federal-article {
    background: var(--panel); border: 1px solid var(--border-soft); border-radius: var(--radius);
    padding: 22px 24px; margin-bottom: 18px; scroll-margin-top: 90px;
}
.code-federal-article-head { display: flex; align-items: center; gap: 12px; margin-bottom: 12px; flex-wrap: wrap; }
.code-federal-article-numero { font-family: var(--font-serif); font-weight: 700; color: var(--gold-2); }
.code-federal-article-corps { color: var(--muted); line-height: 1.7; }
.sanction-box {
    margin-top: 16px; padding: 14px 18px; border-radius: var(--radius-sm);
    border-left: 3px solid var(--tag-color, var(--gold)); background: var(--panel-2); font-size: 14px;
}
.sanction-box strong { color: var(--tag-color, var(--gold-2)); text-transform: uppercase; font-size: 12px; letter-spacing: .06em; display: block; margin-bottom: 6px; }
.sanction-box.niveau-1 { --tag-color: #5b8def; }
.sanction-box.niveau-2 { --tag-color: #e0a72e; }
.sanction-box.niveau-3 { --tag-color: #e08a3f; }
.sanction-box.niveau-4 { --tag-color: #d9534f; }
@media (max-width: 900px) {
    .code-federal-layout { flex-direction: column; }
    .code-federal-toc { position: static; width: 100%; max-height: none; }
}

/* FAQ (page publique) : réutilise .code-federal-filtres/-search/-niveau-tabs/-layout/-toc/-chapitre
   ci-dessus tel quel pour le tri par rubrique + la recherche (voir app.js, même bloc
   [data-cf-groupes]) — seul l'accordéon question/réponse est propre à la FAQ, Code Fédéral affichant
   toujours ses articles dépliés. max-height volontairement large (pas de mesure JS de scrollHeight) :
   simple et jamais limitant pour une réponse de FAQ réaliste, au prix d'une transition qui peut finir
   un peu tôt sur une réponse très longue. */
.faq-toolbar { display: flex; gap: 10px; margin: 0 0 20px; }
.faq-item {
    background: var(--panel); border: 1px solid var(--border-soft); border-radius: var(--radius);
    margin-bottom: 12px; scroll-margin-top: 90px; overflow: hidden;
}
.faq-item-question {
    display: flex; justify-content: space-between; align-items: center; gap: 12px; width: 100%;
    padding: 18px 22px; background: none; border: none; color: var(--text); font-family: var(--font-serif);
    font-size: 16px; font-weight: 600; text-align: left; cursor: pointer;
}
.faq-item-question:hover { color: var(--gold-2); }
.faq-item-chevron { flex-shrink: 0; transition: transform .2s ease; color: var(--muted); }
.faq-item.expanded .faq-item-chevron { transform: rotate(180deg); color: var(--gold-2); }
.faq-item-answer {
    max-height: 0; overflow: hidden; color: var(--muted); line-height: 1.7;
    padding: 0 22px; transition: max-height .25s ease, padding .25s ease;
}
.faq-item.expanded .faq-item-answer { max-height: 5000px; padding: 0 22px 20px; }

/* ------------------------------------------------------------------ badge */
.badge {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 4px 10px;
    border-radius: 999px;
    font-size: 12px;
    font-weight: 600;
    white-space: nowrap;
    border: 1px solid var(--grade-color, var(--border));
    color: var(--grade-color, var(--muted));
}
.badge::before {
    content: "";
    width: 7px; height: 7px;
    border-radius: 50%;
    background: var(--grade-color, var(--muted));
}
.badge.ok { border-color: var(--ok); color: var(--ok); }
.badge.warn { border-color: var(--warn); color: var(--warn); }

/* Badge décoratif avec icône/logo (contrairement à .badge, pas de pastille ::before —
   l'icône remplace la pastille comme signal visuel). */
.tag-badge {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 4px 10px;
    border-radius: 999px;
    font-size: 12px;
    font-weight: 600;
    border: 1px solid var(--tag-color, var(--border));
    color: var(--tag-color, var(--muted));
}
.tag-badge .ic { width: 13px; height: 13px; flex: none; }
.tag-badge img { width: 13px; height: 13px; border-radius: 50%; object-fit: cover; flex: none; }

/* Document lié à une entreprise (fiche entreprise) — "sous accréditation" : accès restreint par
   grade/groupe, cliquable seulement si le membre courant y a droit (sinon texte simple). */
.accreditation-row {
    display: flex; align-items: center; gap: 12px;
    background: var(--bg-2); border: 1px solid var(--border-soft); border-radius: var(--radius-sm);
    padding: 12px 14px;
}
.accreditation-row .ic { width: 18px; height: 18px; flex: none; color: var(--gold-2); }
.accreditation-badge {
    display: inline-flex; align-items: center; gap: 5px;
    font-size: 11px; font-weight: 600; letter-spacing: .02em;
    color: var(--warn); border: 1px solid rgba(224, 167, 46, .35); background: rgba(224, 167, 46, .1);
    border-radius: 999px; padding: 2px 9px; margin: 4px 8px 0 0;
}
.accreditation-badge .ic { width: 11px; height: 11px; flex: none; }

/* Bulle d'information générique au survol/focus (icône ou tout élément avec data-tooltip) — même
   mécanisme CSS pur que .page-presence [data-tooltip], généralisé pour être réutilisable ailleurs
   (ex. résumé des permissions d'un groupe sur sa fiche, dashboard/departements/detail.html). */
.info-bulle { position: relative; display: inline-flex; align-items: center; cursor: help; color: var(--muted); }
.info-bulle .ic { width: 15px; height: 15px; }
.info-bulle::after {
    content: attr(data-tooltip);
    position: absolute; bottom: calc(100% + 8px); left: 50%; transform: translateX(-50%);
    background: var(--panel-2); border: 1px solid var(--border-soft); border-radius: var(--radius-sm);
    padding: 6px 10px; font-size: 12px; color: var(--text); white-space: normal;
    width: max-content; max-width: 260px; text-align: left;
    opacity: 0; pointer-events: none; transition: opacity .15s ease; box-shadow: var(--shadow); z-index: 20;
}
.info-bulle:hover::after, .info-bulle:focus-visible::after { opacity: 1; }

/* Liste de permissions sous forme de bulles individuelles (au lieu d'un texte concaténé). */
.perm-chips { display: flex; flex-wrap: wrap; gap: 6px; }
.perm-chip {
    display: inline-flex;
    align-items: center;
    padding: 3px 9px;
    border-radius: 999px;
    font-size: 11.5px;
    font-weight: 600;
    border: 1px solid var(--border);
    color: var(--muted);
    background: var(--panel-2);
    white-space: nowrap;
}

/* --------------------------------------------------------------- tables */
/* Empêche un tableau large de forcer le scroll horizontal de toute la page sur mobile —
   seul ce conteneur défile, pas le reste de .dash-content. */
.table-scroll { width: 100%; overflow-x: auto; }
table.data { width: 100%; border-collapse: collapse; font-size: 14px; }
table.data th {
    text-align: left;
    font-size: 11px;
    letter-spacing: .08em;
    text-transform: uppercase;
    color: var(--faint);
    padding: 10px 12px;
    border-bottom: 1px solid var(--border-soft);
}
table.data td { padding: 12px; border-bottom: 1px solid var(--border-soft); vertical-align: middle; }
table.data tr:last-child td { border-bottom: none; }
table.data tr:hover td { background: rgba(255, 255, 255, .015); }

/* --------------------------------------------------------------- formulaires */
.field { margin-bottom: 18px; }
.field label { display: block; font-size: 13px; color: var(--muted); margin-bottom: 6px; }
.field .hint { font-size: 12px; color: var(--faint); margin-top: 6px; }

/* Ligne label + bouton "gérer" (département/groupe/tags sur la fiche personnel) — le bouton
   reste sur sa propre ligne à droite du label, séparé des badges affichés en dessous, pour ne
   pas se fondre visuellement parmi eux. */
/* Une valeur par ligne (département/groupe/tag) plutôt qu'un flux qui les regroupe plusieurs
   par ligne — plus lisible avec des libellés longs. */
.badge-row { display: flex; flex-direction: column; align-items: flex-start; gap: 6px; margin-bottom: 8px; }
/* inline-block plutôt que le display:flex hérité de .dropdown summary (block, pleine largeur) —
   garde le bouton "gérer" à sa largeur de contenu, sous les valeurs. */
details.dropdown.field-manage { display: inline-block; }
details.dropdown.field-manage summary { padding: 5px 10px 5px 8px; font-size: 12px; color: var(--muted); }
details.dropdown.field-manage summary:hover { color: var(--text); }
details.dropdown.field-manage summary .ic { width: 14px; height: 14px; }
input[type="text"], input[type="search"], input[type="number"], textarea, select {
    width: 100%;
    background: var(--bg-2);
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    color: var(--text);
    padding: 11px 13px;
    font-size: 14px;
    font-family: inherit;
}
/* Sans ça, le popup natif du <select> reste blanc sur Chrome/Edge Windows même si le
   contrôle fermé est stylé sombre — color-scheme doit être répété sur l'élément lui-même. */
select { color-scheme: dark; }
select option { background: var(--bg-2); color: var(--text); }
textarea { resize: vertical; min-height: 140px; }
input[type="text"]:focus, textarea:focus, select:focus {
    outline: none;
    border-color: var(--gold);
    box-shadow: 0 0 0 3px rgba(201, 162, 39, .18);
}
input:disabled, textarea:disabled, select:disabled {
    opacity: .6;
    cursor: not-allowed;
}

/* Dropdown custom (voir app.js) qui remplace le rendu de chaque <select> : le popup natif reste
   blanc sur Chrome/Edge Windows quel que soit le CSS (color-scheme ci-dessus insuffisant seul).
   Le <select> d'origine reste dans le DOM, juste masqué visuellement — la soumission du
   formulaire et la validation serveur (th:field, erreurs) ne changent pas. */
.select-custom { position: relative; width: 100%; }
.select-custom select { position: absolute; opacity: 0; pointer-events: none; width: 1px; height: 1px; }
.select-trigger {
    width: 100%;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    background: var(--bg-2);
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    color: var(--text);
    padding: 11px 13px;
    font-size: 14px;
    font-family: inherit;
    cursor: pointer;
    text-align: left;
}
.select-trigger:hover { border-color: var(--gold); }
.select-trigger:disabled { opacity: .6; cursor: not-allowed; }
.select-trigger .caret { font-size: 10px; color: var(--muted); transition: transform .2s ease; flex: none; }
.select-custom.open .select-trigger {
    border-color: var(--gold);
    box-shadow: 0 0 0 3px rgba(201, 162, 39, .18);
}
.select-custom.open .select-trigger .caret { transform: rotate(180deg); }

.select-panel {
    display: none;
    flex-direction: column;
    gap: 2px;
    position: absolute;
    top: calc(100% + 6px);
    left: 0;
    right: 0;
    max-height: 260px;
    overflow-y: auto;
    background: var(--panel);
    border: 1px solid var(--border-soft);
    border-radius: var(--radius);
    box-shadow: var(--shadow);
    padding: 6px;
    z-index: 50;
}
.select-custom.open .select-panel { display: flex; animation: dd-menu-in .16s ease; }
.select-option {
    display: block;
    width: 100%;
    padding: 8px 10px;
    border-radius: var(--radius-sm);
    font-size: 14px;
    color: var(--muted);
    background: none;
    border: none;
    text-align: left;
    cursor: pointer;
}
.select-option:hover { background: var(--panel-2); color: var(--text); }
.select-option.selected { color: var(--gold-2); background: rgba(201, 162, 39, .12); font-weight: 600; }
input[type="color"] {
    width: 52px; height: 40px;
    padding: 2px;
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    background: var(--bg-2);
}
.color-row { display: flex; align-items: center; gap: 12px; }
.color-preview { width: 16px; height: 16px; border-radius: 4px; border: 1px solid rgba(255, 255, 255, .2); }

/* Interrupteurs à glissière (jamais de checkbox native) — utilisés pour les permissions */
.switch-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
    padding: 12px 0;
    border-bottom: 1px solid var(--border-soft);
}
.switch-row:last-child { border-bottom: none; }
.switch-row .label { font-size: 14px; }

/* Regroupe plusieurs .switch-row apparentés (ex. statuts Décédé/Recherché) dans une seule carte
   au lieu de les laisser flotter comme des blocs bruts qui se suivent. */
.switch-group {
    border: 1px solid var(--border-soft);
    border-radius: var(--radius-sm);
    background: var(--panel-2);
    padding: 2px 14px;
    margin-bottom: 18px;
}
.switch-group .switch-row:last-child { border-bottom: none; }
.switch-row .desc { font-size: 12px; color: var(--faint); }

/* Checklist d'attribution rapide (tags sur la fiche personnel) — coche = soumission immédiate
   du formulaire parent, façon menu de rôles Discord. */
.tag-toggle-row { display: flex; align-items: center; gap: 8px; padding: 7px 6px; border-radius: var(--radius-sm); cursor: pointer; }
.tag-toggle-row:hover { background: var(--panel-2); }
/* Checkbox natif masqué (comme .segmented) — la sélection se lit sur le remplissage du badge adjacent. */
.tag-toggle-row input[type="checkbox"] { position: absolute; opacity: 0; pointer-events: none; }
.tag-toggle-row input:checked + .tag-badge { background: var(--tag-color, var(--gold)); color: var(--bg); }
.tag-toggle-row input:checked + .badge { background: var(--grad-gold); color: var(--gold-ink); border-color: transparent; }
.tag-toggle-row input:checked + .badge::before { background: var(--gold-ink); }
.tag-toggle-row input:focus-visible + .tag-badge,
.tag-toggle-row input:focus-visible + .badge { box-shadow: 0 0 0 3px rgba(201, 162, 39, .28); }
.tag-toggle-row.inherited { opacity: .55; cursor: not-allowed; }

/* Sélection de grade façon Discord (fiche personnel) — chaque ligne est son propre petit
   formulaire (clic = soumission immédiate), pas de coche : le grade est toujours unique. */
.grade-toggle-row + .grade-toggle-row { margin-top: 1px; }
.grade-toggle-btn {
    display: flex; align-items: center; gap: 8px; width: 100%; text-align: left;
    padding: 7px 8px; border-radius: var(--radius-sm); cursor: pointer;
    background: none; border: none; color: var(--text); font: inherit; font-size: 13px;
}
.grade-toggle-btn:hover:not(:disabled) { background: var(--panel-2); }
.grade-toggle-btn:disabled { color: var(--gold-2); font-weight: 600; cursor: default; }
.grade-toggle-btn::before { content: ""; width: 7px; height: 7px; border-radius: 50%; background: var(--muted); flex: none; }
.grade-toggle-btn:disabled::before { background: var(--gold-2); }
/* Onglet de catégorie actif dans la fenêtre "Accès du grade" (cliquable, contrairement au
   :disabled ci-dessus qui marque le grade déjà attribué sur la fiche personnel). */
.grade-toggle-btn.is-active { background: var(--panel-2); color: var(--gold-2); font-weight: 600; }
.grade-toggle-btn.is-active::before { background: var(--gold-2); }
.switch { position: relative; display: inline-block; width: 44px; height: 24px; flex: none; }
.switch input { position: absolute; opacity: 0; width: 100%; height: 100%; margin: 0; cursor: pointer; }
.switch .track {
    position: absolute; inset: 0;
    background: var(--border);
    border-radius: 999px;
    transition: background .18s ease;
}
.switch .thumb {
    position: absolute;
    top: 3px; left: 3px;
    width: 18px; height: 18px;
    border-radius: 50%;
    background: var(--text);
    transition: transform .18s ease;
}
.switch input:checked ~ .track { background: var(--grad-gold); }
.switch input:checked ~ .thumb { transform: translateX(20px); background: var(--gold-ink); }
.switch input:focus-visible ~ .track { box-shadow: 0 0 0 3px rgba(201, 162, 39, .28); }

/* Segments (statut brouillon/publié) */
.segmented { display: inline-flex; border: 1px solid var(--border); border-radius: var(--radius-sm); overflow: hidden; }
.segmented input { position: absolute; opacity: 0; pointer-events: none; }
.segmented label {
    padding: 9px 16px;
    font-size: 13px;
    font-weight: 600;
    color: var(--muted);
    cursor: pointer;
    margin: 0;
}
.segmented input:checked + label { background: var(--grad-gold); color: var(--gold-ink); }

/* Variante compacte à 4 options (Aucun/Voir/Utiliser/Gérer) — fenêtre "Accès du grade". */
.segmented.small label { padding: 6px 10px; font-size: 12px; }

/* Fenêtre "Accès du grade" (refonte permissions) : catégories à gauche, pages de la catégorie
   sélectionnée à droite (un seul bloc .acces-grade-categorie-bloc visible à la fois, cf. app.js). */
.acces-grade-layout { display: grid; grid-template-columns: 190px 1fr; gap: 16px; margin-top: 10px; }
.acces-grade-categories { display: flex; flex-direction: column; gap: 2px; border-right: 1px solid var(--border-soft); padding-right: 12px; }
.acces-grade-pages { max-height: 340px; overflow-y: auto; }
.acces-grade-categorie-bloc .switch-row .label { flex: 1; }
@media (max-width: 640px) {
    .acces-grade-layout { grid-template-columns: 1fr; }
    .acces-grade-categories { flex-direction: row; flex-wrap: wrap; border-right: none; border-bottom: 1px solid var(--border-soft); padding-right: 0; padding-bottom: 10px; }
    .acces-grade-categories .grade-toggle-btn { width: auto; }
}

/* Badge "Accès total" (grade avec toutesPermissions=true) — remplace la liste de chips de la
   colonne Permissions puisque le détail par page devient sans objet. */
.acces-total-badge { background: var(--grad-gold); color: var(--gold-ink); font-weight: 700; }

/* Panneau "propriétaire uniquement" en tête de la fenêtre Accès du grade (visible seulement si
   ROLE_SUPER_ADMIN, voir GradeController.estProprietaire). Bordure dorée pour le distinguer
   nettement du reste du formulaire — c'est un interrupteur à haut risque. */
.acces-total-panel {
    display: flex; align-items: center; justify-content: space-between; gap: 16px;
    padding: 14px 16px; border: 1px solid var(--gold-2); border-radius: var(--radius-sm);
    background: rgba(201, 162, 39, .08);
}
.acces-total-panel-texte label { display: flex; align-items: center; gap: 8px; font-weight: 700; color: var(--gold-2); }
.acces-total-field { margin-bottom: 18px; }

/* -------------------------------------------------------------- dashboard */
.dash-layout { display: grid; grid-template-columns: 240px 1fr; min-height: calc(100vh - 63px); }
.dash-sidebar {
    border-right: 1px solid var(--border-soft);
    background: var(--bg-2);
    padding: 24px 16px;
}
.sidebar-group { margin-top: 14px; padding-top: 14px; border-top: 1px solid var(--border-soft); }
.dash-sidebar .group-title {
    display: flex; align-items: center; justify-content: space-between;
    font-size: 11px; letter-spacing: .1em; text-transform: uppercase;
    color: var(--faint); padding: 6px 10px; margin: 0 0 4px;
    border-radius: var(--radius-sm);
    cursor: pointer; user-select: none; list-style: none;
}
.dash-sidebar .group-title::-webkit-details-marker { display: none; }
.dash-sidebar .group-title::marker { content: ""; }
.dash-sidebar .group-title:hover { color: var(--text); background: var(--panel-2); }
.group-caret {
    display: inline-flex; color: var(--muted);
    transition: transform .15s ease, color .15s ease;
}
.group-caret .ic { width: 15px; height: 15px; }
.dash-sidebar .group-title:hover .group-caret { color: var(--gold-2); }
.sidebar-group:not([open]) .group-caret { transform: rotate(-90deg); }
.sidebar-group-links { display: flex; flex-direction: column; gap: 2px; }
.dash-sidebar a {
    display: flex; align-items: center; gap: 10px;
    padding: 10px 10px;
    border-radius: var(--radius-sm);
    font-size: 14px;
    color: var(--muted);
    transition: background .15s ease, color .15s ease;
}
.dash-sidebar a:hover { background: var(--panel-2); color: var(--text); }
.dash-sidebar a.active { background: var(--panel-2); color: var(--gold-2); }
.sidebar-badge {
    margin-left: auto;
    background: var(--grad-gold); color: var(--gold-ink);
    font-size: 11px; font-weight: 700;
    min-width: 18px; height: 18px; padding: 0 5px;
    border-radius: 999px;
    display: flex; align-items: center; justify-content: center;
}
/* min-width: 0 nécessaire car .dash-content est l'enfant de la piste 1fr de .dash-layout : sans
   ça, la piste grid refuse de rétrécir sous la largeur min-content de son contenu, ce qui empêche
   .overview-row (pourtant flex-wrap:wrap) d'atteindre l'étroitesse nécessaire pour s'empiler et
   provoque un débordement horizontal de toute la page entre ~900px et ~1300px de large. */
.dash-content { padding: 40px 32px; max-width: 1620px; margin: 0 auto; width: 100%; min-width: 0; }
.dash-content h1 { font-size: 26px; }

.stat-row { display: grid; grid-template-columns: repeat(auto-fit, minmax(190px, 1fr)); gap: 16px; margin-bottom: 28px; }
/* min-width: 0 casse le comportement par défaut des enfants de grille (qui refusent de rétrécir
   sous la largeur intrinsèque de leur contenu) — sans ça, un montant à 9+ chiffres sans espaces
   (ex. 1,456,118,664$) déborde hors de la tuile au lieu de s'y adapter. Même correctif sur le div
   texte des tuiles .with-icon, qui est lui-même un enfant flex soumis au même piège. */
.stat-tile { background: var(--panel); border: 1px solid var(--border-soft); border-radius: var(--radius); padding: 18px 20px; min-width: 0; }
.stat-tile.with-icon > div { min-width: 0; }
/* Georgia (--font-serif) a des chiffres à la graisse et aux formes inégales aux grandes tailles
   (particulièrement visible sur les gros montants avec séparateurs de milliers) — les tuiles
   statistiques utilisent donc la police sans-serif avec chiffres tabulaires/alignés, plus lisible
   pour des données chiffrées, tout en gardant le serif pour les titres. Taille réduite et
   overflow-wrap en secours : ce site manipule couramment des montants à 9-10 chiffres. */
.stat-tile .n {
    font-family: var(--font-sans);
    font-variant-numeric: tabular-nums lining-nums;
    font-weight: 700;
    font-size: 22px;
    color: var(--gold-2);
    overflow-wrap: anywhere;
}
.stat-tile .l { font-size: 13px; color: var(--muted); }

/* Vue d'ensemble : widgets RCD/MDT à gauche (gap plutôt que margin-top, pour que l'espacement
   reste cohérent quel que soit le widget affiché en premier selon les permissions), présence par
   département en colonne à droite, sur la même ligne — la colonne présence repasse sous si la
   fenêtre devient trop étroite. */
.overview-row { display: flex; gap: 24px; align-items: flex-start; flex-wrap: wrap; margin-bottom: 28px; }
.overview-left { display: flex; flex-direction: column; gap: 20px; flex: 1 1 480px; min-width: 0; }
.presence-col { flex: 1 1 320px; max-width: 380px; min-width: 0; }

/* Ligne cliquable générique (widgets "Dernières enquêtes"/"Derniers citoyens" de la vue
   d'ensemble) : même esprit que .mail-list/.mail-row mais contenu plus court (badge/icône + un
   seul libellé + date), réutilisable pour d'autres listes futures. */
.overview-list { display: flex; flex-direction: column; border: 1px solid var(--border-soft); border-radius: var(--radius); overflow: hidden; }
.overview-list-row {
    display: flex; align-items: center; gap: 12px;
    padding: 12px 18px 12px 15px;
    /* Réutilisé aussi comme <button> (agenda/index.html) : sans ce reset, le navigateur garde
       son cadre par défaut sur les côtés non couverts par border-bottom/border-left ci-dessous
       (liseré blanc/gris visible entre les lignes sur Chrome/Edge). */
    border: none; appearance: none; -webkit-appearance: none;
    border-bottom: 1px solid var(--border-soft);
    border-left: 3px solid transparent;
    background: var(--panel);
    color: var(--muted);
    font-size: 14px;
    transition: background .15s ease, border-left-color .15s ease;
}
.overview-list-row:last-child { border-bottom: none; }
.overview-list-row:hover { background: var(--panel-2); border-left-color: var(--gold); }
.overview-list-row .ic { width: 17px; height: 17px; flex: none; color: var(--gold-2); }
.overview-list-row .titre { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--text); font-weight: 600; }
.overview-list-row .date { flex: none; font-size: 12px; color: var(--faint); }

/* Widget "Derniers documents modifiés" (vue d'ensemble du dashboard) : ligne à deux niveaux de
   texte (titre + créateur/modificateur horodatés), sinon même esprit que .overview-list/-row. */
.doc-recent-list { display: flex; flex-direction: column; border: 1px solid var(--border-soft); border-radius: var(--radius); overflow: hidden; }
.doc-recent-row {
    display: flex; align-items: flex-start; gap: 12px;
    padding: 12px 18px 12px 15px;
    border-bottom: 1px solid var(--border-soft);
    border-left: 3px solid transparent;
    background: var(--panel);
    color: var(--muted);
    transition: background .15s ease, border-left-color .15s ease;
}
.doc-recent-row:last-child { border-bottom: none; }
.doc-recent-row:hover { background: var(--panel-2); border-left-color: var(--gold); }
.doc-recent-row .ic { width: 17px; height: 17px; flex: none; color: var(--gold-2); margin-top: 2px; }
.doc-recent-info { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 3px; }
.doc-recent-info .titre { color: var(--text); font-weight: 600; font-size: 14px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.doc-recent-info .meta { font-size: 12px; color: var(--faint); }

/* Présence par département (vue d'ensemble du dashboard) */
/* Rafraîchissement périodique du widget Présence (app.js, toutes les 15s) : le fragment reçu
   remplace l'ancien en bloc (replaceWith), un fondu bref signale discrètement la mise à jour
   plutôt qu'un remplacement instantané et invisible. */
.presence-refresh-flash { animation: presence-refresh .5s ease; }
@keyframes presence-refresh {
    from { opacity: .4; }
    to { opacity: 1; }
}
.presence-grid { display: flex; flex-direction: column; gap: 14px; }
.presence-dept { background: var(--panel); border: 1px solid var(--border-soft); border-radius: var(--radius); padding: 18px 20px; }
.presence-dept-title { display: flex; align-items: center; gap: 8px; font-weight: 600; font-size: 14px; margin-bottom: 12px; }
.presence-dept-title .ic { width: 16px; height: 16px; color: var(--gold-2); flex: none; }
.presence-row { display: flex; align-items: center; gap: 10px; padding: 7px 0; border-bottom: 1px solid var(--border-soft); }
.presence-row:last-child { border-bottom: none; }
.presence-row img { width: 24px; height: 24px; border-radius: 50%; flex: none; }
.presence-row-info { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.presence-row .nom { font-size: 13px; }
.presence-page { font-size: 11px; color: var(--muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.status-dot { width: 8px; height: 8px; border-radius: 50%; flex: none; }
.status-dot.en-ligne { background: var(--ok); box-shadow: 0 0 0 3px rgba(63, 206, 143, .15); }
.status-dot.inactif { background: var(--warn); box-shadow: 0 0 0 3px rgba(224, 167, 46, .15); }
.status-dot.hors-ligne { background: var(--faint); }
.status-label { font-size: 11px; color: var(--faint); white-space: nowrap; }
.dash-sidebar-toggle {
    display: none;
    flex-direction: column; justify-content: center; gap: 5px;
    width: 38px; height: 38px; padding: 0;
    background: var(--panel-2); border: 1px solid var(--border-soft); border-radius: var(--radius-sm);
    cursor: pointer;
}
.dash-sidebar-toggle span { display: block; width: 16px; height: 2px; background: var(--text); border-radius: 2px; margin: 0 auto; }
@media (max-width: 900px) {
    .dash-layout { grid-template-columns: 1fr; }
    .dash-sidebar {
        position: fixed; left: -280px; top: 63px; width: 260px; height: calc(100vh - 63px);
        overflow-y: auto; z-index: 35; box-shadow: 8px 0 24px rgba(0,0,0,.35);
        transition: left .2s ease;
    }
    .dash-sidebar.open { left: 0; }
    .dash-sidebar-toggle {
        display: flex; position: fixed; top: 73px; left: 16px; z-index: 36;
    }
    /* Marge additionnelle pour ne jamais chevaucher le bouton flottant ci-dessus. */
    .dash-content { padding-top: 90px; }

    /* Mode aperçu actif (voir plus haut) : la sidebar hors-canevas, son bouton bascule et la
       marge du contenu supposent tous que .topbar commence à 63px du haut — décalés ici de la
       hauteur du bandeau, exactement comme .topbar elle-même. */
    .preview-banner ~ .dash-layout .dash-sidebar {
        top: calc(63px + var(--preview-banner-h)); height: calc(100vh - 63px - var(--preview-banner-h));
    }
    .preview-banner ~ .dash-layout .dash-sidebar-toggle { top: calc(73px + var(--preview-banner-h)); }
    .preview-banner ~ .dash-layout .dash-content { padding-top: calc(90px + var(--preview-banner-h)); }
}

.stat-tile.with-icon { display: flex; align-items: center; gap: 14px; }
.stat-tile.with-icon .ic {
    width: 40px; height: 40px; flex: none; margin-bottom: 0;
    display: flex; align-items: center; justify-content: center;
    border-radius: 50%; background: var(--bg-2); border: 1px solid var(--border-soft); color: var(--gold-2);
}
.stat-tile.with-icon .ic svg { width: 20px; height: 20px; }
/* Signale un statut critique (citoyen recherché/décédé) directement sur l'icône de la tuile. */
.stat-tile.with-icon.danger .ic { background: rgba(217, 83, 79, .15); border-color: var(--danger); color: var(--danger); }

/* Icônes SVG inline (fragments :: icon(name)) — pas d'émojis. Taille/couleur neutres par défaut,
   les contextes (tuiles, sidebar, boutons) surchargent au besoin. */
.ic { display: inline-block; width: 18px; height: 18px; color: inherit; flex: none; }
.ic svg { width: 100%; height: 100%; display: block; }

.service-card .ic { width: 28px; height: 28px; margin-bottom: 12px; color: var(--gold-2); }
.dash-sidebar a .ic { width: 17px; height: 17px; }
.btn .ic { width: 14px; height: 14px; }
table.data .ic { width: 15px; height: 15px; }

/* Sélecteur d'icône (départements/groupes/tags/dossiers/catégories académie) : une seule grille
   de toutes les icônes, pas de catégories. Le champ qui porte la valeur soumise est caché (voir
   les templates), la sélection se fait uniquement au clic sur une icône. */
.icon-picker {
    display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 10px;
    max-height: 100px; overflow-y: auto; padding: 2px;
}
.icon-choice {
    width: 42px; height: 42px;
    display: flex; align-items: center; justify-content: center;
    background: var(--bg-2); border: 1px solid var(--border); border-radius: var(--radius-sm);
    color: var(--muted); cursor: pointer;
}
.icon-choice:hover { border-color: var(--gold); color: var(--text); }
.icon-choice.selected { border-color: var(--gold); background: var(--panel-2); color: var(--gold-2); }
.icon-choice .ic { width: 19px; height: 19px; }

/* Icône affichée pour un département/groupe (preset SVG ou image distante) */
.entity-icon {
    width: 38px; height: 38px; flex: none;
    border-radius: var(--radius-sm);
    background: var(--bg-2); border: 1px solid var(--border-soft);
    display: flex; align-items: center; justify-content: center;
    overflow: hidden;
}
.entity-icon .ic { width: 19px; height: 19px; color: var(--gold-2); }
.entity-icon img { width: 100%; height: 100%; object-fit: cover; }
.entity-icon.lg { width: 56px; height: 56px; }
.entity-icon.lg .ic { width: 26px; height: 26px; }
.entity-icon.sm { width: 22px; height: 22px; }
.entity-icon.sm .ic { width: 13px; height: 13px; }

/* Repli quand un citoyen n'a pas de photo (URL) renseignée — même esprit que .entity-icon mais
   circulaire, pour ressembler à un avatar plutôt qu'à une icône de dossier/groupe. */
.citoyen-avatar-vide {
    width: 64px; height: 64px; border-radius: 50%; flex: none;
    background: var(--bg-2); border: 1px solid var(--border-soft);
    display: flex; align-items: center; justify-content: center;
}
.citoyen-avatar-vide .ic { width: 28px; height: 28px; color: var(--gold-2); }

.dep-card {
    display: flex; align-items: center; gap: 14px;
    background: var(--panel); border: 1px solid var(--border-soft); border-radius: var(--radius);
    padding: 16px 18px; margin-bottom: 12px;
}
.dep-card:hover { border-color: var(--gold); }
.dep-card .meta { flex: 1; min-width: 0; }
.dep-card h3 { font-size: 16px; margin-bottom: 4px; }
.dep-card p { font-size: 13px; color: var(--muted); margin-bottom: 0; }

.groupe-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 14px; }
@media (max-width: 700px) { .groupe-grid { grid-template-columns: 1fr; } }

.personnel-columns { display: grid; grid-template-columns: 1fr 1fr; gap: 20px; align-items: start; margin-top: 20px; }
.personnel-columns.single { grid-template-columns: 1fr; }
@media (max-width: 900px) { .personnel-columns { grid-template-columns: 1fr; } }

/* "À propos de cette section" + résumé des accès configurés (fiche Documents), côte à côte et de
   même hauteur (stretch) — si "Accès configurés" déborde, seule sa zone de contenu défile
   (.acces-resume-scroll, hauteur plafonnée), le panneau lui-même reste aligné sur l'autre. */
.about-access-row { display: grid; grid-template-columns: 1fr 1fr; gap: 20px; align-items: stretch; margin-top: 20px; }
.about-access-row.single { grid-template-columns: 1fr; }
@media (max-width: 900px) { .about-access-row { grid-template-columns: 1fr; } }

.acces-resume-panel { display: flex; flex-direction: column; }
.acces-resume-scroll { flex: 1; min-height: 0; max-height: 360px; overflow-y: auto; padding-right: 6px; margin-right: -6px; }

/* Barre de défilement personnalisée (au lieu de la générique du navigateur), assortie au thème. */
.acces-resume-scroll { scrollbar-width: thin; scrollbar-color: var(--border) var(--bg-2); }
.acces-resume-scroll::-webkit-scrollbar { width: 8px; }
.acces-resume-scroll::-webkit-scrollbar-track { background: var(--bg-2); border-radius: 999px; }
.acces-resume-scroll::-webkit-scrollbar-thumb { background: var(--border); border-radius: 999px; }
.acces-resume-scroll::-webkit-scrollbar-thumb:hover { background: var(--gold); }

/* Résumé "qui a accès" (accès-resume-item) : accordéon <details> natif, replié par défaut —
   même logique de caret pivotant que .sidebar-group mais sans dépendance à ce contexte. */
.acces-resume-item {
    background: var(--bg-2); border: 1px solid var(--border-soft); border-radius: var(--radius-sm);
    padding: 10px 14px; margin-bottom: 8px;
}
.acces-resume-item:last-child { margin-bottom: 0; }
.acces-resume-item summary { display: flex; align-items: center; gap: 10px; cursor: pointer; list-style: none; }
.acces-resume-item summary::-webkit-details-marker { display: none; }
.acces-resume-item summary::marker { content: ""; }
.acces-resume-item summary .ic:first-child { color: var(--gold-2); flex: none; }
.acces-resume-nom { flex: 1; font-weight: 600; font-size: 14px; }
.acces-resume-item .group-caret { transform: rotate(-90deg); }
.acces-resume-item[open] .group-caret { transform: rotate(0deg); }
.acces-resume-permissions { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 10px; }

.entreprise-widgets { display: grid; grid-template-columns: 1fr 1fr; gap: 20px; align-items: start; margin-top: 20px; }
@media (max-width: 900px) { .entreprise-widgets { grid-template-columns: 1fr; } }

/* 2 colonnes fixes plutôt qu'un auto-fit qui alignait les 4 widgets (Notes/Traçabilité/
   Documents/RCD) sur une seule ligne écrasée dès que l'écran était assez large. */
.citoyen-widgets { display: grid; grid-template-columns: repeat(2, 1fr); gap: 20px; align-items: stretch; margin-top: 20px; }
@media (max-width: 900px) { .citoyen-widgets { grid-template-columns: 1fr; } }
/* Sans plafond, une note (ou un historique) très longue étire tout le panel et déforme la ligne
   entière face aux deux autres widgets restés courts — hauteur bornée + défilement interne à la place. */
.citoyen-widgets .panel { display: flex; flex-direction: column; }
.citoyen-widget-scroll { max-height: 260px; overflow-y: auto; }

/* Sélecteur de dossier/document en arbre (liaison entreprise) */
.noeud-picker-selection { margin: -6px 0 14px; }
.noeud-picker-selection.has-selection { color: var(--gold-2); font-weight: 600; }
.noeud-tree {
    max-height: 460px;
    overflow-y: auto;
    border: 1px solid var(--border-soft);
    border-radius: var(--radius-sm);
    background: var(--bg-2);
    padding: 6px;
}
.noeud-tree-children { display: none; margin-left: 20px; padding-left: 10px; border-left: 1px dashed var(--border-soft); }
.noeud-tree-item.expanded > .noeud-tree-children { display: block; }
.noeud-tree-row { display: flex; align-items: center; gap: 7px; padding: 7px 8px; border-radius: var(--radius-sm); cursor: pointer; }
.noeud-tree-row:hover { background: var(--panel-2); }
.noeud-tree-row.selected { background: var(--grad-gold); color: var(--gold-ink); }
.noeud-tree-nom { font-size: 13px; }
.noeud-tree-toggle {
    background: none; border: none; color: var(--muted); cursor: pointer; padding: 0;
    width: 16px; flex: none; display: flex; align-items: center; justify-content: center;
}
.noeud-tree-row.selected .noeud-tree-toggle { color: var(--gold-ink); }
.noeud-tree-toggle .caret { display: inline-block; transition: transform .15s ease; }
.noeud-tree-item.expanded > .noeud-tree-row .noeud-tree-toggle .caret { transform: rotate(90deg); }
.noeud-tree-spacer { width: 16px; flex: none; }

/* ------------------------------------------------------------------ galerie */
.gallery-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 12px; }
@media (max-width: 900px) { .gallery-grid { grid-template-columns: repeat(2, 1fr); } }
/* Aperçu galerie (accueil) : simple zoom au survol (pas de lightbox ici, juste un lien vers
   /galerie en dessous) — wrapper overflow:hidden pour clipper le transform:scale de l'image. */
.gallery-thumb { display: block; overflow: hidden; aspect-ratio: 4 / 3; border-radius: var(--radius-sm); border: 1px solid var(--border-soft); }
.gallery-thumb img { display: block; width: 100%; height: 100%; object-fit: cover; transition: transform .25s ease; }
.gallery-thumb:hover img { transform: scale(1.08); }
/* Page Galerie publique : chaque vignette est un déclencheur de lightbox (.piece-image-trigger,
   même mécanique/CSS que les pièces jointes RCD — zoom au survol via transform: scale déjà défini
   plus bas). Scopé à .gallery-grid pour ne rien changer aux dimensions fixes 140x100px de RCD. */
.gallery-grid .piece-image-trigger { display: block; width: 100%; aspect-ratio: 4 / 3; border: 1px solid var(--border-soft); border-radius: var(--radius-sm); }
.gallery-grid .piece-image-trigger img { width: 100%; height: 100%; object-fit: cover; border-radius: inherit; }

/* ------------------------------------------------------------------ organigramme */
.org-grade { margin-bottom: 36px; }
.org-grade h2 { font-size: 20px; display: flex; align-items: center; gap: 10px; }
.org-members { display: grid; grid-template-columns: repeat(4, 1fr); gap: 14px; }
.org-member { display: flex; align-items: center; gap: 12px; background: var(--panel); border: 1px solid var(--border-soft); border-radius: var(--radius); padding: 12px 14px; }
.org-member img { width: 40px; height: 40px; border-radius: 50%; }
.org-member-info { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.org-member .name { font-size: 14px; font-weight: 600; }
.org-member .grade { font-size: 11px; color: var(--grade-color, var(--muted)); }
@media (max-width: 900px) { .org-members { grid-template-columns: repeat(2, 1fr); } }

/* Arbre hiérarchique de la page Organigramme complète : un palier par grade (dans l'ordre de
   Grade.ordre), relié au palier suivant par un tronc vertical central + une barre horizontale par
   palier (masquée s'il n'y a qu'un seul membre) — entièrement en CSS, pas de librairie de graphe. */
.org-tree { display: flex; flex-direction: column; align-items: center; }
.org-tier { position: relative; display: flex; flex-direction: column; align-items: center; }
.org-tier:not(:first-child) { margin-top: 8px; }
.org-tier:not(:first-child)::before {
    content: ""; width: 2px; height: 32px; background: var(--border-soft);
}
.org-tier-label {
    display: inline-flex; align-items: center; gap: 8px; margin: 10px 0 20px;
    padding: 6px 16px; border-radius: 999px; border: 1px solid var(--grade-color, var(--gold));
    color: var(--grade-color, var(--gold-2)); font-weight: 700; font-size: 14px;
}
.org-tier-members { position: relative; display: flex; flex-wrap: wrap; justify-content: center; gap: 24px 20px; padding-top: 24px; }
.org-tier-members::before {
    content: ""; position: absolute; top: 0; left: 12%; right: 12%; height: 2px; background: var(--border-soft);
}
.org-tier-members.single::before { display: none; }
.org-member-node { position: relative; display: flex; flex-direction: column; align-items: center; gap: 8px; padding-top: 20px; width: 96px; }
.org-member-node::before {
    content: ""; position: absolute; top: 0; left: 50%; width: 2px; height: 20px; background: var(--border-soft); transform: translateX(-50%);
}
.org-member-node img { width: 56px; height: 56px; border-radius: 50%; border: 2px solid var(--border-soft); }
.org-member-node .name { font-size: 13px; font-weight: 600; text-align: center; }
@media (max-width: 700px) { .org-tier-members::before { display: none; } .org-member-node::before { display: none; } }

/* ------------------------------------------------------------------ footer */
footer {
    border-top: 3px solid var(--gold);
    background: var(--bg-2);
    padding: 40px 0 24px;
    color: var(--faint);
    font-size: 13px;
}
.footer-grid { display: grid; grid-template-columns: 1.4fr 1fr 1fr; gap: 32px; margin-bottom: 28px; }
.footer-grid h4 { font-family: var(--font-sans); font-size: 12px; text-transform: uppercase; letter-spacing: .08em; color: var(--muted); margin-bottom: 14px; }
.footer-grid p { font-size: 13px; margin-bottom: 0; }
.footer-links { display: flex; flex-direction: column; gap: 10px; }
.footer-links a { color: var(--faint); font-size: 13px; }
.footer-links a:hover { color: var(--gold-2); }
.footer-bottom {
    display: flex; justify-content: space-between; flex-wrap: wrap; gap: 10px;
    padding-top: 20px; border-top: 1px solid var(--border-soft); font-size: 12px;
}
.footer-bottom a.faint:hover { color: var(--gold-2); }
@media (max-width: 700px) { .footer-grid { grid-template-columns: 1fr; } }

/* ------------------------------------------------------------------ utilitaires */
.muted { color: var(--muted); }
.faint { color: var(--faint); }
.mt-0 { margin-top: 0; }
/* Popup de confirmation flottante (pas un bandeau dans le flux de la page) : les contrôleurs
   n'ont rien à changer, ils posent juste un flash attribute "info"/"erreur" comme avant. Sans
   modificateur .ok/.error/.warn, un flash "info" avait jusqu'ici AUCUN fond/bordure (juste du
   padding) et passait inaperçu — d'où le style "réussite" par défaut ci-dessous. app.js la fait
   disparaître automatiquement après quelques secondes. top: 83px = 63px (hauteur de .topbar,
   constante utilisée ailleurs dans ce fichier) + 20px de marge : avec top: 20px seul, le message
   chevauchait la barre de navigation (z-index 400 contre 40) et devenait illisible. */
.flash {
    padding: 14px 20px;
    border-radius: var(--radius-sm);
    font-size: 14px;
    position: fixed;
    top: 83px;
    left: 50%;
    z-index: 400;
    max-width: min(90vw, 480px);
    box-shadow: var(--shadow);
    background: rgba(63, 206, 143, .12);
    border: 1px solid var(--ok);
    color: var(--ok);
    animation: flash-in .25s ease-out;
}
.flash.hiding { animation: flash-out .3s ease-in forwards; }
.flash.ok { background: rgba(63, 206, 143, .12); border: 1px solid var(--ok); color: var(--ok); }
.flash.error { background: rgba(217, 83, 79, .12); border: 1px solid var(--danger); color: var(--danger-2); }
.flash.warn { background: rgba(224, 167, 46, .12); border: 1px solid var(--warn); color: var(--warn); }
@keyframes flash-in {
    from { opacity: 0; transform: translate(-50%, -12px); }
    to { opacity: 1; transform: translate(-50%, 0); }
}
@keyframes flash-out {
    from { opacity: 1; transform: translate(-50%, 0); }
    to { opacity: 0; transform: translate(-50%, -12px); }
}
.empty-state {
    text-align: center;
    padding: 48px 20px;
    color: var(--muted);
    background: var(--panel);
    border: 1px dashed var(--border);
    border-radius: var(--radius);
}
.empty-state .ic { width: 30px; height: 30px; margin-bottom: 14px; color: var(--faint); }

/* ------------------------------------------------------------------ mail */
/* Barre d'onglets dédiée (Réception/Envoyés/Nouveau message), remplace la simple entête
   kicker+h1 partagée par le reste du dashboard pour donner l'allure d'un vrai client mail. */
.mail-nav { display: flex; justify-content: space-between; align-items: center; flex-wrap: wrap; gap: 14px; margin-bottom: 20px; }
.mail-nav-tabs { display: flex; gap: 4px; background: var(--panel); border: 1px solid var(--border-soft); border-radius: var(--radius-sm); padding: 4px; }
.mail-nav-tabs a { display: flex; align-items: center; gap: 8px; padding: 8px 16px; border-radius: calc(var(--radius-sm) - 2px); font-size: 14px; color: var(--muted); }
.mail-nav-tabs a:hover { color: var(--text); background: var(--panel-2); }
.mail-nav-tabs a.active { background: var(--grad-gold); color: var(--gold-ink); font-weight: 600; }
.mail-nav-tabs a .ic { width: 16px; height: 16px; }
.mail-nav-tabs .sidebar-badge { margin-left: 2px; }

/* Barre d'onglets de la page Administration — copie du style .mail-nav/.mail-nav-tabs (dupliquée
   plutôt que réutilisée telle quelle pour ne pas coupler sémantiquement Administration à Mail). */
.admin-nav { display: flex; justify-content: space-between; align-items: center; flex-wrap: wrap; gap: 14px; margin-bottom: 20px; }
.admin-nav-tabs { display: flex; gap: 3px; flex-wrap: wrap; background: var(--panel); border: 1px solid var(--border-soft); border-radius: var(--radius-sm); padding: 4px; }
.admin-nav-tabs a { display: flex; align-items: center; gap: 6px; padding: 8px 10px; border-radius: calc(var(--radius-sm) - 2px); font-size: 14px; color: var(--muted); white-space: nowrap; }
.admin-nav-tabs a:hover { color: var(--text); background: var(--panel-2); }
.admin-nav-tabs a.active { background: var(--grad-gold); color: var(--gold-ink); font-weight: 600; }
.admin-nav-tabs a .ic { width: 16px; height: 16px; }

.mail-list { display: flex; flex-direction: column; border: 1px solid var(--border-soft); border-radius: var(--radius); overflow: hidden; }
/* <button> plutôt que <a> (ouvre une fenêtre modale, ne navigue plus) : mêmes resets que les
   autres déclencheurs data-modal-open de l'appli, plus la largeur pleine et l'alignement à
   gauche qu'un <button> n'a pas par défaut. */
.mail-row {
    display: flex; align-items: center; gap: 14px;
    width: 100%;
    padding: 14px 18px 14px 15px;
    border: none; border-bottom: 1px solid var(--border-soft); border-left: 3px solid transparent;
    background: var(--panel);
    color: var(--muted);
    font-size: 14px;
    text-align: left;
    cursor: pointer;
    transition: background .2s ease, border-left-color .15s ease;
}
.mail-row:last-child { border-bottom: none; }
.mail-row:hover { background: var(--panel-2); border-left-color: var(--gold); }
.mail-row.non-lu { background: var(--bg-2); color: var(--text); }
.mail-row.non-lu:hover { background: var(--panel-2); }
.mail-row.non-lu .mail-de, .mail-row.non-lu .mail-objet-ligne strong { color: var(--text); font-weight: 700; }
.mail-row.non-lu .mail-date { color: var(--gold-2); font-weight: 600; }
/* Passage à "lu" (app.js retire .non-lu au clic) : la pastille dorée s'efface en fondu plutôt
   qu'en disparaissant d'un coup (opacity au lieu de visibility, même empreinte de mise en page). */
.mail-unread-dot { width: 8px; height: 8px; border-radius: 50%; background: var(--gold); flex: none; transition: opacity .3s ease; }
.mail-unread-dot.invisible { opacity: 0; }
.mail-avatar { width: 36px; height: 36px; border-radius: 50%; flex: none; object-fit: cover; }
.mail-de { width: 170px; flex: none; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.mail-objet-ligne { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.mail-objet-ligne strong { color: var(--text); font-weight: 600; }
.mail-apercu { color: var(--faint); font-weight: 400; margin-left: 4px; }
.mail-piece { width: 15px; height: 15px; color: var(--faint); flex: none; }
.mail-replied-icon { width: 15px; height: 15px; color: var(--ok); flex: none; }
.mail-reply-icon { width: 15px; height: 15px; color: var(--gold-2); flex: none; }
.mail-date { flex: none; font-size: 12px; color: var(--faint); width: 120px; text-align: right; }
@media (max-width: 700px) { .mail-de { display: none; } }

.mail-thread-note {
    display: flex; align-items: center; gap: 8px;
    font-size: 13px; color: var(--muted);
    background: var(--bg-2); border: 1px solid var(--border-soft); border-radius: var(--radius-sm);
    padding: 8px 12px; margin-bottom: 14px;
}
.mail-thread-note .ic { width: 15px; height: 15px; flex: none; }
.mail-thread-note.replied { color: var(--ok); border-color: rgba(63, 206, 143, .3); }

.mail-detail-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 16px; margin-bottom: 20px; }
.mail-detail-from { display: flex; align-items: center; gap: 12px; }
.mail-detail-from img { width: 40px; height: 40px; border-radius: 50%; }
.mail-attachments { display: flex; flex-direction: column; gap: 8px; margin-top: 24px; padding-top: 20px; border-top: 1px solid var(--border-soft); }
.mail-attachment {
    display: flex; align-items: center; gap: 10px;
    background: var(--bg-2); border: 1px solid var(--border-soft); border-radius: var(--radius-sm);
    padding: 10px 14px; font-size: 13px; color: var(--muted);
}
.mail-attachment:hover { border-color: var(--gold); color: var(--text); }
.mail-attachment .taille { margin-left: auto; color: var(--faint); font-size: 12px; }

/* Sélecteur de destinataires (rédaction de mail) */
.recipient-picker { position: relative; }
/* Source de données du mode "local" (voir data-options en JS) : jamais affichée elle-même,
   seulement lue par app.js. */
.recipient-picker [data-options] { display: none; }
.chips { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 8px; }
.chip {
    display: inline-flex; align-items: center; gap: 6px;
    background: var(--panel-2); border: 1px solid var(--border); border-radius: 999px;
    padding: 5px 6px 5px 12px; font-size: 13px;
}
.chip-remove { background: none; border: none; color: var(--faint); cursor: pointer; font-size: 15px; line-height: 1; padding: 2px 6px; }
.chip-remove:hover { color: var(--danger-2); }
.recipient-suggestions {
    display: none;
    position: absolute; left: 0; right: 0; top: 100%;
    background: var(--panel); border: 1px solid var(--border-soft); border-radius: var(--radius-sm);
    box-shadow: var(--shadow); z-index: 30; max-height: 260px; overflow-y: auto; margin-top: 4px;
}
.recipient-suggestions.open { display: block; }
.recipient-suggestion {
    display: flex; align-items: center; gap: 10px; width: 100%;
    padding: 9px 12px; background: none; border: none; text-align: left; cursor: pointer; color: var(--text);
}
.recipient-suggestion:hover { background: var(--panel-2); }
.recipient-suggestion img { width: 26px; height: 26px; border-radius: 50%; flex: none; }
.recipient-suggestion small { display: block; color: var(--faint); font-size: 12px; }

/* Le bouton natif "Sélect. fichiers" reste blanc/gris quel que soit le CSS appliqué à
   l'input — masqué au profit du <label for> stylé en .btn juste à côté dans le markup. */
.file-input-hidden { position: absolute; width: 1px; height: 1px; opacity: 0; pointer-events: none; }
.attachment-list { display: flex; flex-direction: column; gap: 6px; margin-top: 8px; }
.attachment-chip {
    font-size: 13px; color: var(--muted);
    background: var(--bg-2); border: 1px solid var(--border-soft); border-radius: var(--radius-sm);
    padding: 8px 12px;
}

/* ------------------------------------------------------------------ documents */
.breadcrumb { font-size: 13px; color: var(--muted); margin-bottom: 16px; }
.breadcrumb a { color: var(--muted); }
.breadcrumb a:hover { color: var(--gold-2); }
.breadcrumb .sep { margin: 0 6px; color: var(--faint); }

.mode-picker { display: flex; gap: 10px; flex-wrap: wrap; margin-bottom: 16px; }
.mode-picker label {
    display: flex; align-items: center; gap: 8px;
    background: var(--panel-2); border: 1px solid var(--border); border-radius: var(--radius-sm);
    padding: 10px 14px; font-size: 14px; cursor: pointer;
}
.mode-picker input { accent-color: var(--gold); }

/* Contenu riche (article/document rédigé) : le sanitizer autorise les tableaux et blocs de code
   collés depuis Google Docs — sans ça, un tableau large forcerait le scroll horizontal de toute
   la page sur mobile (display:block permet à overflow-x de s'appliquer sur une <table>). */
.article-body table, .document-body table { display: block; overflow-x: auto; max-width: 100%; }
.article-body pre, .document-body pre { overflow-x: auto; }

#editor { min-height: 320px; background: var(--panel-2); color: var(--text); }
.ql-toolbar.ql-snow { border-color: var(--border); background: var(--panel); border-radius: var(--radius-sm) var(--radius-sm) 0 0; }
.ql-container.ql-snow { border-color: var(--border); border-radius: 0 0 var(--radius-sm) var(--radius-sm); }
.ql-editor { min-height: 320px; }

/* Rendu en lecture du contenu rédigé (pas de dépendance à quill.snow.css ici) — .mail-body et
   .article-body partagent ces règles depuis que mail/articles utilisent aussi l'éditeur Quill. */
.document-body, .mail-body, .article-body { line-height: 1.7; }
.document-body h1, .document-body h2, .document-body h3,
.mail-body h1, .mail-body h2, .mail-body h3,
.article-body h1, .article-body h2, .article-body h3 { margin-top: 1.2em; }
.document-body p, .mail-body p, .article-body p { margin-bottom: 1em; }
.document-body ul, .document-body ol, .mail-body ul, .mail-body ol, .article-body ul, .article-body ol { margin: 0 0 1em 1.4em; }
.document-body a, .mail-body a, .article-body a { color: var(--gold-2); }
.document-body img, .mail-body img, .article-body img { max-width: 100%; border-radius: var(--radius-sm); }
.document-body table, .mail-body table, .article-body table { border-collapse: collapse; width: 100%; margin-bottom: 1em; }
.document-body table td, .document-body table th,
.article-body table td, .article-body table th { border: 1px solid var(--border-soft); padding: 8px 10px; }

.acl-matrice { border: 1px solid var(--border-soft); border-radius: var(--radius); max-height: 520px; overflow-y: auto; }
.acl-matrice.disabled { opacity: .5; }

/* Un département par bloc repliable, ses groupes imbriqués et repliables indépendamment —
   distincts visuellement (icône propre, retrait, taille de police) plutôt que la même ligne
   générique répétée, qui rendait département et groupe difficiles à distinguer d'un coup d'œil. */
.acl-dept { border-bottom: 1px solid var(--border-soft); background: var(--panel); }
.acl-dept:last-child { border-bottom: none; }
.acl-dept-head {
    display: flex; align-items: center; gap: 10px; width: 100%;
    padding: 14px 16px; background: none; border: none; cursor: pointer; text-align: left;
    font-size: 15px; font-weight: 700; color: var(--text);
}
.acl-dept-head:hover { background: var(--panel-2); }
.acl-dept-head .caret { margin-left: auto; font-size: 11px; color: var(--muted); transition: transform .15s ease; flex: none; }
.acl-dept.expanded > .acl-dept-head .caret { transform: rotate(90deg); }
.acl-dept-body { display: none; padding: 0 16px 16px; background: var(--bg-2); }
.acl-dept.expanded > .acl-dept-body { display: block; }
.acl-dept-body > .acl-caps { padding-top: 14px; }

.acl-groupe { margin-top: 12px; padding-left: 16px; border-left: 2px solid var(--border-soft); }
.acl-groupe:first-child { margin-top: 0; }
.acl-groupe-head {
    display: flex; align-items: center; gap: 8px; width: 100%;
    padding: 6px 0; background: none; border: none; cursor: pointer; text-align: left;
    font-size: 13px; font-weight: 600; color: var(--muted);
}
.acl-groupe-head:hover { color: var(--text); }
.acl-groupe-head .caret { margin-left: auto; font-size: 10px; transition: transform .15s ease; flex: none; }
.acl-groupe.expanded > .acl-groupe-head .caret { transform: rotate(90deg); }
.acl-groupe-body { display: none; padding: 8px 0 4px; }
.acl-groupe.expanded > .acl-groupe-body { display: block; }

.acl-caps { display: flex; gap: 8px; flex-wrap: wrap; }

/* Capacité d'accès (Regarder/Modifier/...) en pilule à bascule plutôt qu'une case à cocher
   générique + libellé — se remplit à la sélection, comme les autres bascules de l'app. */
.acl-cap { position: relative; display: inline-flex; }
.acl-cap input { position: absolute; opacity: 0; pointer-events: none; }
.acl-cap span {
    display: inline-flex; align-items: center;
    padding: 6px 12px; border-radius: 999px; border: 1px solid var(--border);
    font-size: 12px; font-weight: 600; color: var(--muted); cursor: pointer; white-space: nowrap;
    transition: background .12s ease, color .12s ease, border-color .12s ease;
}
.acl-cap:hover span { border-color: var(--gold); }
/* Sélecteur de frère général (~), pas adjacent (+) : th:field sur une checkbox liée à une propriété
   booléenne fait insérer par Thymeleaf un input caché juste après elle (valeur "false" par défaut
   si décochée) — avec "+", le span n'est alors plus le frère immédiat et ne réagit jamais à :checked. */
.acl-cap input:checked ~ span { background: var(--grad-gold); border-color: transparent; color: var(--gold-ink); }
.acl-cap input:focus-visible ~ span { box-shadow: 0 0 0 3px rgba(201, 162, 39, .28); }
.acl-cap input:disabled ~ span { opacity: .5; cursor: not-allowed; }

/* Fenêtre modale plus large pour un contenu dense (matrice d'accès). */
.modal-box.wide { max-width: 1040px; }

/* Fiche enquête RCD : infos déclarées à gauche, conclusion à droite, séparées par un filet vertical. */
.enquete-info-conclusion { display: grid; grid-template-columns: 1fr 1fr; gap: 24px; }
.enquete-conclusion-col { padding-left: 24px; border-left: 1px solid var(--border-soft); }
@media (max-width: 780px) {
    .enquete-info-conclusion { grid-template-columns: 1fr; }
    .enquete-conclusion-col { padding-left: 0; border-left: none; padding-top: 16px; border-top: 1px solid var(--border-soft); }
}

/* Miniature "Image de l'annonce" (fiche enquête RCD) : zoom léger au survol pour indiquer qu'elle
   est agrandissable, clic -> lightbox en grand (.lightbox-box, même mécanique modale générique). */
.annonce-image-trigger {
    display: inline-block; padding: 0; border: none; background: none; cursor: zoom-in;
    overflow: hidden; border-radius: var(--radius-sm); line-height: 0;
}
.annonce-image-trigger img { display: block; transition: transform .25s ease; }
.annonce-image-trigger:hover img, .annonce-image-trigger:focus-visible img { transform: scale(1.08); }

.modal-box.lightbox-box {
    max-width: min(94vw, 1300px); padding: 0; background: transparent; border: none;
    box-shadow: none; position: relative;
}
.lightbox-box img {
    width: 100%; height: auto; max-height: 90vh; object-fit: contain;
    border-radius: var(--radius); display: block;
}
/* Les modales de formulaire restent alignées en haut (contenu variable, souvent long) ; une
   lightbox n'a qu'une image, donc plus agréable centrée verticalement dans l'écran. */
.modal-overlay:has(.lightbox-box) { align-items: center; }
.lightbox-box .modal-close {
    position: absolute; top: -18px; right: -18px; z-index: 2;
    width: 38px; height: 38px; display: flex; align-items: center; justify-content: center;
    background: var(--panel); border: 2px solid var(--gold); border-radius: 50%;
    color: var(--text); font-size: 24px; box-shadow: var(--shadow);
}
.lightbox-box .modal-close:hover { background: var(--gold); color: var(--gold-ink); }

/* Pièces jointes (fiche enquête RCD) : grille de miniatures + bouton d'ajout, chacune agrandissable
   en lightbox (même mécanique que .annonce-image-trigger) et supprimable individuellement. */
.pieces-jointes-grid { display: flex; flex-wrap: wrap; gap: 12px; }
.piece-jointe-item { position: relative; width: 140px; height: 100px; }
.piece-image-trigger {
    display: block; width: 100%; height: 100%; padding: 0; border: none; background: none;
    cursor: zoom-in; overflow: hidden; border-radius: var(--radius-sm); line-height: 0;
    border: 1px solid var(--border-soft);
}
.piece-image-trigger img { display: block; width: 100%; height: 100%; object-fit: cover; transition: transform .25s ease; }
.piece-image-trigger:hover img, .piece-image-trigger:focus-visible img { transform: scale(1.08); }

/* Image de couverture d'un article (page publique) : pleine largeur, pas de dimensions fixes comme
   les vignettes ci-dessus — même mécanique de lightbox générique (.lightbox-box), zoom plus léger
   vu la taille déjà grande de l'image. */
.article-image-trigger {
    display: block; width: 100%; padding: 0; border: none; background: none; cursor: zoom-in;
    overflow: hidden; border-radius: var(--radius); line-height: 0; margin-bottom: 24px;
}
.article-image-trigger img { display: block; width: 100%; transition: transform .25s ease; }
.article-image-trigger:hover img, .article-image-trigger:focus-visible img { transform: scale(1.04); }
.piece-jointe-delete {
    position: absolute; top: 6px; right: 6px; z-index: 1; width: 26px; height: 26px;
    display: flex; align-items: center; justify-content: center; border-radius: 50%;
    background: rgba(5, 8, 15, .78); border: 1px solid var(--border-soft); color: var(--muted);
    cursor: pointer; opacity: 0; transition: opacity .15s ease, color .15s ease;
}
.piece-jointe-item:hover .piece-jointe-delete { opacity: 1; }
.piece-jointe-delete:hover { color: var(--danger-2); }
.piece-jointe-delete .ic { width: 14px; height: 14px; }
.piece-jointe-add {
    width: 140px; height: 100px; display: flex; align-items: center; justify-content: center;
    border-radius: var(--radius-sm); border: 1px dashed var(--border); background: none;
    color: var(--muted); cursor: pointer; transition: color .15s ease, border-color .15s ease;
}
.piece-jointe-add:hover { color: var(--gold); border-color: var(--gold); }

/* Constructeur d'options de question de candidature (admin) : une ligne libellé+score par option,
   ajoutée/retirée librement côté client — voir le bloc .candidature-options-builder dans app.js. */
.candidature-options-rows { display: flex; flex-direction: column; gap: 8px; }
.candidature-option-row { display: flex; gap: 8px; align-items: center; }
.candidature-option-row input[type="text"] { flex: 1; margin-bottom: 0; }
.candidature-option-row input[type="number"] { margin-bottom: 0; }
.option-row-remove {
    flex: none; width: 30px; height: 30px; border-radius: 50%; border: 1px solid var(--border-soft);
    background: none; color: var(--muted); cursor: pointer; font-size: 16px; line-height: 1;
    transition: color .15s ease, border-color .15s ease;
}
.option-row-remove:hover { color: var(--danger-2); border-color: var(--danger-2); }

/* Cartes de choix cliquables sur le formulaire public de candidature (CHOIX_UNIQUE/CHOIX_MULTIPLE) —
   remplacent des puces radio/checkbox nues par une carte entière cliquable, dorée à la sélection. */
.candidature-option-card {
    display: block; position: relative; padding: 14px 16px; border-radius: var(--radius-sm);
    border: 1px solid var(--border-soft); cursor: pointer; transition: border-color .15s ease, background .15s ease;
}
.candidature-option-card input { position: absolute; opacity: 0; pointer-events: none; }
.candidature-option-card:hover { border-color: var(--gold); }
.candidature-option-card:has(input:checked) { border-color: var(--gold); background: rgba(201, 162, 39, .1); }

/* Aperçu réduit du rapport d'arrestation (fiche enquête RCD) : le document complet prend beaucoup
   de place affiché en continu dans la colonne Conclusion — une carte compacte cliquable ouvre le
   document en entier dans une fenêtre modale (#modal-rapport-voir), même logique que les miniatures
   de pièces jointes mais pour un document plutôt qu'une image. */
.rapport-preview {
    display: flex; align-items: center; gap: 14px; width: 100%; text-align: left;
    background: #fbfbfa; color: #20242e; border: none; border-top: 4px solid var(--gold);
    border-radius: var(--radius-sm); padding: 12px 16px; cursor: pointer;
    box-shadow: var(--shadow); transition: transform .15s ease;
}
.rapport-preview:hover, .rapport-preview:focus-visible { transform: translateY(-2px); }
.rapport-preview img { width: 38px; height: 38px; object-fit: contain; flex: none; }
.rapport-preview .ic { color: #8891a3; flex: none; }
.rapport-preview-text { display: flex; flex-direction: column; gap: 2px; flex: 1; min-width: 0; }
.rapport-preview-text strong { font-family: var(--font-serif); font-size: 14px; color: #14182a; }
.rapport-preview-text span { font-family: var(--font-sans); font-size: 12px; color: #5c6478; }

/* Rapport d'arrestation (fiche enquête RCD) : rendu volontairement clair/"papier officiel",
   indépendant du thème sombre du reste de l'app — un rapport administratif se lit comme un document
   imprimé, pas comme un panneau du dashboard. */
.rapport-document {
    background: #fbfbfa;
    color: #20242e;
    border-radius: var(--radius);
    padding: 32px 36px;
    box-shadow: var(--shadow);
    font-family: var(--font-serif);
    border-top: 6px solid var(--gold);
}
.rapport-header {
    display: flex; align-items: center; gap: 16px;
    padding-bottom: 18px; margin-bottom: 22px; border-bottom: 2px solid #e4e6ec;
}
.rapport-logo { width: 60px; height: 60px; object-fit: contain; flex: none; }
.rapport-institution { display: flex; flex-direction: column; gap: 2px; }
.rapport-institution strong { font-size: 16px; color: #14182a; }
.rapport-institution span { font-family: var(--font-sans); font-size: 12px; color: #5c6478; }
.rapport-title { font-size: 22px; margin: 0 0 26px; color: #14182a; text-align: center; }
.rapport-grid-2 { display: grid; grid-template-columns: 1fr 1fr; gap: 24px; margin-bottom: 22px; }
@media (max-width: 700px) { .rapport-grid-2 { grid-template-columns: 1fr; } }
.rapport-section { margin-bottom: 22px; }
.rapport-section:last-of-type { margin-bottom: 0; }
.rapport-section h4 {
    font-family: var(--font-sans); font-size: 11px; text-transform: uppercase; letter-spacing: .09em;
    color: #8a6d1f; border-bottom: 1px solid #e4e6ec; padding-bottom: 6px; margin: 0 0 10px;
}
.rapport-section p, .rapport-section ul, .rapport-body {
    font-family: var(--font-sans); font-size: 14px; color: #20242e; margin: 0 0 6px;
}
.rapport-section ul { padding-left: 18px; }
.rapport-body { line-height: 1.7; }
.rapport-body p { margin: 0 0 1em; }
.rapport-table { width: 100%; border-collapse: collapse; font-family: var(--font-sans); font-size: 14px; }
.rapport-table td { padding: 8px 10px; border-bottom: 1px solid #e4e6ec; }
.rapport-table td:last-child { text-align: right; }
.rapport-table tfoot td { font-weight: 600; color: #14182a; border-bottom: none; border-top: 2px solid #e4e6ec; }
.rapport-footer {
    margin-top: 26px; padding-top: 14px; border-top: 1px solid #e4e6ec;
    text-align: center; font-family: var(--font-sans); font-size: 11px; color: #8891a3;
}

/* --------------------------------------------------------------- agenda */
.agenda-grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 6px; }
.agenda-weekday {
    text-align: center; font-size: 11px; text-transform: uppercase; letter-spacing: .06em;
    color: var(--muted); padding-bottom: 6px;
}
.agenda-day {
    min-height: 92px; border: 1px solid var(--border-soft); border-radius: var(--radius-sm);
    padding: 6px; background: var(--panel-2); display: flex; flex-direction: column; gap: 4px;
}
.agenda-day.hors-mois { opacity: .4; }
.agenda-day.aujourdhui { border-color: var(--gold); }
.agenda-day-head { display: flex; justify-content: space-between; align-items: center; }
.agenda-day-head .num { font-size: 12px; color: var(--muted); }
.agenda-day-add {
    width: 18px; height: 18px; border-radius: 50%; border: 1px solid var(--border-soft);
    background: none; color: var(--muted); cursor: pointer; font-size: 13px; line-height: 1;
    display: flex; align-items: center; justify-content: center; opacity: 0;
    transition: opacity .15s ease, color .15s ease, border-color .15s ease;
}
.agenda-day:hover .agenda-day-add { opacity: 1; }
.agenda-day-add:hover { color: var(--gold); border-color: var(--gold); }
.agenda-events { display: flex; flex-direction: column; gap: 3px; overflow: hidden; }
.agenda-event {
    border: none; border-radius: 4px; padding: 2px 6px; font-size: 11px; text-align: left;
    color: #0a0e1a; font-weight: 600; cursor: pointer; white-space: nowrap; overflow: hidden;
    text-overflow: ellipsis;
}

/* Infobulle riche au survol d'un rendez-vous (calendrier + listes "Prochains rendez-vous",
   voir app.js) — un seul élément partagé en position:fixed (pas absolute) : .agenda-event et
   .agenda-events ont volontairement overflow:hidden pour tronquer les titres trop longs, ce qui
   aurait aussi rogné une infobulle en position absolue générée sur ces mêmes éléments. */
.agenda-popover {
    position: fixed; z-index: 300; width: 240px;
    background: var(--panel-2); border: 1px solid var(--border-soft); border-radius: var(--radius);
    box-shadow: var(--shadow); padding: 12px 14px;
    opacity: 0; transform: translateY(-4px); pointer-events: none;
    transition: opacity .12s ease, transform .12s ease;
}
.agenda-popover.visible { opacity: 1; transform: translateY(0); }
.agenda-popover-titre {
    font-family: var(--font-serif); font-weight: 700; font-size: 14px; color: var(--text);
    margin-bottom: 8px; padding-bottom: 8px; border-bottom: 1px solid var(--border-soft);
}
.agenda-popover-row { display: flex; justify-content: space-between; align-items: baseline; gap: 12px; font-size: 12.5px; padding: 3px 0; }
.agenda-popover-row .label { color: var(--muted); flex: none; }
.agenda-popover-row .value { color: var(--text); font-weight: 600; text-align: right; }

/* Picker "Participants" (création/modification de rendez-vous) — mêmes classes chips/suggestions
   que .recipient-picker (Mail/Groupe/Tags) pour l'apparence, mais comportement JS dédié (agenda.js)
   avec 3 filtres natifs Département/Groupe/Grade en plus du texte. */
.agenda-participant-filtres { display: flex; gap: 8px; flex-wrap: wrap; margin-bottom: 8px; }
.agenda-participant-filtres select { max-width: 160px; margin-bottom: 0; }
.agenda-participant-picker { position: relative; }

/* ---------------------------------------------------------------- notes */
.notes-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(230px, 1fr)); gap: 16px; }
.note-card {
    background: var(--panel); border: 1px solid var(--border-soft); border-left: 4px solid var(--gold);
    border-radius: var(--radius); padding: 16px; display: flex; flex-direction: column; gap: 8px;
    cursor: pointer; transition: border-color .15s ease;
}
.note-card:hover { border-color: var(--gold); }
.note-card-head { display: flex; justify-content: space-between; align-items: flex-start; gap: 8px; }
.note-card-head h3 { margin: 0; font-size: 15px; }
.note-pin { flex: none; color: var(--muted); background: none; border: none; cursor: pointer; padding: 2px; }
.note-pin.epinglee { color: var(--gold-2); }
.note-card-apercu { color: var(--muted); font-size: 13px; line-height: 1.5; flex: 1; }
.note-card-date { font-size: 11px; color: var(--faint); }
.note-color-picker { display: flex; gap: 8px; }
.note-color-swatch {
    width: 26px; height: 26px; border-radius: 50%; border: 2px solid transparent; cursor: pointer;
    padding: 0;
}
.note-color-swatch.selected { border-color: #fff; }

/* Widget compact "Bloc-notes" de la Vue d'ensemble — mirror .overview-list-row avec un liseré de
   couleur (comme .note-card) plutôt qu'une icône, deux lignes (titre + aperçu). */
.notes-overview-list { display: flex; flex-direction: column; gap: 8px; }
.notes-overview-row {
    display: flex; flex-direction: column; gap: 2px; padding: 8px 10px;
    border: 1px solid var(--border-soft); border-left: 3px solid var(--gold); border-radius: var(--radius-sm);
    transition: border-color .15s ease;
}
.notes-overview-row:hover { border-color: var(--gold); }
.notes-overview-row .titre { font-size: 13px; font-weight: 600; color: var(--text); }
.notes-overview-row .apercu { font-size: 12px; color: var(--muted); }

/* Widget "Patch notes" de la Vue d'ensemble : même .overview-list/-row que les autres widgets
   compacts, avec un plafond de hauteur + défilement (seul widget de la page à devoir accueillir
   un historique potentiellement long — voir aussi .acces-resume-scroll pour le même traitement
   de barre de défilement personnalisée). */
.overview-list-scroll { max-height: 300px; overflow-y: auto; scrollbar-width: thin; scrollbar-color: var(--border) var(--bg-2); }
.overview-list-scroll::-webkit-scrollbar { width: 8px; }
.overview-list-scroll::-webkit-scrollbar-track { background: var(--bg-2); }
.overview-list-scroll::-webkit-scrollbar-thumb { background: var(--border); border-radius: 999px; }
.overview-list-scroll::-webkit-scrollbar-thumb:hover { background: var(--gold); }

/* Page complète /dashboard/patch-notes : une carte par commit, description multi-lignes préservée
   (white-space: pre-wrap — les messages de commit de ce projet ont souvent plusieurs paragraphes
   ou une liste numérotée). */
.patch-notes-list { display: flex; flex-direction: column; gap: 12px; }
.patch-note-card {
    background: var(--panel); border: 1px solid var(--border-soft); border-left: 3px solid var(--gold);
    border-radius: var(--radius-sm); padding: 14px 18px;
}
.patch-note-head { display: flex; justify-content: space-between; align-items: baseline; flex-wrap: wrap; gap: 8px 16px; }
.patch-note-titre { font-weight: 600; color: var(--text); font-size: 15px; }
.patch-note-meta { display: flex; align-items: center; gap: 14px; flex: none; }
.patch-note-auteur { display: flex; align-items: center; gap: 5px; font-size: 12px; color: var(--gold-2); font-weight: 600; }
.patch-note-auteur .ic { width: 13px; height: 13px; }
.patch-note-date { font-size: 12px; color: var(--faint); white-space: nowrap; }
.patch-note-description { margin: 10px 0 0; font-size: 13px; color: var(--muted); white-space: pre-wrap; line-height: 1.5; }
