﻿/* ============================================================
   Espace privé Port'Ability — extension « moderne »
   ADDITIF : à charger APRÈS app.css.
   Réutilise les tokens existants (--pa-blue, --pa-orange, --border,
   --radius, --ink*, .pill, .quickgrid…). Aucune redéfinition de token.
     <link rel="stylesheet" href="css/app.moderne.css" />  (après app.css)

   SOMMAIRE
     1. Bandeau de synthèse (cartes-filtres) — liste CRA
     2. Montants : zéros atténués (composant Money)
     3. Zébrage + hover + ligne active — QuickGrid
     4. Actions de ligne façon petits boutons (.act)
     5. Sélection multiple + barre groupée   [MASQUÉ — à réactiver]
     6. Drawer de détail (panneau latéral droit)
     7. Fragments partagés (mini-line, detail-meta) — utilisés par le drawer
     8. Édition CRA : largeur élargie + 2 colonnes + tableau contraint + récap
     9. Pastille « Traité »
    10. Responsive + reduced-motion
    11. Relevés mensuels : tuiles, barre de répartition, tableaux débit/crédit
    12. Fiches détaillées client et contrat : bandeau, onglets, définitions
    13. Liste des clients : en-tête de page, recherche, tableau
    14. Incidents : reconnexion au serveur, erreur non rattrapée
   ============================================================ */


/* ---------- 1. Bandeau de synthèse (liste CRA) ---------- */
/* Cartes cliquables servant aussi de filtre d'état.
   flex-direction:column indispensable : un <button> n'empile pas ses
   enfants tout seul. */
.stat-strip {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: .8rem;
    margin: 0 0 1rem;
}

.stat {
    position: relative;
    overflow: hidden;
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: .15rem;
    text-align: left;
    width: 100%;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: .7rem .9rem;
    box-shadow: var(--shadow-1);
    cursor: pointer;
    transition: transform .12s, box-shadow .12s, border-color .12s;
}

    .stat::before {
        content: "";
        position: absolute;
        left: 0;
        top: 0;
        bottom: 0;
        width: 3px;
        background: var(--stat-dot, var(--border));
        opacity: .9;
    }

    .stat:hover {
        transform: translateY(-1px);
        box-shadow: var(--shadow-2);
    }

    .stat.active {
        border-color: var(--stat-dot);
        background: color-mix(in srgb, var(--stat-dot) 6%, var(--surface));
    }

.stat-lbl {
    display: block;
    width: 100%;
    font-size: .72rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: .04em;
    color: var(--ink-3);
}

.stat-row {
    display: flex;
    width: 100%;
    align-items: baseline;
    gap: .5rem;
    margin-top: .25rem;
}

.stat-count {
    font-size: 1.4rem;
    font-weight: 700;
    letter-spacing: -.02em;
    font-variant-numeric: tabular-nums;
}

.stat-sum {
    font-size: .8rem;
    color: var(--ink-3);
    font-variant-numeric: tabular-nums;
}

.stat[data-tone="all"] {
    --stat-dot: var(--pa-orange);
}

.stat[data-tone="prep"] {
    --stat-dot: var(--ink-3);
}

.stat[data-tone="sent"] {
    --stat-dot: var(--pa-blue);
}

.stat[data-tone="done"] {
    --stat-dot: var(--ok);
}


/* ---------- 2. Montants : zéros atténués ---------- */
.num .zero, td.num.zero {
    color: var(--ink-3);
}


/* ---------- 3. Zébrage + hover + ligne active (QuickGrid) ---------- */
/* Fond posé sur les td. Ordre imposé (spécificité égale → la dernière
   règle gagne) : nth-child, puis hover, puis row-active. */
table.quickgrid tbody tr:nth-child(even) td {
    background: #fafbfd;
}

table.quickgrid tbody tr:hover td {
    background: var(--pa-blue-soft);
}

table.quickgrid tbody tr.row-active td {
    background: var(--pa-blue-soft);
}


/* ---------- 4. Actions de ligne façon petits boutons ---------- */
.row-acts {
    display: flex;
    gap: .4rem;
    justify-content: flex-end;
    align-items: center;
}

    .row-acts .act {
        display: inline-flex;
        align-items: center;
        line-height: 1.3;
        padding: .26rem .6rem;
        border-radius: var(--radius-s);
        border: 1px solid var(--border);
        background: var(--surface);
        color: var(--ink-2);
        font-size: .82rem;
        font-weight: 600;
        text-decoration: none;
        cursor: pointer;
        transition: border-color .12s, color .12s, background .12s;
    }

        .row-acts .act:hover {
            border-color: var(--pa-blue);
            color: var(--pa-blue-dark);
            background: var(--pa-blue-soft);
            text-decoration: none;
        }
    /* Action principale (Modifier / Ouvrir) légèrement accentuée */
    .row-acts .act-primary {
        color: var(--pa-blue-dark);
        border-color: #bcd6f2;
    }


/* ---------- 5. Sélection multiple + barre groupée ----------
   MASQUÉ pour l'instant (colonne .col-select et .bulk-bar commentées
   dans List.razor). À réactiver avec l'endpoint d'export PDF groupé. */
.col-select {
    width: 2.2rem;
    text-align: center;
}

tr.selected td {
    background: var(--pa-blue-soft) !important;
}

.bulk-bar {
    position: fixed;
    left: 50%;
    bottom: -80px;
    transform: translateX(-50%);
    z-index: 40;
    display: flex;
    align-items: center;
    gap: 1rem;
    padding: .6rem .8rem .6rem 1.2rem;
    color: #fff;
    background: var(--ink);
    border-radius: 12px;
    box-shadow: var(--shadow-2);
    white-space: nowrap;
    transition: bottom .25s ease;
}

    .bulk-bar.show {
        bottom: 1.5rem;
    }

    .bulk-bar .bk-count {
        font-weight: 600;
        font-variant-numeric: tabular-nums;
    }

        .bulk-bar .bk-count b {
            color: var(--pa-orange);
        }

    .bulk-bar .sep {
        width: 1px;
        height: 1.3rem;
        background: rgba(255,255,255,.25);
    }

    .bulk-bar button {
        color: inherit;
        background: none;
        border: none;
        cursor: pointer;
        font: inherit;
        font-weight: 500;
        padding: .35rem .6rem;
        border-radius: 6px;
    }

        .bulk-bar button:hover {
            background: rgba(255,255,255,.15);
        }


/* ---------- 6. Drawer de détail (panneau latéral droit) ---------- */
.drawer-backdrop {
    position: fixed;
    inset: 0;
    z-index: 45;
    background: rgba(16, 24, 40, .35);
    animation: pa-fade .18s ease;
}

@keyframes pa-fade {
    from {
        opacity: 0;
    }

    to {
        opacity: 1;
    }
}

.drawer {
    position: fixed;
    top: 0;
    right: 0;
    bottom: 0;
    z-index: 46;
    width: 440px;
    max-width: 92vw;
    background: var(--surface);
    border-left: 1px solid var(--border);
    box-shadow: var(--shadow-2);
    display: flex;
    flex-direction: column;
    animation: pa-slide .22s ease;
}

@keyframes pa-slide {
    from {
        transform: translateX(100%);
    }

    to {
        transform: none;
    }
}

.drawer-head {
    display: flex;
    align-items: flex-start;
    gap: 1rem;
    padding: 1.1rem 1.3rem;
    border-bottom: 1px solid var(--border);
}

.drawer-ref {
    font-family: ui-monospace, monospace;
    font-size: .8rem;
    color: var(--ink-3);
}

.drawer-head h2 {
    margin: .25rem 0 0;
    font-size: 1.05rem;
}

.drawer-close {
    margin-left: auto;
    background: none;
    border: none;
    cursor: pointer;
    font-size: 1.05rem;
    color: var(--ink-3);
    width: 2rem;
    height: 2rem;
    border-radius: var(--radius-s);
    flex-shrink: 0;
}

    .drawer-close:hover {
        background: var(--bg);
        color: var(--ink);
    }

.drawer-body {
    flex: 1;
    overflow-y: auto;
    padding: 1.1rem 1.3rem;
}

.drawer-section {
    margin-bottom: 1.4rem;
}

    .drawer-section:last-child {
        margin-bottom: 0;
    }

    .drawer-section h4 {
        margin: 0 0 .5rem;
        font-size: .7rem;
        text-transform: uppercase;
        letter-spacing: .05em;
        color: var(--ink-3);
    }

.drawer-foot {
    padding: 1rem 1.3rem;
    border-top: 1px solid var(--border);
    background: #f8fafd;
    display: flex;
    gap: .6rem;
}

    .drawer-foot > * {
        flex: 1;
        text-align: center;
    }


/* ---------- 7. Fragments partagés (utilisés par le drawer) ---------- */
.mini-line {
    display: flex;
    justify-content: space-between;
    padding: .3rem 0;
    border-bottom: 1px dashed var(--border);
    font-size: .88rem;
}

    .mini-line:last-child {
        border-bottom: none;
    }

    .mini-line.total {
        font-weight: 650;
        border-top: 1px solid var(--border);
        border-bottom: none;
        margin-top: .2rem;
    }

.detail-meta {
    display: flex;
    flex-direction: column;
    gap: .35rem;
    font-size: .88rem;
}

    .detail-meta .m {
        display: flex;
        gap: .5rem;
        align-items: baseline;
    }

        .detail-meta .m .k {
            color: var(--ink-3);
            width: 5rem;
            flex-shrink: 0;
        }


/* ---------- 8. Édition CRA : élargie + 2 colonnes + tableau contraint ---------- */
/* Le plafond de largeur qui était ici n'a plus lieu d'être : .content n'est
   plus borné dans app.css et prend toute la place à droite du menu. Le laisser
   aurait fait de l'écran d'édition le SEUL écran plafonné, à l'envers de son
   intention d'origine. */
.edit-layout {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 320px;
    gap: 1.4rem;
    align-items: start;
    min-width: 0;
}

.edit-main {
    min-width: 0;
    display: flex;
    flex-direction: column;
}

    /* --- Tableau des prestations : contraint pour tenir DANS sa colonne ---
   table-layout:fixed est la clé : sans lui, le navigateur élargit le
   tableau selon son contenu (débordement sous le récap). Avec, les
   colonnes respectent les % ci-dessous et les inputs se compriment.
   7 colonnes : N° / Libellé / Unité / Nombre / Prix unit. / Montant HT / actions */
    .edit-main .panel {
        overflow-x: visible;
    }
    /* annule tout overflow hérité */
    .edit-main table.tbl {
        table-layout: fixed;
        width: 100%;
    }

        .edit-main table.tbl th, .edit-main table.tbl td {
            overflow: hidden;
            text-overflow: ellipsis;
        }

        .edit-main table.tbl input, .edit-main table.tbl select {
            width: 100%;
            min-width: 0;
        }

        /* 3 % tronquait « N° » en « N.. » ; 13 % d'actions tronquait « Suppr. »
           (largeurs revues : 5/26/14/12/14/13 + 16 % d'actions = 100). */
        .edit-main table.tbl th:nth-child(1), .edit-main table.tbl td:nth-child(1) {
            width: 5%;
        }

        .edit-main table.tbl th:nth-child(2), .edit-main table.tbl td:nth-child(2) {
            width: 26%;
        }

        .edit-main table.tbl th:nth-child(3), .edit-main table.tbl td:nth-child(3) {
            width: 14%;
        }

        .edit-main table.tbl th:nth-child(4), .edit-main table.tbl td:nth-child(4) {
            width: 12%;
        }

        .edit-main table.tbl th:nth-child(5), .edit-main table.tbl td:nth-child(5) {
            width: 14%;
        }

        .edit-main table.tbl th:nth-child(6), .edit-main table.tbl td:nth-child(6) {
            width: 14%;
        }

        .edit-main table.tbl th:nth-child(7), .edit-main table.tbl td:nth-child(7) {
            width: 13%;
        }

.recap {
    position: sticky;
    top: 4.5rem;
    display: flex;
    flex-direction: column;
    gap: 1rem;
}

.recap-card {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    box-shadow: var(--shadow-1);
    overflow: hidden;
}

.recap-head {
    padding: 1rem 1.15rem 0;
}

    .recap-head .r-title {
        font-size: 1rem;
        font-weight: 650;
    }

    .recap-head .r-sub {
        font-size: .8rem;
        color: var(--ink-3);
        margin-top: .1rem;
    }

.recap-lines {
    padding: .8rem 1.15rem;
}

.r-line {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    padding: .35rem 0;
    font-size: .92rem;
}

    .r-line .rl {
        color: var(--ink-2);
    }

    .r-line .rv {
        font-variant-numeric: tabular-nums;
        font-weight: 600;
    }

.r-ttc {
    margin-top: .3rem;
    padding-top: .6rem;
    border-top: 1px solid var(--border);
}

    .r-ttc .rl {
        font-weight: 650;
        color: var(--ink);
        font-size: .98rem;
    }

    .r-ttc .rv {
        font-size: 1.35rem;
        font-weight: 750;
        letter-spacing: -.02em;
        color: var(--pa-orange-dark);
    }

.recap-actions {
    padding: 1rem 1.15rem;
    background: #f8fafd;
    border-top: 1px solid var(--border);
    display: flex;
    flex-direction: column;
    gap: .5rem;
}

    .recap-actions .btn-primary, .recap-actions .btn-secondary {
        width: 100%;
        text-align: center;
    }

    .recap-actions .row2 {
        display: flex;
        gap: .5rem;
    }

        .recap-actions .row2 > * {
            flex: 1;
        }

/* Check-list de complétude */
.checklist {
    padding: .8rem 1.15rem;
}

.check-item {
    display: flex;
    align-items: center;
    gap: .6rem;
    padding: .3rem 0;
    font-size: .88rem;
    color: var(--ink-2);
}

.check-dot {
    width: 18px;
    height: 18px;
    border-radius: 50%;
    border: 1.5px solid var(--border);
    flex-shrink: 0;
    position: relative;
    transition: .15s;
}

.check-item.ok .check-dot {
    background: var(--ok);
    border-color: var(--ok);
}

    .check-item.ok .check-dot::after {
        content: "";
        position: absolute;
        left: 5.5px;
        top: 2px;
        width: 4px;
        height: 8px;
        border: solid #fff;
        border-width: 0 1.5px 1.5px 0;
        transform: rotate(45deg);
    }

.check-item.ok {
    color: var(--ink-3);
}

/* Interrupteur d'envoi (remplace la checkbox brute) */
.switch-row {
    display: flex;
    align-items: center;
    gap: .7rem;
    cursor: pointer;
    font-weight: 500;
    color: var(--ink);
}

.switch {
    width: 38px;
    height: 22px;
    border-radius: 11px;
    background: var(--border);
    position: relative;
    transition: .18s;
    flex-shrink: 0;
}

    .switch::after {
        content: "";
        position: absolute;
        top: 2px;
        left: 2px;
        width: 18px;
        height: 18px;
        border-radius: 50%;
        background: #fff;
        box-shadow: 0 1px 2px rgba(0,0,0,.3);
        transition: .18s;
    }

.switch-row.on .switch {
    background: var(--pa-orange);
}

    .switch-row.on .switch::after {
        transform: translateX(16px);
    }

/* Champs d'envoi sous l'interrupteur : rendus seulement quand l'envoi client est
   coché (le bloc entier disparaît sinon, cf. Cra/Edit.razor). */
.send-fields {
    margin-top: 1rem;
}


/* Lien « + Ajouter une prestation » sous la grille (cf. maquette). */
.add-line {
    display: inline-flex; align-items: center; gap: .3rem;
    margin-top: .55rem; text-decoration: none; font-weight: 600;
}
.add-line:hover { text-decoration: underline; }
.add-line:disabled { opacity: .5; cursor: default; }

/* ---------- 9. Pastille « Traité » (vert) ---------- */
/* Complète tes .pill existantes (pill-neutral, pill-blue…). */
.pill-done {
    background: #e8f5e9;
    color: var(--ok);
    border-color: #b7dfc0;
}


/* ---------- 10. Responsive + reduced-motion ---------- */
@media (max-width: 1300px) {
    /* Sous 1300px : récap sous le formulaire, pleine largeur */
    .edit-layout {
        grid-template-columns: 1fr;
    }

    .recap {
        position: static;
    }
}

@media (max-width: 1100px) {
    .stat-strip {
        grid-template-columns: 1fr 1fr;
    }
}

@media (max-width: 800px) {
    .stat-strip {
        grid-template-columns: 1fr;
    }

    .drawer {
        width: 100%;
    }

    .row-acts {
        flex-wrap: wrap;
    }
}

@media (prefers-reduced-motion: reduce) {
    .stat, .bulk-bar, .switch, .switch::after,
    .drawer, .drawer-backdrop {
        transition: none !important;
        animation: none !important;
    }
}


/* ============================================================
   11. Relevés mensuels — page /releves
   ------------------------------------------------------------
   Le relevé reste le document comptable en débit/crédit ; ce bloc
   ajoute par-dessus les trois choses qui manquaient : les chiffres
   qu'on vient chercher (tuiles), leur proportion (barre), et un
   tableau qui ne noie plus quatre lignes utiles dans quinze.
   ============================================================ */

/* Tokens AJOUTÉS, aucun redéfini : gris de tableau, vert de réussite. */
:root {
    --row-alt: #fafbfd;
    --row-hover: #f2f6fb;
    --row-line: #eef1f6;
    --text-zero: var(--ink-3);
    --ok-bg: #e9f5ec;
    --ok-fg: #1e7e34;
}

/* Réservé aux lecteurs d'écran : légendes de tableau, état de chargement. */
.sr-only {
    position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
    overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/* ---------- 11.1 En-tête + sélecteur de période ---------- */
.rv-head {
    display: flex; align-items: flex-end; justify-content: space-between;
    gap: 1rem; flex-wrap: wrap; margin-bottom: 1.1rem;
}
.rv-head h1 { margin-bottom: .1rem; }
.rv-sub { margin: 0; color: var(--ink-2); font-size: .95rem; text-transform: capitalize; }

.mp { display: flex; align-items: flex-end; gap: .5rem; flex-wrap: wrap; }
.mp-champ { display: flex; flex-direction: column; gap: .2rem; }
.mp-lib {
    font-size: .72rem; font-weight: 600; letter-spacing: .3px;
    text-transform: uppercase; color: var(--ink-3);
}
.mp-champ select {
    padding: .4rem .55rem; border: 1px solid var(--border); border-radius: var(--radius-s);
    background: var(--surface); color: var(--ink); font-family: inherit; font-size: .92rem;
}
.mp-champ select:focus-visible { outline: 2px solid var(--pa-blue); outline-offset: 1px; }
.mp-fleche {
    display: inline-flex; align-items: center; justify-content: center;
    width: 2.1rem; height: 2.1rem; border: 1px solid var(--border);
    border-radius: var(--radius-s); background: var(--surface);
    color: var(--pa-blue); font-size: 1.25rem; line-height: 1; text-decoration: none;
}
.mp-fleche:hover { border-color: var(--pa-blue); background: var(--pa-blue); color: #fff; }
/* Pas de mois de ce côté : on garde la place, sans laisser croire qu'on peut cliquer. */
.mp-fleche.off { opacity: .35; pointer-events: none; }
.mp-note { align-self: center; font-size: .82rem; color: var(--pa-orange-dark); }

/* ---------- 11.2 Cartes et états ---------- */
.rv-carte { margin-bottom: 1rem; }
.rv-carte > h2 { margin-top: 0; }
.rv-etat { text-align: center; padding: 2rem 1rem; }
.rv-etat h2 { margin-top: 0; }
.rv-etat-ko { text-align: left; border-left: 3px solid var(--danger); }
.rv-etat-ko h2 { color: var(--danger); }

/* ---------- 11.3 Tuiles ---------- */
.tiles { display: grid; grid-template-columns: repeat(auto-fit, minmax(170px, 1fr)); gap: .7rem; }
.tile {
    display: flex; flex-direction: column; gap: .15rem;
    padding: .7rem .85rem; background: var(--surface);
    border: 1px solid var(--border); border-left: 3px solid var(--ink-3);
    border-radius: var(--radius-s);
}
.tile-lib {
    font-size: .72rem; font-weight: 600; letter-spacing: .3px;
    text-transform: uppercase; color: var(--ink-2);
}
.tile-val { font-size: 1.22rem; font-weight: 600; font-variant-numeric: tabular-nums; }
.tile-val .zero { color: var(--text-zero); }
.tile-note { font-size: .76rem; color: var(--ink-3); }
.tile-entree { border-left-color: var(--pa-blue); }
.tile-sortie { border-left-color: var(--pa-orange); }
.tile-fort { border-left-color: var(--ok); background: var(--ok-bg); }
.tile-fort .tile-val { color: var(--ok-fg); }

/* ---------- 11.4 Barre de répartition ---------- */
.sbar { display: flex; height: 14px; border-radius: 999px; overflow: hidden; background: var(--row-line); }
.sbar-part { display: block; min-width: 2px; }
.sbar-leg { list-style: none; margin: .7rem 0 0; padding: 0; display: grid; gap: .3rem; }
.sbar-leg li {
    display: grid; grid-template-columns: 10px 1fr auto auto;
    align-items: center; gap: .5rem; font-size: .88rem;
}
.sbar-puce { width: 10px; height: 10px; border-radius: 3px; }
.sbar-pct { color: var(--ink-3); font-variant-numeric: tabular-nums; }
.sbar-val { min-width: 6.5rem; text-align: right; font-variant-numeric: tabular-nums; }
.sbar-c0 { background: var(--pa-blue); }
.sbar-c1 { background: var(--pa-orange); }
.sbar-c2 { background: var(--pa-blue-dark); }
.sbar-c3 { background: var(--ok); }
.sbar-c4 { background: var(--ink-3); }
.sbar-c5 { background: var(--pa-orange-dark); }

/* ---------- 11.5 Tableaux du relevé ---------- */
.rv-cols {
    display: grid; grid-template-columns: repeat(auto-fit, minmax(340px, 1fr));
    gap: 1.4rem; margin-top: .9rem;
}
.rv-cols h3 { margin: 0 0 .5rem; font-size: .95rem; }
.tbl.ledger thead th {
    background: #f2f6fb; color: var(--ink-2);
    text-transform: none; font-size: .85rem; letter-spacing: 0;
}
/* Le libellé est un en-tête de ligne (accessibilité) mais se lit comme une cellule. */
.tbl.ledger th[scope="row"] {
    background: transparent; color: var(--ink); font-weight: 400;
    font-size: inherit; text-transform: none; letter-spacing: 0; text-align: left;
}
.tbl.ledger tbody tr:nth-child(even) { background: var(--row-alt); }
.tbl.ledger tbody tr:hover { background: var(--row-hover); }
.tbl.ledger th, .tbl.ledger td { border-bottom: 1px solid var(--row-line); }
.tbl.ledger .num { width: 7.5rem; }
.tbl.ledger .ledger-solde { background: var(--pa-blue-soft) !important; }
.tbl.ledger .ledger-solde th, .tbl.ledger .ledger-solde td {
    font-weight: 600; color: var(--pa-blue-dark); border-bottom: 0;
}
.tbl.ledger .ledger-solde .zero { color: inherit; }
.ledger-note { margin: .45rem 0 0; font-size: .8rem; color: var(--ink-3); }

/* ---------- 11.5bis Lignes alternées, pour les listes qui se parcourent ----------
   .tbl seul se lit bien sur trois ou quatre lignes — les tableaux de fiche. Dès
   qu'une liste s'allonge, ou qu'une cellule enroule sur plusieurs lignes, l'œil
   perd la ligne en traversant : c'est le cas de la bibliothèque documentaire, dont
   les intitulés montent à 305 caractères. On reprend la mécanique déjà éprouvée
   sur .tbl.ledger, en modificateur réutilisable plutôt qu'en propriété de .tbl —
   les tableaux courts n'ont pas à devenir rayés.

   Trois gestes, et le troisième compte autant que la rayure :
     • une ligne sur deux teintée, et le survol par-dessus ;
     • des séparateurs plus clairs, la rayure portant déjà la séparation ;
     • l'alignement en haut — sans lui, un intitulé sur quatre lignes laisse la
       date et les liens flotter au milieu d'une cellule haute, et la ligne ne se
       lit plus de gauche à droite. */
.tbl.zebra tbody tr:nth-child(even) { background: var(--row-alt); }
.tbl.zebra tbody tr:hover { background: var(--row-hover); }
.tbl.zebra th, .tbl.zebra td { border-bottom: 1px solid var(--row-line); }
.tbl.zebra thead th { border-bottom: 1px solid var(--border); }
.tbl.zebra td { padding: .6rem .7rem; vertical-align: top; line-height: 1.45; }

/* Longueur de ligne : au-delà d'une soixantaine de caractères, l'œil ne retrouve
   plus le début de la ligne suivante. La contrainte porte sur un élément interne,
   une cellule de tableau n'honorant pas max-width de façon fiable. */
.tbl.zebra .mesure { display: inline-block; max-width: 62ch; }

/* Deux liens libellés tiennent rarement côte à côte dans une colonne d'actions :
   qu'ils passent à la ligne plutôt que de déborder. */
.tbl.zebra .row-acts { flex-wrap: wrap; row-gap: .3rem; }
.tbl.zebra td.date { white-space: nowrap; color: var(--ink-2); }

/* ---------- 11.6 Squelette de chargement ---------- */
.rv-skel { display: grid; gap: 1rem; }
.skel {
    border-radius: var(--radius); background-size: 400% 100%;
    background: linear-gradient(90deg, #eef1f6 25%, #f6f8fb 37%, #eef1f6 63%);
    animation: skel 1.2s ease-in-out infinite;
}
.skel-tuiles { height: 92px; }
.skel-bloc { height: 240px; }

@keyframes skel {
    0% { background-position: 100% 50%; }
    100% { background-position: 0 50%; }
}

@media (max-width: 640px) {
    .rv-head { align-items: flex-start; }
    .sbar-leg li { grid-template-columns: 10px 1fr auto; }
    .sbar-leg .sbar-pct { display: none; }
}

@media (prefers-reduced-motion: reduce) {
    .skel { animation: none; }
}


/* ============================================================
   12. Fiches détaillées — client (/clients/{n}) et contrat (/contrats/{n})
   ------------------------------------------------------------
   Deux écrans bâtis pareil : fil d'Ariane, bandeau d'identité, tuiles
   (section 11), cartes de définitions, puis onglets sur les listes
   rattachées. Les liens croisés sont le point : client → contrat →
   CRA → client.
   ============================================================ */

/* ---------- 12.1 Fil d'Ariane et bandeau ---------- */
.fil {
    display: flex; align-items: center; gap: .4rem; flex-wrap: wrap;
    margin-bottom: .5rem; font-size: .85rem; color: var(--ink-3);
}
.fil a { color: var(--ink-2); }
.fil a:hover { color: var(--pa-blue-dark); }

.fiche-head {
    display: flex; align-items: flex-end; justify-content: space-between;
    gap: 1rem; flex-wrap: wrap; margin-bottom: 1.1rem;
}
.fiche-head h1 { margin: 0 0 .25rem; }
.fiche-sub {
    display: flex; align-items: center; gap: .5rem; flex-wrap: wrap;
    margin: 0; font-size: .9rem; color: var(--ink-2);
}
.fiche-sub .ref { font-weight: 600; color: var(--ink); font-variant-numeric: tabular-nums; }
.fiche-actions { display: flex; align-items: center; gap: .5rem; flex-wrap: wrap; }

/* ---------- 12.3 Bandeau client de la fiche contrat ---------- */
.bandeau-client {
    display: flex; align-items: center; gap: .8rem;
    padding: .75rem .9rem; margin-bottom: 1rem;
    background: var(--surface); border: 1px solid var(--border);
    border-radius: var(--radius); box-shadow: var(--shadow-1);
    color: inherit; text-decoration: none;
}
.bandeau-client:hover { border-color: var(--pa-blue); text-decoration: none; }
.bandeau-txt { display: flex; flex-direction: column; gap: .1rem; flex-grow: 1; min-width: 0; }
.bandeau-nom { font-weight: 600; }
.bandeau-note { font-size: .85rem; color: var(--ink-2); }
.bandeau-fleche { font-size: .85rem; font-weight: 600; color: var(--pa-blue); white-space: nowrap; }

.avatar {
    display: inline-flex; align-items: center; justify-content: center;
    width: 2.2rem; height: 2.2rem; flex-shrink: 0;
    border-radius: 50%; background: var(--pa-blue-soft); color: var(--pa-blue-dark);
    font-size: .8rem; font-weight: 700; letter-spacing: .3px;
}

/* ---------- 12.4 Onglets ---------- */
.onglets {
    display: flex; gap: .2rem; flex-wrap: wrap;
    margin: 1.2rem 0 0; border-bottom: 1px solid var(--border);
}
.onglet {
    appearance: none; border: 0; background: transparent;
    padding: .6rem .9rem; margin-bottom: -1px;
    font-family: inherit; font-size: .9rem; font-weight: 600;
    color: var(--ink-2); cursor: pointer;
    border-bottom: 2px solid transparent;
}
.onglet:hover { color: var(--pa-blue-dark); }
.onglet.actif { color: var(--pa-blue); border-bottom-color: var(--pa-blue); }
.onglet:focus-visible { outline: 2px solid var(--pa-blue); outline-offset: -2px; }
.onglet .cpt {
    display: inline-block; margin-left: .35rem; padding: 0 .4rem;
    border-radius: 999px; background: #eef1f6; color: var(--ink-2);
    font-size: .74rem; font-variant-numeric: tabular-nums;
}
.onglet.actif .cpt { background: var(--pa-blue-soft); color: var(--pa-blue-dark); }
/* La carte qui suit les onglets se colle à eux : ils forment un seul bloc. */
.onglets + .panel { border-top-left-radius: 0; border-top-right-radius: 0; margin-top: 0; }

/* ---------- 12.5 Cartes de définitions ---------- */
.fiche-cartes {
    display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
    gap: 1rem; margin-top: 1rem;
}
.fiche-cartes .panel { margin: 0; }
.fiche-cartes h2 {
    margin: 0 0 .7rem; font-size: 1rem;
    display: flex; align-items: baseline; gap: .5rem; flex-wrap: wrap;
}
.defs {
    display: grid; grid-template-columns: minmax(7rem, auto) minmax(0, 1fr);
    gap: .5rem .9rem; margin: 0; font-size: .9rem;
}
.defs dt { color: var(--ink-2); }
.defs dd { margin: 0; overflow-wrap: anywhere; }

.interlocs { list-style: none; margin: 0; padding: 0; display: grid; gap: .7rem; }
.interlocs li { display: flex; align-items: flex-start; gap: .6rem; }
.interloc-txt { display: flex; flex-direction: column; gap: .05rem; min-width: 0; font-size: .88rem; }
.interloc-nom { font-weight: 600; }
.interloc-note { color: var(--ink-3); font-size: .8rem; overflow-wrap: anywhere; }

@media (max-width: 640px) {
    .fiche-head { align-items: flex-start; }
    .defs { grid-template-columns: 1fr; gap: .15rem .9rem; }
    .defs dd { margin-bottom: .45rem; }
    .bandeau-fleche { display: none; }
}




/* ============================================================
   13. Listes de consultation — clients, contrats, factures, bulletins
   ------------------------------------------------------------
   Le tableau lui-même n'est PAS retouché : table.quickgrid (section 3 et
   app.css) sert aussi aux listes CRA, devis, notes de frais et opérations,
   et le redéfinir ici les aurait désalignées. Ce qui s'uniformise, c'est
   tout ce qui entoure le tableau : l'en-tête, les filtres, le décompte,
   le squelette de chargement et l'écran vide.
   ============================================================ */

.liste-head {
    display: flex; align-items: flex-end; justify-content: space-between;
    gap: 1rem; flex-wrap: wrap; margin-bottom: 1.1rem;
}
.liste-head h1 { margin: 0 0 .15rem; }
.liste-compte { margin: 0; font-size: .85rem; color: var(--ink-3); }

.liste-outils { display: flex; align-items: flex-end; gap: 1rem; flex-wrap: wrap; }
.liste-actions { display: flex; align-items: flex-end; gap: .5rem; flex-wrap: wrap; }
.liste-filtres { display: flex; align-items: flex-end; gap: .7rem; flex-wrap: wrap; }
.liste-filtres label {
    display: flex; flex-direction: column; gap: .2rem;
    font-size: .72rem; font-weight: 600; letter-spacing: .3px;
    text-transform: uppercase; color: var(--ink-3);
}
.liste-filtres input, .liste-filtres select {
    padding: .42rem .6rem; border: 1px solid var(--border); border-radius: var(--radius-s);
    background: var(--surface); color: var(--ink);
    font-family: inherit; font-size: .9rem; font-weight: 400;
    text-transform: none; letter-spacing: 0;
}
.liste-filtres input:focus-visible, .liste-filtres select:focus-visible {
    outline: 2px solid var(--pa-blue); outline-offset: 1px;
}
.liste-filtres .search input { min-width: 250px; }

/* Premier libellé de la ligne : c'est le lien vers la fiche, il doit se voir
   avant les colonnes qui l'accompagnent. Portée à .liste seulement : les
   grilles CRA, devis, notes de frais et opérations partagent table.quickgrid
   et n'ont pas à changer d'apparence. */
table.quickgrid.liste tbody td:first-child a { font-weight: 600; }

.liste-vide { text-align: center; padding: 2.2rem 1rem; }
.liste-vide h2 { margin-top: 0; }

/* Étape intermédiaire d'une cascade (net social avant le net payé) : soulignée
   sans être conclusive, le solde restant le seul mis en couleur. */
.tbl.ledger .ledger-etape th, .tbl.ledger .ledger-etape td {
    font-weight: 600;
    border-bottom: 2px solid var(--border);
}

/* Précision accolée à un libellé de ligne (« 117 h × 15,00 € » après « Salaire
   horaire »). L'espace ne peut pas venir du balisage : Razor supprime le saut de
   ligne qui précède un bloc @if, et un <text> </text> ne contenant que de l'espace
   est retiré lui aussi. Il vient donc d'ici, où il ne risque plus rien. */
.tbl.ledger th .hint-inline { margin-left: .4rem; }


/* ---------- Confirmation de suppression (SuppressionBrouillon) ---------- */
.confirm-backdrop { z-index: 47; }

/* Boîte centrée sur le même voile que le drawer ; z-index au-dessus de
   celui-ci, la suppression pouvant être demandée drawer ouvert. */
.confirm-box {
    position: fixed;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    z-index: 48;
    width: 420px;
    max-width: calc(100vw - 2rem);
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    box-shadow: var(--shadow-2);
    padding: 1.2rem 1.3rem;
    animation: pa-fade .18s ease;
}

    .confirm-box h2 {
        margin: 0 0 .5rem;
        font-size: 1.05rem;
    }

    .confirm-box p {
        margin: 0 0 .6rem;
        color: var(--ink-2);
        font-size: .9rem;
    }

    .confirm-box .confirm-desc {
        font-weight: 600;
        color: var(--ink);
    }

.confirm-acts {
    display: flex;
    justify-content: flex-end;
    gap: .6rem;
    margin-top: 1rem;
}

.btn-danger {
    padding: .55rem 1.05rem;
    border: none;
    border-radius: var(--radius-s);
    cursor: pointer;
    font-size: .9rem;
    font-weight: 600;
    font-family: inherit;
    line-height: 1.4;
    background: var(--danger);
    color: #fff;
}

    .btn-danger:hover { background: #a52020; }
    .btn-danger:disabled { opacity: .55; cursor: default; }

/* Action de ligne destructrice : neutre au repos, rouge au survol seulement,
   pour ne pas faire de chaque brouillon une ligne d'alerte. */
.row-acts .act-danger:hover {
    border-color: #f2b8b5;
    color: var(--danger);
    background: var(--danger-bg);
}

.recap-actions .btn-del-doc {
    background: none;
    border: none;
    color: var(--danger);
    font-size: .85rem;
    font-weight: 600;
    cursor: pointer;
    padding: .3rem;
    font-family: inherit;
}

    .recap-actions .btn-del-doc:hover { text-decoration: underline; }


/* ============================================================
   14. Incidents : reconnexion au serveur, erreur non rattrapée
   ------------------------------------------------------------
   Deux éléments d'App.razor que blazor.web.js pilote lui-même :
   - #components-reconnect-modal reçoit les classes components-reconnect-*
     (show, retrying, paused, failed, rejected, resume-failed) quand la
     liaison SignalR tombe — recyclage IIS, déploiement, réseau. Sans lui,
     Blazor affichait sa fenêtre par défaut, en anglais ;
   - #blazor-error-ui s'affiche quand une exception tue le circuit. Sans
     lui, l'écran restait figé sans un mot.
   Chaque message n'apparaît que dans son état.
   ============================================================ */
#components-reconnect-modal {
    display: none;
    position: fixed;
    inset: 0;
    z-index: 2000;
    align-items: center;
    justify-content: center;
    padding: 16px;
    background: rgba(16, 24, 40, .45);
}

#components-reconnect-modal.components-reconnect-show,
#components-reconnect-modal.components-reconnect-retrying,
#components-reconnect-modal.components-reconnect-paused,
#components-reconnect-modal.components-reconnect-failed,
#components-reconnect-modal.components-reconnect-rejected,
#components-reconnect-modal.components-reconnect-resume-failed {
    display: flex;
}

.reconnect-boite {
    max-width: 30rem;
    padding: 1.4rem 1.6rem;
    background: var(--surface);
    color: var(--ink);
    border-radius: var(--radius);
    box-shadow: var(--shadow-2);
}

    .reconnect-boite h2 { margin: 0 0 .5rem; font-size: 1.1rem; }
    .reconnect-boite p { margin: .4rem 0; }
    .reconnect-boite .reconnect-actions { display: flex; gap: .6rem; margin-top: 1rem; flex-wrap: wrap; }

.reconnect-etat { display: none; }
.components-reconnect-show .etat-show,
.components-reconnect-retrying .etat-retrying,
.components-reconnect-paused .etat-paused,
.components-reconnect-failed .etat-failed,
.components-reconnect-rejected .etat-rejected,
.components-reconnect-resume-failed .etat-resume-failed {
    display: block;
}

#blazor-error-ui {
    display: none;
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 1900;
    padding: .8rem 3rem .8rem 1.2rem;
    background: #fdecea;
    color: #8a1c13;
    border-top: 1px solid #f3b8b1;
    box-shadow: var(--shadow-2);
}

    #blazor-error-ui .reload { margin-left: .6rem; font-weight: 600; color: inherit; }
    #blazor-error-ui .dismiss {
        position: absolute;
        right: 1rem;
        top: .7rem;
        cursor: pointer;
    }
