/* ============================================================
   Proxima design system — application stylesheet (starter kit)
   Brand accent lives in the --accent* tokens below — change them in ONE place.
   ============================================================ */

:root {
    /* Surfaces */
    --bg-primary:    #f8f9fc;
    --bg-secondary:  #ffffff;
    --bg-tertiary:   #f0f1f5;
    --bg-elevated:   #ffffff;
    --bg-glass:       rgba(0, 0, 0, 0.02);
    --bg-glass-hover: rgba(0, 0, 0, 0.04);
    --bg-primary-rgb: 248, 249, 252;

    /* Text */
    --text-primary:   #1a1a2e;
    --text-secondary: #6b7084;
    --text-muted:     #9ca3b4;

    /* Accent */
    --accent:         #006838;
    --accent-soft:    rgba(0, 104, 56, 0.10);
    --accent-glow:    rgba(0, 104, 56, 0.16);
    --accent-gradient: linear-gradient(135deg, #006838, #0b9b54);

    /* Brouillon — violet. Volontairement distinct du vert d'une approbation : un brouillon
       n'est ni validé ni transmis, la confusion visuelle serait coûteuse. (Norme reprise
       de Chronos.) */
    --draft:      #7c3aed;
    --draft-soft: rgba(124, 58, 237, 0.10);

    /* Borders */
    --border:        rgba(0, 0, 0, 0.08);
    --border-subtle: rgba(0, 0, 0, 0.04);

    /* Scrollbar */
    --scrollbar-thumb:       rgba(0, 0, 0, 0.18);
    --scrollbar-thumb-hover: rgba(0, 0, 0, 0.32);

    /* Radii */
    --radius-sm:   8px;
    --radius-md:  12px;
    --radius-lg:  16px;
    --radius-xl:  24px;
    --radius-full: 9999px;

    /* Shadows */
    --shadow-sm:   0 1px 2px  rgba(0, 0, 0, 0.05);
    --shadow-md:   0 4px 16px rgba(0, 0, 0, 0.06);
    --shadow-lg:   0 8px 32px rgba(0, 0, 0, 0.08);
    --shadow-glow: 0 0 30px var(--accent-glow);

    --transition: 200ms cubic-bezier(0.4, 0, 0.2, 1);

    /* Tokens additionnels utilisés par la zone « Rapports » — couleur de marque (voir --accent). */
    --accent-wash: radial-gradient(120% 100% at 0% 0%, rgba(0, 104, 56, 0.10) 0%, rgba(0, 104, 56, 0.00) 60%);
    --shimmer: linear-gradient(90deg, var(--bg-tertiary) 0%, var(--bg-glass-hover) 50%, var(--bg-tertiary) 100%);
    --status-success: #22c55e;
    --status-warning: #f59e0b;
    --status-danger:  #ef4444;

    /* « Machine au travail » — délibérément NEUTRE. Le vert de marque est réservé à une seule
       chose dans le pilotage Forge : signaler qu'un HUMAIN est requis. Tout ce que les agents
       font seuls se rend en gris, pour que l'œil apprenne la convention sans lire les libellés. */
    --machine:      #8b93a5;
    --machine-soft: rgba(139, 147, 165, 0.12);

    /* Chevron des <select>. En jeton parce qu'une image de fond ne peut pas hériter
       currentColor : la seule façon d'avoir la bonne couleur dans les deux thèmes est
       d'échanger l'image elle-même. */
    --select-chevron: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%236b7084' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E");
}

[data-theme="dark"] {
    --bg-primary:    #0f1419;
    --bg-secondary:  #161b22;
    --bg-tertiary:   #1e242c;
    --bg-elevated:   #1a2028;
    --bg-glass:       rgba(255, 255, 255, 0.03);
    --bg-glass-hover: rgba(255, 255, 255, 0.06);
    --bg-primary-rgb: 15, 20, 25;

    --text-primary:   #e6edf3;
    --text-secondary: #9aa4b1;
    --text-muted:     #6b7280;

    /* Brighten the brand accent on dark backgrounds so text/links stay legible. */
    --accent:      #1c9c5d;
    --accent-glow: rgba(0, 104, 56, 0.32);
    --accent-soft: rgba(28, 156, 93, 0.16);

    /* Violet éclairci pour rester lisible sur fond sombre. */
    --draft:      #a78bfa;
    --draft-soft: rgba(167, 139, 250, 0.16);

    --border:        rgba(255, 255, 255, 0.08);
    --border-subtle: rgba(255, 255, 255, 0.04);

    --scrollbar-thumb:       rgba(255, 255, 255, 0.18);
    --scrollbar-thumb-hover: rgba(255, 255, 255, 0.32);

    --shadow-sm: 0 1px 2px  rgba(0, 0, 0, 0.4);
    --shadow-md: 0 4px 16px rgba(0, 0, 0, 0.45);
    --shadow-lg: 0 8px 32px rgba(0, 0, 0, 0.55);

    --machine:      #79839a;
    --machine-soft: rgba(121, 131, 154, 0.16);

    --select-chevron: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%239aa4b1' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E");

    /* color-scheme: dark fait aussi dessiner à l'OS ses widgets natifs en sombre — c'est ce qui
       empêche la liste déroulante d'un <select> de s'ouvrir en blanc sur un thème sombre. */
    color-scheme: dark;
}

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

html, body {
    height: 100%;
    font-family: 'Inter', -apple-system, BlinkMacSystemFont, system-ui, sans-serif;
    font-size: 15px;
    line-height: 1.6;
    color: var(--text-primary);
    background: var(--bg-primary);
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
}

a { color: inherit; text-decoration: none; }

/* ---- Scrollbars ---- */
* {
    scrollbar-width: thin;
    scrollbar-color: var(--scrollbar-thumb) transparent;
}
*::-webkit-scrollbar          { width: 10px; height: 10px; }
*::-webkit-scrollbar-track    { background: transparent; }
*::-webkit-scrollbar-thumb {
    background: var(--scrollbar-thumb);
    border: 2px solid transparent;
    background-clip: padding-box;
    border-radius: 8px;
    transition: background-color 0.15s ease;
}
*::-webkit-scrollbar-thumb:hover {
    background: var(--scrollbar-thumb-hover);
    background-clip: padding-box;
}
*::-webkit-scrollbar-corner   { background: transparent; }

/* ============================================================
   App shell
   ============================================================ */
.app-shell {
    display: flex;
    flex-direction: column;
    min-height: 100vh;
}

.appbar {
    position: sticky;
    top: 0;
    z-index: 50;
    display: flex;
    align-items: center;
    gap: 16px;
    height: 56px;
    padding: 0 24px;
    background: var(--bg-secondary);
    border-bottom: 1px solid var(--border);
    backdrop-filter: blur(20px);
}
.appbar-leading,
.appbar-trailing { display: flex; align-items: center; gap: 12px; }
.appbar-center   { flex: 1; }

.brand-lockup      { display: inline-flex; align-items: center; gap: 12px; }
.brand-lockup-name { font-weight: 600; font-size: 18px; font-family: inherit; letter-spacing: -0.015em; color: var(--text-primary); }
.app-icon { display: inline-block; flex-shrink: 0; }
.app-icon-md { width: 32px; height: 32px; }

.appbar-badge {
    font-weight: 500; font-size: 9.5px; font-family: inherit;
    color: var(--accent);
    background: var(--accent-soft);
    padding: 2px 8px;
    border-radius: var(--radius-full);
    letter-spacing: 0.06em;
    text-transform: uppercase;
    line-height: 1.6;
}
/* Pastille « Dev » (BadgeEnvironnement.razor) : ambre plutôt que l'accent — l'accent dit
   « c'est la marque », l'ambre dit « attention, pas la production ». Teintes de .tag.warn.
   La pastille « Démo » garde la teinte neutre de .appbar-badge : rien à craindre, c'est fictif. */
.appbar-badge.badge-dev { color: #b45309; background: rgba(245, 158, 11, 0.16); }
[data-theme="dark"] .appbar-badge.badge-dev { color: #fbbf24; }

.status-row {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-weight: 500; font-size: 11px; font-family: inherit;
    letter-spacing: 0.02em;
    color: var(--text-secondary);
}
.status-dot {
    width: 7px;
    height: 7px;
    border-radius: var(--radius-full);
    background: #22c55e;
    box-shadow: 0 0 0 3px rgba(34, 197, 94, 0.18);
}

.btn-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 34px;
    height: 34px;
    background: transparent;
    border: none;
    border-radius: var(--radius-full);
    color: var(--text-secondary);
    cursor: pointer;
    transition: background-color 0.12s ease, color 0.12s ease;
}
.btn-icon:hover { background: var(--bg-glass-hover); color: var(--accent); }

/* ---- Mobile ----
   Sur petit écran, tout débordement horizontal fait « dézoomer » le navigateur, ce qui casse
   toute la mise en page (grilles qui repassent en 2 colonnes, champs coupés). On réduit donc le
   padding de la barre du haut et du contenu pour tout faire tenir dans la largeur de l'écran. */
@media (max-width: 640px) {
    .appbar   { padding: 0 14px; gap: 10px; }
    .app-main { padding: 18px 14px; }
}

.app-main {
    flex: 1 1 auto;
    min-height: 0;
    width: 100%;
    /* Utilise l'essentiel de la largeur de l'écran (≈ 95 % sur écran standard, plafonné sur
       très grand écran) au lieu de l'ancien 1320px qui laissait de larges marges vides. */
    max-width: min(2000px, 95vw);
    margin: 0 auto;
    padding: 28px 28px;
}

/* ---- Footer ---- */
.footer {
    background: var(--bg-secondary);
    border-top: 1px solid var(--border);
    color: var(--text-secondary);
    font-size: 13px;
}
.footer-minimal {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
    padding: 14px 24px;
}
.footer-copy strong { color: var(--text-primary); font-weight: 600; }
.footer-meta { color: var(--text-muted); font-variant-numeric: tabular-nums; }
@media (max-width: 720px) {
    .footer-minimal { flex-direction: column; align-items: flex-start; gap: 6px; }
}

/* ============================================================
   Page
   ============================================================ */
.page { display: flex; flex-direction: column; gap: 20px; }

.page-header {
    display: flex;
    align-items: flex-end;
    justify-content: space-between;
    gap: 16px;
    flex-wrap: wrap;
}
.page-title    { font-weight: 600; font-size: 28px; font-family: inherit; letter-spacing: -0.02em; color: var(--text-primary); }
.page-subtitle { font-size: 13px; color: var(--text-muted); margin-top: 2px; }

/* ---- Search ---- */
.search-field { position: relative; min-width: 280px; }
.search-icon {
    position: absolute;
    left: 12px;
    top: 50%;
    transform: translateY(-50%);
    color: var(--text-muted);
    display: inline-flex;
    pointer-events: none;
}
.input.search-input { padding-left: 36px; }

.input {
    width: 100%;
    padding: 9px 12px;
    background: var(--bg-elevated);
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    color: var(--text-primary);
    /* IMPORTANT : hériter la police du body (Inter). Le raccourci « font: … inherit » est
       invalide et était ignoré → les <input>/<select> tombaient en Arial et les <textarea>
       en monospace. On déclare donc les propriétés séparément. */
    font-family: inherit;
    font-size: 14px;
    line-height: 1.5;
    transition: border-color 0.15s ease, box-shadow 0.15s ease;
}
.input:focus {
    outline: none;
    border-color: var(--accent);
    box-shadow: 0 0 0 3px var(--accent-soft);
}

/* ---- <select> : le navigateur en dessine une partie, comme <input type="file"> ----

   La BOÎTE FERMÉE obéit à .input depuis toujours. Ce qui restait natif, c'est la flèche (que
   le navigateur peint lui-même) et la LISTE OUVERTE (que dessine le système d'exploitation —
   d'où le surlignage bleu de Windows au milieu d'une interface verte).

   La flèche se règle partout : appearance:none la supprime, et on remet la nôtre.
   La liste ouverte, elle, n'est stylable que depuis `appearance: base-select` (Chrome/Edge ;
   Firefox et Safari ne l'ont pas encore). D'où le @supports plus bas : amélioration
   progressive, jamais une condition de bon fonctionnement.

   ⚠️ Ne PAS remplacer <select> par un composant maison. On y perd la navigation au clavier,
   le sélecteur natif du mobile et le support des lecteurs d'écran — trois choses difficiles à
   refaire correctement, pour gagner une bordure. */
select.input {
    appearance: none;
    -webkit-appearance: none;
    padding-right: 34px;                 /* la place de notre chevron */
    background-image: var(--select-chevron);
    background-repeat: no-repeat;
    background-position: right 11px center;
    background-size: 15px 15px;
    cursor: pointer;
}
select.input:disabled {
    cursor: not-allowed;
    opacity: 0.55;
    background-image: none;              /* désactivé : rien à dérouler, pas de chevron */
}

/* Chrome/Edge : la liste déroulante devient un élément de la page, donc enfin la nôtre.
   Partout ailleurs ce bloc est ignoré et la liste native — parfaitement fonctionnelle et
   accessible — reste en place. */
@supports (appearance: base-select) {
    select.input {
        appearance: base-select;
        /* On GARDE notre chevron en image de fond : le glyphe que le navigateur fournit dans
           ce mode est un triangle plein, qui jure avec le reste des icônes (traits fins). */
    }
    select.input::picker-icon { display: none; }

    select.input::picker(select) {
        appearance: base-select;
        margin-top: 4px;
        padding: 4px;
        border: 1px solid var(--border);
        border-radius: var(--radius-sm);
        background: var(--bg-elevated);
        box-shadow: var(--shadow-md);
    }
    select.input option {
        padding: 8px 10px;
        border-radius: 6px;
        font-size: 14px;
        color: var(--text-primary);
    }
    select.input option:hover { background: var(--bg-glass-hover); }
    select.input option:checked { background: var(--accent-soft); color: var(--accent); }
    /* La coche que le navigateur ajoute devant l'option choisie : superflue, on garde la
       couleur d'accent comme seule marque. */
    select.input option::checkmark { display: none; }
}

/* Les grilles resserrent le padding des champs avec le raccourci `padding:` — plus
   spécifique, il écraserait la place réservée au chevron. On la re-réserve pour les
   <select> concernés. */
.data-table td select.input,
.entry-table tbody td select.input { padding-right: 28px; }

/* ============================================================
   Buttons
   ============================================================ */
.btn-primary {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 7px;
    padding: 8px 16px;
    border: none;
    border-radius: var(--radius-sm);
    background: var(--accent-gradient);
    color: #ffffff;
    font: 500 13px/1 'Inter', system-ui, sans-serif;
    cursor: pointer;
    box-shadow: 0 1px 2px rgba(0, 0, 0, 0.08);
    transition: transform 0.15s ease, box-shadow 0.15s ease;
}
.btn-primary:hover  { transform: translateY(-1px); box-shadow: 0 6px 14px var(--accent-glow), 0 2px 4px rgba(0, 0, 0, 0.06); }
.btn-primary:active { transform: translateY(0); }

.btn-secondary {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    white-space: nowrap;
    padding: 8px 16px;
    background: var(--bg-elevated);
    color: var(--text-secondary);
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    font: 500 13px/1 'Inter', system-ui, sans-serif;
    cursor: pointer;
    transition: var(--transition);
}
.btn-secondary:hover { border-color: var(--text-secondary); color: var(--text-primary); }

/* Bouton « brouillon » — même poids visuel que btn-secondary (il ne doit pas concurrencer
   l'action principale), mais teinté violet pour rattacher l'action au brouillon plutôt
   qu'à une validation. (Norme reprise de Chronos.) */
.btn-draft {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    white-space: nowrap;
    padding: 8px 16px;
    background: var(--draft-soft);
    color: var(--draft);
    border: 1px solid var(--draft);
    border-radius: var(--radius-sm);
    font: 500 13px/1 'Inter', system-ui, sans-serif;
    cursor: pointer;
    transition: var(--transition);
}
.btn-draft:hover { background: var(--draft); color: #fff; }
.btn-draft:disabled { opacity: 0.45; cursor: default; background: var(--draft-soft); color: var(--draft); }

/* ============================================================
   List
   ============================================================ */
.list { list-style: none; padding: 0; margin: 0; }
.list-item {
    display: flex;
    align-items: center;
    gap: 16px;
    padding: 16px 18px;
    border-bottom: 1px solid var(--border-subtle);
    transition: background-color 0.12s ease;
}
.list-item:last-child { border-bottom: none; }
.list-item:hover      { background: var(--bg-glass-hover); }
.list-item-body  { flex: 1; min-width: 0; }
.list-item-title {
    font-weight: 600; font-size: 15px; font-family: inherit;
    color: var(--text-primary);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.list-item-sub {
    font-size: 13px;
    color: var(--text-secondary);
    margin-top: 4px;
    line-height: 1.5;
}

.project-item-head {
    display: flex;
    align-items: center;
    gap: 10px;
    margin-bottom: 4px;
}
.project-number {
    font: 600 11px 'JetBrains Mono', 'Fira Code', monospace;
    letter-spacing: 0.04em;
    color: var(--text-muted);
}

/* ============================================================
   Table
   ============================================================ */
.table-scroll {
    background: var(--bg-elevated);
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    overflow: auto;              /* scrolls horizontally and vertically as needed */
    max-height: 640px;
}
.table {
    width: 100%;
    min-width: 720px;            /* keep columns readable; the wrapper scrolls when narrower */
    border-collapse: separate;
    border-spacing: 0;
    font-size: 14px;
    table-layout: fixed;
}
.table thead th {
    position: sticky;            /* header stays put while the rows scroll */
    top: 0;
    z-index: 1;
    background: var(--bg-tertiary);
    text-align: left;
    padding: 11px 14px;
    font-weight: 500;
    font-size: 11px;
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: 0.06em;
    border-bottom: 1px solid var(--border);
    white-space: nowrap;
}
/* Clickable, sortable column headers — styled to read like the header label itself.
   Shared by the projects list (.table) and every detail table (.data-table). */
.table thead th .th-sort,
.data-table thead th .th-sort {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    margin: 0;
    padding: 0;
    background: none;
    border: 0;
    font: inherit;
    letter-spacing: inherit;
    text-transform: inherit;
    color: inherit;
    cursor: pointer;
    user-select: none;
    transition: color 0.15s ease;
}
.table thead th .th-sort:hover,
.data-table thead th .th-sort:hover { color: var(--text-primary); }
.table thead th .th-sort:focus-visible,
.data-table thead th .th-sort:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 2px;
    border-radius: 4px;
}
.table thead th:not([aria-sort="none"]) .th-sort,
.data-table thead th:not([aria-sort="none"]) .th-sort { color: var(--text-primary); }
.sort-arrow {
    font-size: 10px;
    line-height: 1;
    opacity: 0.4;
    transition: opacity 0.15s ease, color 0.15s ease;
}
.sort-arrow.is-active {
    opacity: 1;
    color: var(--accent);
}
.table tbody td {
    padding: 12px 14px;
    color: var(--text-primary);
    border-bottom: 1px solid var(--border);
    vertical-align: middle;
}
.table tbody tr:last-child td { border-bottom: none; }
.table tbody tr:hover         { background: var(--bg-glass-hover); }

/* Column widths — applied to header and body so the two aligned tables match.
   Every column (including Projet, col 2) gets a width so none collapses to 0 when
   the table is narrow; table-layout:fixed then shrinks them proportionally. */
.table th:nth-child(1), .table td:nth-child(1) { width: 130px; }
.table th:nth-child(2), .table td:nth-child(2) { width: 260px; }
.table th:nth-child(3), .table td:nth-child(3) { width: 190px; }
.table th:nth-child(4), .table td:nth-child(4) { width: 160px; }
.table th:nth-child(5), .table td:nth-child(5) { width: 120px; }
.table th:nth-child(6), .table td:nth-child(6) { width: 130px; }

.cell-number {
    font-family: 'JetBrains Mono', 'Fira Code', monospace;
    font-size: 12px;
    letter-spacing: 0.02em;
    color: var(--text-muted);
    white-space: nowrap;
}
.cell-title {
    font-weight: 600;
    color: var(--text-primary);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.cell-sub {
    font-size: 12.5px;
    color: var(--text-secondary);
    margin-top: 2px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.cell-action { text-align: right; white-space: nowrap; }
.btn-row { padding: 6px 12px; }
/* Troncature « … » générique pour les colonnes texte (Contact, Emplacement) afin que
   les valeurs longues n'augmentent pas la hauteur des lignes — la valeur complète reste
   visible au survol via l'attribut title. */
.cell-ellipsis {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* ============================================================
   Pagination
   ============================================================ */
.table-footer {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
    flex-wrap: wrap;
}
.table-footer-info { font-size: 13px; color: var(--text-muted); font-variant-numeric: tabular-nums; }

.pagination { display: inline-flex; align-items: center; gap: 4px; }
.pagination-btn {
    min-width: 32px;
    height: 32px;
    padding: 0 8px;
    background: transparent;
    border: 1px solid transparent;
    border-radius: var(--radius-sm);
    color: var(--text-secondary);
    font-weight: 500;
    font-size: 13px;
    font-variant-numeric: tabular-nums;
    cursor: pointer;
    transition: var(--transition);
    display: inline-flex;
    align-items: center;
    justify-content: center;
}
.pagination-btn:hover:not(:disabled):not(.active) {
    border-color: var(--border);
    color: var(--text-primary);
    background: var(--bg-glass-hover);
}
.pagination-btn.active {
    background: var(--accent);
    border-color: var(--accent);
    color: #ffffff;
    cursor: default;
}
.pagination-btn:disabled { opacity: 0.4; cursor: not-allowed; }
.pagination-ellipsis { color: var(--text-muted); padding: 0 6px; user-select: none; }

/* ============================================================
   Tags
   ============================================================ */
.tag {
    display: inline-block;
    padding: 3px 8px;
    background: var(--accent-soft);
    color: var(--accent);
    font-weight: 600;
    font-size: 10px;
    line-height: 1;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    border-radius: var(--radius-full);
    white-space: nowrap;
}
.tag.tag-success { color: #22c55e; background: rgba(34, 197, 94, 0.14); }
.tag.tag-info    { color: #6b7084; background: var(--bg-tertiary); }
.tag.warn        { color: #b45309; background: rgba(245, 158, 11, 0.16); }
.tag.error       { color: #b91c1c; background: rgba(239, 68, 68, 0.14); }
/* Brouillon — violet : ni validé ni transmis, à ne pas confondre avec un statut approuvé (vert). */
.tag.tag-draft   { color: var(--draft); background: var(--draft-soft); }
[data-theme="dark"] .tag.warn  { color: #fbbf24; }
[data-theme="dark"] .tag.error { color: #f87171; }

/* ── Nuancier de teintes distinctives (norme reprise de Chronos) ────────────
   Huit teintes à attribuer par un condensé stable de la valeur (même catégorie,
   même couleur partout et à chaque démarrage). Elles sont DISTINCTIVES, pas
   sémantiques : contrairement à vert/ambre/rouge ailleurs dans l'app, la teinte
   ne dit rien de bon ou de mauvais — elle sert uniquement à repérer une
   catégorie sans lire chaque ligne.

   ⚠ AUCUN ROUGE dans ce nuancier, et ce n'est pas un choix esthétique : dans le
   reste de l'app le rouge signale une erreur (ligne bloquante, tag `error`,
   suppression). Une catégorie teintée en rouge se lit comme un élément en
   défaut. Rose et corail sont écartés pour la même raison : de loin, ils sont
   du rouge. Toute teinte ajoutée ici doit passer le même test. */
.tag.cat-color-1 { color: #7c3aed; background: rgba(124, 58, 237, 0.14); }  /* violet */
.tag.cat-color-2 { color: #2563eb; background: rgba(37, 99, 235, 0.14); }   /* bleu */
.tag.cat-color-3 { color: #0d9488; background: rgba(13, 148, 136, 0.16); }  /* sarcelle */
.tag.cat-color-4 { color: #a16207; background: rgba(161, 98, 7, 0.16); }    /* ocre */
.tag.cat-color-5 { color: #4338ca; background: rgba(67, 56, 202, 0.14); }   /* indigo */
.tag.cat-color-6 { color: #a21caf; background: rgba(162, 28, 175, 0.13); }  /* magenta */
.tag.cat-color-7 { color: #0369a1; background: rgba(3, 105, 161, 0.14); }   /* cyan */
.tag.cat-color-8 { color: #4d7c0f; background: rgba(77, 124, 15, 0.16); }   /* olive */
/* En thème sombre, seules les teintes de TEXTE sont éclaircies : les fonds translucides
   restent lisibles tels quels sur le fond sombre. */
[data-theme="dark"] .tag.cat-color-1 { color: #c4b5fd; }
[data-theme="dark"] .tag.cat-color-2 { color: #93c5fd; }
[data-theme="dark"] .tag.cat-color-3 { color: #5eead4; }
[data-theme="dark"] .tag.cat-color-4 { color: #fcd34d; }
[data-theme="dark"] .tag.cat-color-5 { color: #a5b4fc; }
[data-theme="dark"] .tag.cat-color-6 { color: #f0abfc; }
[data-theme="dark"] .tag.cat-color-7 { color: #7dd3fc; }
[data-theme="dark"] .tag.cat-color-8 { color: #bef264; }

/* ============================================================
   Cards / details
   ============================================================ */
.card {
    background: var(--bg-secondary);
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    padding: 18px 20px;
}
.detail-description { font-size: 15px; line-height: 1.6; color: var(--text-primary); }

.breadcrumbs {
    display: flex;
    align-items: center;
    gap: 8px;
    font-size: 13px;
    color: var(--text-muted);
}
.breadcrumbs a { color: var(--text-secondary); transition: color 0.12s ease; }
.breadcrumbs a:hover { color: var(--accent); }
.breadcrumbs-sep { color: var(--border); }

.detail-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
    gap: 1px;
    background: var(--border-subtle);
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    overflow: hidden;
}
.detail-field {
    background: var(--bg-secondary);
    padding: 14px 18px;
}
.detail-field dt {
    font-weight: 500; font-size: 11px; font-family: inherit;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    color: var(--text-muted);
    margin-bottom: 4px;
}
.detail-field dd {
    font-weight: 500; font-size: 14px; font-family: inherit;
    color: var(--text-primary);
    /* Les valeurs longues sans espaces (courriel, URL, adresse) se replient dans la
       case au lieu de déborder horizontalement. */
    overflow-wrap: anywhere;
}
.detail-field dd a { color: var(--accent); text-decoration: none; }
.detail-field dd a:hover { text-decoration: underline; }

/* ============================================================
   Empty state
   ============================================================ */
.empty-state {
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
    gap: 8px;
    padding: 48px 24px;
    color: var(--text-secondary);
}
.empty-state-icon {
    width: 72px;
    height: 72px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border-radius: 50%;
    background: var(--accent-soft);
    color: var(--accent);
    margin-bottom: 4px;
}
.empty-state-title { font-weight: 600; font-size: 17px; font-family: inherit; color: var(--text-primary); letter-spacing: -0.01em; }
.empty-state-body  { font-size: 13.5px; line-height: 1.55; max-width: 360px; color: var(--text-muted); margin-bottom: 8px; }

/* ---- Blazor error UI ---- */
#blazor-error-ui {
    display: none;
    position: fixed;
    bottom: 0;
    left: 0;
    right: 0;
    z-index: 1000;
    padding: 12px 24px;
    background: #fef2f2;
    color: #b91c1c;
    border-top: 1px solid rgba(239, 68, 68, 0.3);
    font-size: 13px;
}
#blazor-error-ui .dismiss { cursor: pointer; float: right; }

@media (max-width: 600px) {
    .page-header { flex-direction: column; align-items: stretch; }
    .search-field { min-width: 0; width: 100%; }
    .list-item { flex-direction: column; align-items: stretch; }
}

/* ============================================================
   Project detail — tabs, KPIs, people, data tables
   ============================================================ */
.section-title {
    font-weight: 600; font-size: 16px; font-family: inherit;
    letter-spacing: -0.01em;
    color: var(--text-primary);
    margin: 26px 0 12px;
}

/* ---- Tabs ---- */
.tabs {
    display: flex;
    flex-wrap: wrap;
    gap: 2px;
    border-bottom: 1px solid var(--border);
    /* Espace sous les onglets réduit (au-dessus des barres d'outils) — interface plus compacte. */
    margin: 16px 0 12px;
}
.tab {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    background: none;
    border: 0;
    border-bottom: 2px solid transparent;
    margin-bottom: -1px;
    padding: 10px 14px;
    font-weight: 500; font-size: 14px; font-family: inherit;
    color: var(--text-muted);
    cursor: pointer;
    transition: color 0.15s ease, border-color 0.15s ease;
}
.tab:hover { color: var(--text-primary); }
.tab.is-active { color: var(--accent); border-bottom-color: var(--accent); }
.tab-count {
    font-size: 11px;
    font-weight: 600;
    padding: 1px 7px;
    border-radius: var(--radius-full);
    background: var(--bg-tertiary);
    color: var(--text-muted);
}
.tab.is-active .tab-count { background: var(--accent-soft); color: var(--accent); }

/* ---- KPI cards ---- */
.kpi-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
    gap: 12px;
    margin-bottom: 6px;
}
.kpi-card {
    display: flex;
    flex-direction: column;
    gap: 4px;
    background: var(--bg-secondary);
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    padding: 16px 18px;
}
.kpi-label { font-weight: 500; font-size: 11px; font-family: inherit; letter-spacing: 0.05em; text-transform: uppercase; color: var(--text-muted); }
.kpi-value { font-weight: 600; font-size: 22px; font-family: inherit; letter-spacing: -0.02em; color: var(--text-primary); font-variant-numeric: tabular-nums; }
.kpi-value.neg { color: #dc2626; }
[data-theme="dark"] .kpi-value.neg { color: #f87171; }
.kpi-sub { font-size: 12px; color: var(--text-muted); }

/* ---- People ---- */
.person-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
    gap: 12px;
}
.person-card {
    display: flex;
    flex-direction: column;
    gap: 3px;
    background: var(--bg-secondary);
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    padding: 14px 16px;
}
.person-role { font-weight: 500; font-size: 11px; font-family: inherit; letter-spacing: 0.05em; text-transform: uppercase; color: var(--text-muted); }
.person-name { font-weight: 600; font-size: 15px; font-family: inherit; color: var(--text-primary); margin-bottom: 3px; }
.person-line { font-size: 13px; color: var(--text-secondary); }
a.person-line:hover { color: var(--accent); }
.person-line.muted, .muted { color: var(--text-muted); }

/* ---- Data tables (budget, transactions, orders, reports, rates) ---- */
.data-scroll {
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    overflow: auto;
}
/* Les longues tables utilisent ~toute la hauteur d'écran restante (au lieu d'un plafond fixe à 560px)
   pour voir beaucoup plus de lignes sans rogner l'en-tête de page. Plancher pour les petits écrans. */
.data-scroll.tall { max-height: calc(100vh - 240px); min-height: 360px; }
.data-table {
    width: 100%;
    border-collapse: collapse;
    font-size: 13px;
    white-space: nowrap;
}
.data-table thead th {
    position: sticky;
    top: 0;
    z-index: 1;
    background: var(--bg-tertiary);
    text-align: center;
    padding: 10px 14px;
    font-weight: 600; font-size: 11px; font-family: inherit;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--text-muted);
    border-bottom: 1px solid var(--border);
}
/* Valeurs centrées dans toutes les grilles (les cellules d'action restent à droite).
   (Norme reprise de Chronos.) */
.data-table tbody td {
    padding: 9px 14px;
    color: var(--text-primary);
    border-bottom: 1px solid var(--border);
    vertical-align: middle;
    text-align: center;
}
.data-table td.cell-action { text-align: right; }
.data-table thead th .th-sort { justify-content: center; }
.data-table tbody tr:hover { background: var(--bg-glass-hover); }
.data-table tfoot td {
    position: sticky;
    bottom: 0;
    background: var(--bg-tertiary);
    padding: 10px 14px;
    font-weight: 600;
    color: var(--text-primary);
    border-top: 1px solid var(--border);
    font-variant-numeric: tabular-nums;
    text-align: center;
}
.data-table .num { text-align: center; font-variant-numeric: tabular-nums; }
/* Police des nombres agrandie dans le corps et le pied des grilles (pas dans l'en-tête). */
.data-table td.num { font-size: 15px; font-weight: 600; }
/* Colonne Commentaire : largeur plafonnée + retour à la ligne, pour garder toute la grille
   visible sans défilement horizontal excessif. */
.data-table td.cell-comment {
    max-width: 380px;
    white-space: normal;
    overflow-wrap: anywhere;
}

/* Champs d'édition en ligne dans les grilles (édition directe cellule par cellule). */
.data-table td .input {
    padding: 5px 8px;
    font-size: 13px;
    color: var(--text-primary);
    width: 100%;
    min-width: 0;
}

/* Cellule en cours d'édition : toute la cellule s'illumine (liseré accent + fond doux) pour
   repérer d'un coup d'œil où l'on saisit — le liseré de la cellule fait office de contour. */
.data-table tbody td:has(.input):focus-within,
.entry-table tbody td:has(.input):focus-within {
    background: var(--accent-soft);
    box-shadow: inset 0 0 0 2px var(--accent);
}
/* Le contour est porté par la cellule : on neutralise l'anneau propre du champ dans la grille
   pour éviter un double anneau (le champ garde son bord accent via .input:focus).
   Repli sans :has() → le champ garde simplement son bord accent, sans surbrillance de cellule. */
.data-table td .input:focus,
.entry-table td .input:focus {
    box-shadow: none;
}
/* Commentaire éditable en ligne : zone de texte qui grandit pour montrer TOUT le texte,
   avec retours à la ligne (field-sizing pour l'auto-hauteur sur navigateurs récents). */
.data-table td.cell-comment .cell-comment-input {
    min-width: 300px;
    field-sizing: content;
    min-height: 2.4em;
    max-height: 16em;
    line-height: 1.45;
    resize: vertical;
    white-space: pre-wrap;
    overflow-wrap: anywhere;
    vertical-align: top;
}
.data-table .mono { font-family: 'JetBrains Mono', 'Fira Code', monospace; font-size: 12px; color: var(--text-secondary); }
.data-table .neg { color: #dc2626; }
[data-theme="dark"] .data-table .neg { color: #f87171; }
.data-table td.num.neg, .data-table .kpi-value.neg { color: #dc2626; }
/* économie (Écart positif : Budget ≥ Facturé) — vert */
.data-table .pos { color: #16a34a; }
[data-theme="dark"] .data-table .pos { color: #4ade80; }

/* hour chips inside the labour-report detail cell */
.chip {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    margin: 2px 4px 2px 0;
    padding: 2px 9px;
    border-radius: var(--radius-full);
    background: var(--bg-tertiary);
    font-size: 12px;
    color: var(--text-secondary);
    white-space: nowrap;
}
.chip strong { color: var(--text-primary); font-variant-numeric: tabular-nums; }

/* Document link button in transaction / order tables */
.file-link {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    padding: 4px 10px;
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    background: var(--bg-elevated);
    color: var(--text-secondary);
    font-weight: 500; font-size: 12px; font-family: inherit;
    white-space: nowrap;
    transition: border-color 0.12s ease, color 0.12s ease;
}
.file-link:hover { border-color: var(--accent); color: var(--accent); }
.file-link-empty { color: var(--text-muted); }

/* ---- Onglet Avenant : tableau maître-détail extensible ---- */
/* Bouton « Voir détails » / « Masquer » de chaque ligne parent. */
.btn-link {
    border: none;
    background: none;
    padding: 0;
    font-weight: 500; font-size: 12px; font-family: inherit;
    color: var(--accent);
    cursor: pointer;
    white-space: nowrap;
}
.btn-link:hover { text-decoration: underline; }
/* Ligne d'en-tête des sous-lignes (petite légende). */
.data-table tbody tr.avenant-sub-head td {
    background: var(--bg-tertiary);
    padding-left: 32px;
    font-weight: 600; font-size: 10px; font-family: inherit;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--text-muted);
}
/* Sous-lignes de documents : fond subtil + indentation à gauche pour lire comme du détail imbriqué. */
.data-table tbody tr.avenant-sub td { background: var(--bg-glass); }
.data-table tbody tr.avenant-sub td:first-child { padding-left: 32px; }
.data-table tbody tr.avenant-sub:hover { background: transparent; }

.detail-grid.compact { grid-template-columns: repeat(auto-fill, minmax(180px, 1fr)); margin-bottom: 14px; }
.detail-card + .data-scroll { margin-top: 0; }

/* ---- DataTable: filter row + empty state ---- */
.data-table-wrap { display: flex; flex-direction: column; gap: 12px; }
.table-filter { min-width: 0; width: 100%; max-width: 380px; }
.table-filter .search-input { padding-right: 70px; }
.table-filter-count {
    position: absolute;
    right: 12px;
    top: 50%;
    transform: translateY(-50%);
    font-size: 12px;
    color: var(--text-muted);
    font-variant-numeric: tabular-nums;
    pointer-events: none;
}
.data-table .empty-row { text-align: center; color: var(--text-muted); padding: 22px; }

/* ---- View toggle (Tableau / Graphique) ---- */
.view-toggle {
    display: inline-flex;
    gap: 2px;
    padding: 2px;
    margin-bottom: 14px;
    background: var(--bg-tertiary);
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
}
.view-btn {
    background: none;
    border: 0;
    padding: 6px 16px;
    font-weight: 500; font-size: 13px; font-family: inherit;
    color: var(--text-muted);
    border-radius: calc(var(--radius-md) - 3px);
    cursor: pointer;
    transition: background 0.15s ease, color 0.15s ease;
}
.view-btn:hover { color: var(--text-primary); }
.view-btn.is-active { background: var(--accent); color: #fff; }

/* ---- Budget treemap ---- */
.treemap { display: flex; flex-direction: column; gap: 12px; }
.treemap-crumbs { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; font-size: 13px; }
.treemap-crumb {
    background: none;
    border: 0;
    padding: 2px 4px;
    font-weight: 600; font-size: 13px; font-family: inherit;
    color: var(--text-secondary);
    cursor: pointer;
}
.treemap-crumb:hover { color: var(--accent); }
.treemap-crumb.is-active { color: var(--text-primary); cursor: default; }
.treemap-crumb-sep { color: var(--text-muted); }
.treemap-hint { margin-left: auto; color: var(--text-muted); font-size: 12px; }
.treemap-crumbs { justify-content: space-between; }
.treemap-title { font-weight: 500; font-size: 13px; font-family: inherit; color: var(--text-secondary); }
.treemap-legend { display: flex; gap: 14px; flex-wrap: wrap; }
.legend-item { display: inline-flex; align-items: center; gap: 6px; font-size: 12px; color: var(--text-muted); }
.legend-dot { width: 10px; height: 10px; border-radius: 3px; display: inline-block; }
/* #2 — indicateurs cliquables (boutons de tri) du graphique d'écart au budget. */
.legend-btn { border: 1px solid var(--border, #d7dde3); background: var(--surface, #fff); border-radius: 999px; padding: 3px 10px; cursor: pointer; line-height: 1.4; transition: background .12s, border-color .12s, color .12s; }
.legend-btn:hover { border-color: var(--accent, #0a7a45); color: var(--text-secondary); }
.legend-btn.is-active { border-color: var(--accent, #0a7a45); background: rgba(10, 122, 69, .10); color: var(--text-secondary); font-weight: 600; }

/* #6 — niveau « facture » (2e imbrication) du résumé de contrat : léger retrait + fond plus pâle. */
.suivi-sub-2 > td:first-child { padding-left: 28px; }
.suivi-sub-2 { background: rgba(125, 125, 125, .04); }

/* #4 — édition en ligne de la DP dans le suivi d'heures. */
.dp-edit { display: inline-flex; align-items: center; gap: 4px; }
.dp-input { width: 72px; padding: 2px 6px; text-align: right; }
.dp-edit-btn { margin-left: 6px; opacity: .55; }
.dp-edit-btn:hover { opacity: 1; }

/* ---- Budget bar chart (facturé vs budget, par activité) ---- */
.budget-bars { display: flex; flex-direction: column; gap: 14px; }
.bars-head { display: flex; align-items: center; justify-content: space-between; gap: 16px; flex-wrap: wrap; }
.bars-title { font-weight: 500; font-size: 13px; font-family: inherit; color: var(--text-secondary); max-width: 560px; }
.bars-legend { display: flex; gap: 14px; flex-wrap: wrap; }
.bars-body { display: flex; gap: 14px; align-items: flex-start; }
.bars-list { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 3px; }
.bar-row {
    display: grid;
    grid-template-columns: 220px 1fr 156px;
    align-items: center;
    gap: 14px;
    padding: 5px 8px;
    border-radius: 7px;
    cursor: pointer;
    transition: background 0.12s ease;
}
.bar-row:hover { background: var(--bg-glass-hover); }
.bar-row.is-selected { background: var(--accent-soft); }
.bar-label { min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.bar-code { font-family: 'JetBrains Mono', 'Fira Code', monospace; font-size: 12px; color: var(--text-muted); }
.bar-desc { font-size: 12.5px; color: var(--text-primary); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.bar-track {
    position: relative;
    height: 22px;
    background: var(--bg-tertiary);
    border: 1px solid var(--border);
    border-radius: 5px;
    overflow: hidden;
}
.bar-fill { position: absolute; left: 0; top: 0; height: 100%; border-radius: 4px 0 0 4px; transition: width 0.2s ease; }
.bar-budget-line { position: absolute; left: 50%; top: 0; bottom: 0; width: 2px; background: var(--text-secondary); opacity: 0.7; }
.bar-meta { text-align: right; display: flex; flex-direction: column; gap: 1px; }
.bar-pct { font-weight: 700; font-size: 13px; font-family: inherit; font-variant-numeric: tabular-nums; }
.bar-ecart { font-size: 11.5px; font-variant-numeric: tabular-nums; }
.bar-ecart.over { color: #dc2626; }
.bar-ecart.under { color: var(--text-muted); }
[data-theme="dark"] .bar-ecart.over { color: #f87171; }

/* Detail panel beside the bars — reuses the figures styling, stays in view while scrolling. */
.bars-detail {
    position: sticky;
    top: 12px;
    flex: 0 0 250px;
    background: var(--bg-secondary);
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    padding: 14px 16px;
}

@media (max-width: 760px) {
    .bars-body { flex-direction: column; }
    .bars-detail { position: static; flex-basis: auto; width: 100%; }
    .bar-row { grid-template-columns: 110px 1fr 120px; gap: 8px; }
}

.treemap-body { display: flex; gap: 14px; align-items: flex-start; }
.treemap-svg {
    flex: 1 1 auto;
    width: 100%;
    height: auto;
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    background: var(--bg-secondary);
    overflow: visible;
}
.treemap-tile { cursor: pointer; }
.treemap-tile rect { transition: opacity 0.12s ease; }
.treemap-tile:hover rect { opacity: 0.86; }
.treemap-tile rect.is-selected { stroke: var(--text-primary); stroke-width: 3; }
.treemap-label { font: 600 13px 'Inter', sans-serif; pointer-events: none; }
.treemap-amount { font: 500 12px 'Inter', sans-serif; pointer-events: none; opacity: 0.92; font-variant-numeric: tabular-nums; }
.treemap-dev { font: 700 12px 'Inter', sans-serif; pointer-events: none; }
.treemap-state { font-weight: 600; font-size: 13px; font-family: inherit; margin-bottom: 12px; }

.treemap-detail {
    flex: 0 0 250px;
    background: var(--bg-secondary);
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    padding: 14px 16px;
}
.treemap-detail-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 4px; }
.treemap-detail-close { background: none; border: 0; color: var(--text-muted); cursor: pointer; font-size: 14px; }
.treemap-detail-close:hover { color: var(--text-primary); }
.treemap-detail-title { font-weight: 600; font-size: 14px; font-family: inherit; color: var(--text-primary); margin-bottom: 12px; line-height: 1.4; }
.treemap-figures { display: flex; flex-direction: column; gap: 8px; }
.treemap-figures > div { display: flex; justify-content: space-between; gap: 12px; font-size: 13px; }
.treemap-figures dt { color: var(--text-muted); }
.treemap-figures dd { color: var(--text-primary); font-variant-numeric: tabular-nums; font-weight: 500; }
.treemap-figures dd.neg { color: #dc2626; }
[data-theme="dark"] .treemap-figures dd.neg { color: #f87171; }
.treemap-figures dd.pos { color: #16a34a; }
[data-theme="dark"] .treemap-figures dd.pos { color: #4ade80; }

@media (max-width: 720px) {
    .treemap-body { flex-direction: column; }
    .treemap-detail { flex-basis: auto; width: 100%; }
}

/* ============================================================
   Forms (new project, new rates, new report)
   ============================================================ */
.header-tools { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
.header-actions { display: flex; gap: 10px; align-items: center; }

/* ---- Projects list filter bar ---- */
.filter-bar {
    display: flex;
    align-items: center;
    gap: 18px;
    flex-wrap: wrap;
    margin-bottom: 16px;
}
.filter-check { display: inline-flex; align-items: center; gap: 8px; font-size: 13px; color: var(--text-secondary); cursor: pointer; user-select: none; }
.filter-check input { width: 16px; height: 16px; accent-color: var(--accent); cursor: pointer; }
.filter-years { display: inline-flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.filter-label { font-size: 13px; color: var(--text-muted); }
.chip-toggle {
    padding: 4px 12px;
    border-radius: var(--radius-full);
    border: 1px solid var(--border);
    background: var(--bg-elevated);
    color: var(--text-secondary);
    font-weight: 500; font-size: 12.5px; font-family: inherit;
    cursor: pointer;
    transition: background 0.12s ease, border-color 0.12s ease, color 0.12s ease;
}
.chip-toggle:hover { border-color: var(--accent); color: var(--text-primary); }
.chip-toggle.is-on { background: var(--accent); border-color: var(--accent); color: #fff; }
.chip-more { font-weight: 600; }
.filter-count { margin-left: auto; font-size: 13px; color: var(--text-muted); font-variant-numeric: tabular-nums; }

.tab-toolbar { display: flex; justify-content: flex-end; margin-bottom: 14px; }
.toolbar-locked { font-size: 13px; color: var(--text-muted); display: inline-flex; align-items: center; gap: 6px; }

.form-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
    gap: 14px;
    margin-bottom: 4px;
}
.form-grid.tight { grid-template-columns: repeat(auto-fill, minmax(155px, 1fr)); gap: 10px; }
.form-field { display: flex; flex-direction: column; gap: 5px; }
.form-field.span-2 { grid-column: span 2; }
.form-field label { font-weight: 500; font-size: 12px; font-family: inherit; color: var(--text-secondary); }
.form-field .req { color: #dc2626; }
[data-theme="dark"] .form-field .req { color: #f87171; }

.form-actions {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap: 10px;
    margin-top: 18px;
}
.form-running-total { margin-right: auto; color: var(--text-secondary); font-size: 13px; }
.form-running-total strong { color: var(--text-primary); font-variant-numeric: tabular-nums; }

.form-card { margin-bottom: 18px; }
.form-card-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 14px; }
.form-card-head h3 { font-weight: 600; font-size: 16px; font-family: inherit; color: var(--text-primary); }
.form-card-close { background: none; border: 0; color: var(--text-muted); cursor: pointer; font-size: 15px; }
.form-card-close:hover { color: var(--text-primary); }
.form-subhead { font-weight: 600; font-size: 12px; font-family: inherit; letter-spacing: 0.04em; text-transform: uppercase; color: var(--text-muted); margin: 18px 0 10px; }

.form-banner {
    padding: 11px 14px;
    border-radius: var(--radius-sm);
    font-size: 13.5px;
    margin-bottom: 14px;
}
.form-banner.success { background: var(--accent-soft); color: var(--accent); border: 1px solid var(--accent); }
/* Bandeau lié au brouillon (ex. « élément rappelé ») — violet, surtout pas le vert de succès :
   repasser en brouillon n'est pas une validation. */
.form-banner.draft { background: var(--draft-soft); color: var(--draft); border: 1px solid var(--draft); }
.form-banner.error {
    background: rgba(239, 68, 68, 0.1);
    color: #dc2626;
    border: 1px solid rgba(239, 68, 68, 0.4);
}
[data-theme="dark"] .form-banner.error { color: #f87171; }

.form-hint { color: var(--text-muted); font-size: 13px; margin-bottom: 12px; }

/* ---- Editable budget-entry table (new project) ---- */
.entry-table { width: 100%; border-collapse: collapse; font-size: 13px; }
.entry-table thead th {
    text-align: left;
    padding: 9px 12px;
    font-weight: 600; font-size: 11px; font-family: inherit;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--text-muted);
    background: var(--bg-tertiary);
    border-bottom: 1px solid var(--border);
}
.entry-table thead th.num { text-align: right; }
.entry-table tbody td { padding: 6px 10px; border-bottom: 1px solid var(--border); vertical-align: middle; }
.entry-table tbody td .input { padding: 7px 9px; }
.entry-table .mono-input { font-family: 'JetBrains Mono', 'Fira Code', monospace; }
.entry-table .num-input { text-align: right; font-variant-numeric: tabular-nums; }
.entry-table .empty-row { text-align: center; color: var(--text-muted); padding: 20px; }
.entry-table tfoot td {
    padding: 10px 12px;
    font-weight: 600;
    color: var(--text-primary);
    background: var(--bg-tertiary);
    border-top: 1px solid var(--border);
    font-variant-numeric: tabular-nums;
}
.entry-table tfoot td.num { text-align: right; }
.row-remove {
    background: none;
    border: 0;
    color: var(--text-muted);
    cursor: pointer;
    font-size: 14px;
    padding: 4px 6px;
    border-radius: var(--radius-sm);
}
.row-remove:hover { color: #dc2626; background: var(--bg-glass-hover); }

/* ── Feuille de temps : zone de dépôt + pastilles de statut ─────────────────── */
/* Zone de dépôt de fichier.

   Le <input type="file"> natif dessine SON propre bouton (« Choose File »), carré, gris, et
   dans la langue du navigateur — le navigateur ne laisse pas le styler. On ne le cache pas :
   on l'étale, TRANSPARENT, sur toute la zone. Le clic et le glisser-déposer marchent donc
   partout dans le cadre, le focus clavier reste réel, et ce qui s'affiche est notre bouton.
   Le cacher (display:none, ou 1×1 px) casserait le dépôt par glissement — précisément ce que
   la zone annonce à l'utilisateur. */
.dropzone {
    position: relative;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 4px;
    padding: 32px 24px;
    border: 2px dashed var(--border);
    border-radius: var(--radius-md);
    background: var(--bg-glass);
    color: var(--text-secondary);
    text-align: center;
    cursor: pointer;
    transition: border-color 0.18s ease, background-color 0.18s ease, color 0.18s ease;
}
.dropzone:hover { border-color: var(--text-secondary); background: var(--bg-glass-hover); }

/* focus-within et non :focus : c'est l'input invisible qui reçoit le focus clavier, jamais le
   cadre. Sans ça, tabuler jusqu'à la zone ne montrerait rigoureusement rien. */
.dropzone:focus-within {
    border-color: var(--accent);
    background: var(--accent-soft);
    color: var(--accent);
    outline: none;
}

/* Cette règle DOIT rester globale : l'input est rendu par le composant <InputFile>, donc il
   n'hérite pas de l'attribut de portée du composant parent, et un sélecteur dans un
   *.razor.css ne l'atteindrait pas sans ::deep. C'est aussi ce qui garantit que toutes les
   zones de dépôt de l'app se comportent pareil — il n'y a qu'une mécanique, écrite une fois. */
.dropzone input[type="file"] {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    opacity: 0;
    cursor: pointer;
}
/* Pendant l'analyse d'une capture, l'input est désactivé : le curseur doit le dire, sinon la
   zone a l'air cliquable alors qu'elle ne répond plus. */
.dropzone input[type="file"]:disabled { cursor: progress; }

.dropzone-icon { color: var(--text-muted); margin-bottom: 6px; line-height: 0; }
.dropzone:hover .dropzone-icon,
.dropzone:focus-within .dropzone-icon { color: var(--accent); }
.dropzone-title { font-weight: 600; font-size: 14px; font-family: inherit; color: var(--text-primary); }
.dropzone:focus-within .dropzone-title { color: var(--accent); }
.dropzone-hint { font-size: 12.5px; color: var(--text-muted); }

.pill {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 2px 10px;
    border-radius: var(--radius-full, 999px);
    background: var(--accent-soft);
    color: var(--accent);
    font-weight: 600; font-size: 12px; font-family: inherit;
}
.pill-ok   { background: rgba(34, 197, 94, 0.14);  color: #15803d; }
.pill-warn { background: rgba(234, 179, 8, 0.16);  color: #a16207; }

.clean-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 6px; }
.clean-list-row { display: flex; align-items: center; gap: 10px; font-size: 13.5px; color: var(--text-secondary); }

/* ── Menu de configuration — norme Chronos ─────────────────────────────────
   Une barre latérale GROUPÉE plutôt qu'une rangée d'onglets : les intertitres
   disent à quoi sert chaque écran, et un écran de plus n'aggrave rien. */
.config-layout {
    display: grid;
    grid-template-columns: 232px minmax(0, 1fr);
    gap: 28px;
    align-items: start;
}

.config-nav {
    display: grid;
    gap: 18px;
    position: sticky;
    top: 76px;                      /* 56 px de barre d'app collante + une respiration */
}
.config-nav-group { display: grid; gap: 2px; }
.config-nav-title {
    font-size: 11px;
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--text-muted);
    padding: 0 10px 6px;
}
.config-nav-item {
    appearance: none;
    background: none;
    border: none;
    border-left: 2px solid transparent;
    padding: 8px 12px;
    font: inherit;
    font-weight: 600;
    font-size: 13.5px;
    color: var(--text-secondary);
    text-align: left;
    cursor: pointer;
    border-radius: 0 var(--radius-sm) var(--radius-sm) 0;
    transition: color 0.12s ease, background-color 0.12s ease, border-color 0.12s ease;
}
.config-nav-item:hover { color: var(--text-primary); background: var(--bg-glass-hover); }
.config-nav-item.is-active {
    color: var(--accent);
    border-left-color: var(--accent);
    background: var(--bg-glass-hover);
}

/* La variante « zone de danger » : même géométrie, couleur d'alerte. */
.config-nav-danger { color: var(--status-danger); }
.config-nav-danger:hover { color: var(--status-danger); }
.config-nav-danger.is-active { color: var(--status-danger); border-left-color: var(--status-danger); }

/* Le panneau ne doit jamais pousser la grille : les tableaux larges défilent chez eux. */
.config-panel { min-width: 0; }

/* Sous 900 px la barre repasse au-dessus du contenu, en rangée défilante — mieux
   qu'une colonne de 232 px qui mangerait la moitié d'un écran de portable. */
@media (max-width: 900px) {
    .config-layout { grid-template-columns: minmax(0, 1fr); gap: 18px; }
    .config-nav {
        position: static;
        grid-auto-flow: column;
        grid-auto-columns: max-content;
        gap: 20px;
        overflow-x: auto;
        padding-bottom: 6px;
        border-bottom: 1px solid var(--border);
    }
    .config-nav-group { grid-auto-flow: column; grid-auto-columns: max-content; gap: 4px; align-items: center; }
    .config-nav-title { padding: 0 6px 0 0; }
    .config-nav-item { border-left: none; border-bottom: 2px solid transparent; border-radius: var(--radius-sm); white-space: nowrap; }
    .config-nav-item.is-active { border-left-color: transparent; border-bottom-color: var(--accent); }
    .config-nav-danger.is-active { border-left-color: transparent; border-bottom-color: var(--status-danger); }
}

.config-check { display: flex; align-items: center; gap: 10px; padding: 6px 0; }
.config-check input[type="checkbox"] { width: 16px; height: 16px; accent-color: var(--accent); }
.config-inline { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.config-inline .input { max-width: 140px; }

/* ═══════════════════════════════════════════════════════════════════════════
   USAGERS & ACCÈS — liste des usagers, fiche dans un tiroir (STYLE_GUIDE §5.23),
   confirmation (§5.22), mot de passe révélé une fois, rôles par zone, matrice.
   Le même bloc dans toutes les applications du kit : seuls les jetons changent.
   ═══════════════════════════════════════════════════════════════════════════ */

/* Libellés et textes discrets — bornés aux écrans d'accès, pour ne rien changer ailleurs. */
.acces-ecran .field-label {
    display: block;
    font-size: 12px;
    font-weight: 500;
    color: var(--text-secondary);
    margin-bottom: 6px;
}
.acces-ecran .text-muted { color: var(--text-muted); font-size: 12.5px; }
.acces-ecran .champ + .champ { margin-top: 12px; }
.acces-ecran .actions-ligne { display: flex; flex-wrap: wrap; gap: 6px; }

/* Boutons : la petite taille des lignes de tableau, et le rouge des gestes destructifs. */
.btn-sm { padding: 6px 12px; font-size: 12.5px; }
.btn-primary.btn-danger { background: var(--status-danger); }
.btn-primary.btn-danger:hover { box-shadow: 0 6px 14px rgba(239, 68, 68, 0.3), 0 2px 4px rgba(0, 0, 0, 0.06); }
.btn-secondary.btn-danger { color: var(--status-danger); }
.btn-secondary.btn-danger:hover { border-color: var(--status-danger); color: var(--status-danger); }

/* Pastilles d'état d'un compte (EtatCompte). */
.etat-compte { display: inline-flex; flex-wrap: wrap; gap: 4px; }

/* Modale de confirmation — STYLE_GUIDE §5.22. */
.modal-backdrop {
    position: fixed; inset: 0;
    background: rgba(15, 23, 42, 0.45);
    display: flex;
    align-items: center; justify-content: center;
    z-index: 1000;
    animation: modal-backdrop-in 0.18s ease-out;
}
@keyframes modal-backdrop-in { from { opacity: 0; } to { opacity: 1; } }
.modal-card {
    width: 460px;
    max-width: calc(100vw - 32px);
    background: var(--bg-elevated);
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    padding: 22px 24px 18px;
    box-shadow: 0 24px 60px rgba(0, 0, 0, 0.22), 0 4px 12px rgba(0, 0, 0, 0.08);
    animation: modal-card-in 0.22s cubic-bezier(0.4, 0, 0.2, 1);
}
.modal-card:focus { outline: none; }
@keyframes modal-card-in {
    from { opacity: 0; transform: scale(0.96) translateY(10px); }
    to   { opacity: 1; transform: scale(1) translateY(0); }
}
.modal-title { margin: 0 0 10px; font-weight: 600; font-size: 17px; line-height: 1.3; font-family: inherit; letter-spacing: -0.01em; color: var(--text-primary); }
.modal-body  { margin: 0 0 22px; font-size: 14px; line-height: 1.55; color: var(--text-secondary); }
.modal-actions { display: flex; justify-content: flex-end; gap: 8px; }

/* Tiroir latéral — STYLE_GUIDE §5.23. Pleine largeur sur un téléphone. */
.tiroir-fond {
    position: fixed; inset: 0;
    background: rgba(20, 22, 30, 0.45);
    z-index: 900;
    animation: modal-backdrop-in 0.18s ease-out;
}
.tiroir {
    position: fixed; top: 0; right: 0; bottom: 0;
    width: min(560px, 100vw);
    display: flex; flex-direction: column;
    background: var(--bg-elevated);
    color: var(--text-primary);
    box-shadow: var(--shadow-lg), -12px 0 40px rgba(0, 0, 0, 0.12);
    z-index: 910;
    animation: tiroir-entree 0.28s cubic-bezier(0.4, 0, 0.2, 1);
}
.tiroir:focus { outline: none; }
@keyframes tiroir-entree { from { transform: translateX(100%); } to { transform: translateX(0); } }
.tiroir-tete {
    display: flex; align-items: flex-start; justify-content: space-between; gap: 12px;
    padding: 20px 24px 14px;
    border-bottom: 1px solid var(--border-subtle);
}
.tiroir-titre { margin: 0; font-weight: 600; font-size: 17px; letter-spacing: -0.01em; color: var(--text-primary); }
.tiroir-sous-titre { margin: 4px 0 0; font-size: 13px; color: var(--text-muted); }
.tiroir-fermer {
    border: 0; background: none; cursor: pointer;
    color: var(--text-muted); font-size: 16px; line-height: 1;
    padding: 6px; border-radius: var(--radius-sm);
}
.tiroir-fermer:hover { color: var(--text-primary); background: var(--bg-tertiary); }
.tiroir-corps { flex: 1; overflow-y: auto; padding: 18px 24px; }
.tiroir-pied {
    display: flex; justify-content: flex-end; gap: 8px;
    padding: 14px 24px;
    border-top: 1px solid var(--border-subtle);
}
@media (prefers-reduced-motion: reduce) {
    .tiroir, .tiroir-fond, .modal-card, .modal-backdrop { animation: none; }
}

/* Choix de rôles dans le tiroir : une case, le nom, et ce que le rôle ouvre. */
.choix-role {
    display: flex; gap: 10px; align-items: flex-start;
    padding: 10px 12px;
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-sm);
    cursor: pointer;
}
.choix-role + .choix-role { margin-top: 6px; }
.choix-role:hover { border-color: var(--border); }
.choix-role input { margin-top: 3px; accent-color: var(--accent); }
.choix-role-nom { font-weight: 500; font-size: 13.5px; color: var(--text-primary); }
.choix-role-quoi {
    display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 3; line-clamp: 3; overflow: hidden;
    font-size: 12.5px; color: var(--text-muted);
}

/* Le mot de passe généré, montré une fois (RevelationSecret). */
.revelation-secret { display: flex; flex-direction: column; gap: 8px; align-items: flex-start; scroll-margin-top: 80px; }
.revelation-secret:focus { outline: 2px solid var(--accent); outline-offset: 2px; }
.revelation-tete { display: flex; gap: 8px; align-items: baseline; flex-wrap: wrap; }
.revelation-tete .text-muted { color: var(--text-muted); font-size: 12px; }
.revelation-valeur { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
.revelation-code {
    display: inline-block;
    padding: 6px 10px;
    font-family: 'JetBrains Mono', ui-monospace, monospace;
    font-size: 15px;
    color: var(--text-primary);
    background: var(--bg-elevated);
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    user-select: all;
    overflow-wrap: anywhere;
}
.revelation-consigne { margin: 0; font-size: 12.5px; line-height: 1.5; color: var(--text-secondary); }

/* Les onglets de la configuration sont des LIENS (une adresse par onglet) : même allure que
   les anciens boutons. */
a.config-nav-item { display: block; text-decoration: none; }

/* DataTable : une ligne qui ouvre quelque chose (OnRowClick). */
.data-table tbody tr.ligne-cliquable { cursor: pointer; }
.data-table tbody tr.ligne-selectionnee td { background: var(--accent-soft); }

/* Usagers : l'entête de la liste (titre + « Nouvel usager »), les filtres rapides. */
.entete-liste { display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap; }
.entete-liste .section-titre { margin-bottom: 0; }
.filtres-acces { display: flex; flex-wrap: wrap; gap: 6px; margin: 14px 0 12px; }
.lien-compte { font-size: 13.5px; font-weight: 600; font-family: 'JetBrains Mono', ui-monospace, monospace; }
.lien-registre { display: block; margin-top: 4px; font-size: 12px; color: var(--accent); }

/* La fiche d'un usager, dans le tiroir : quatre sections dans le même ordre partout. */
.fiche-section + .fiche-section { margin-top: 22px; padding-top: 18px; border-top: 1px solid var(--border-subtle); }
.fiche-titre {
    margin: 0 0 10px;
    font-size: 12px; font-weight: 600; letter-spacing: 0.05em; text-transform: uppercase;
    color: var(--text-muted);
}
.fiche-dl { display: grid; grid-template-columns: max-content 1fr; gap: 6px 16px; margin: 0 0 12px; font-size: 13.5px; }
.fiche-dl dt { color: var(--text-muted); }
.fiche-dl dd { margin: 0; color: var(--text-primary); overflow-wrap: anywhere; }
.fiche-dl code { font-family: 'JetBrains Mono', ui-monospace, monospace; font-size: 12.5px; }
.fiche-etat { margin-bottom: 10px; }
.fiche-actions { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 12px; }
.fiche-actions a.btn-secondary { text-decoration: none; }
.champ-ligne { display: flex; gap: 8px; align-items: center; }
.champ-ligne .input { flex: 1; min-width: 0; }
.fiche-historique { list-style: none; margin: 0; padding: 0; display: grid; gap: 8px; font-size: 12.5px; color: var(--text-secondary); }
.fiche-historique li { display: flex; flex-wrap: wrap; gap: 6px; align-items: baseline; }
.fiche-historique .mono { font-family: 'JetBrains Mono', ui-monospace, monospace; font-size: 11.5px; color: var(--text-muted); }
@media (max-width: 480px) {
    .fiche-dl { grid-template-columns: 1fr; gap: 2px; }
    .fiche-dl dd { margin-bottom: 8px; }
}

/* Création : les sortes de compte en cartes cliquables. */
.choix-sorte { display: grid; gap: 8px; }
.choix-sorte-carte {
    display: flex; flex-direction: column; gap: 4px; text-align: left;
    padding: 12px 14px;
    background: var(--bg-elevated);
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    font: inherit; font-size: 13.5px; color: var(--text-primary);
    cursor: pointer;
    transition: border-color 0.12s ease, background-color 0.12s ease;
}
.choix-sorte-carte:hover, .choix-sorte-carte:focus-visible { border-color: var(--accent); background: var(--accent-soft); }
.choix-sorte-carte .text-muted { font-size: 12.5px; }

/* La liste des usagers garde le tableau de l'app (centré, sans retour à la ligne), sauf deux
   colonnes : l'identifiant, qu'on lit à gauche, et dont la description tient en deux lignes ;
   les rôles, qui passent à la ligne plutôt que de pousser l'état hors de l'écran. */
.data-table td.cellule-compte { text-align: left; white-space: normal; min-width: 180px; max-width: 320px; }
.data-table td.cellule-compte .description-compte {
    display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; line-clamp: 2; overflow: hidden;
    font-size: 12.5px;
}
.data-table td.cellule-roles { white-space: normal; max-width: 240px; }
.data-table td.cellule-texte { text-align: left; white-space: normal; min-width: 280px; }

/* Les droits d'un rôle, rangés par zone (ListeDroitsParZone). */
.droits-par-zone { display: grid; gap: 14px; }
.droit-tout { display: flex; gap: 10px; align-items: flex-start; padding: 10px 12px; border: 1px solid var(--status-danger); border-radius: var(--radius-sm); cursor: pointer; }
.zone-droits { border: 1px solid var(--border-subtle); border-radius: var(--radius-sm); padding: 8px 12px 10px; margin: 0; }
.zone-droits legend { padding: 0 6px; font-size: 12px; font-weight: 600; letter-spacing: 0.05em; text-transform: uppercase; color: var(--text-muted); }
.famille-droits + .famille-droits { margin-top: 8px; padding-top: 8px; border-top: 1px dashed var(--border-subtle); }
.famille-entete { display: flex; gap: 8px; align-items: center; font-size: 12.5px; color: var(--text-secondary); margin-bottom: 4px; cursor: pointer; }
.droit { display: flex; gap: 10px; align-items: flex-start; padding: 5px 0 5px 12px; cursor: pointer; font-size: 13px; color: var(--text-primary); }
.droit code, .famille-entete code, .droit-tout code { font-family: 'JetBrains Mono', ui-monospace, monospace; font-size: 12px; }
.droit .tag { margin-left: 4px; }
.droit .text-muted { font-size: 12px; }
.droit-herite { opacity: 0.75; cursor: default; }
.droit input, .famille-entete input, .droit-tout input { margin-top: 3px; accent-color: var(--accent); }

/* ── Fil de retour des sous-pages de « Mon compte » (/compte/mot-de-passe, /compte/double-authentification) ── */
.fil-retour {
    display: inline-block;
    margin-bottom: 6px;
    font-size: 0.8125rem;
    color: var(--accent);
    text-decoration: none;
}
.fil-retour:hover { text-decoration: underline; }

/* La matrice « Accès par rôle » (Configuration → Qui a accès à quoi) : une colonne par rôle.
   Au-delà de la largeur de la feuille, elle défile DANS son cadre au lieu d'élargir la page. */
.acces-defilement { overflow-x: auto; }

/* Usagers : le titre de la liste et « + Nouvel usager » sur une ligne. */
.usagers-tete { display: flex; justify-content: space-between; align-items: flex-start; gap: 12px; flex-wrap: wrap; }
.lien-compte { padding: 0; border: none; background: none; cursor: pointer; text-align: left; }
.lien-compte code { color: var(--accent); }
