/* /Components/Layout/MainLayout.razor.rz.scp.css */
/* Navigation de section dans l'entête : le flux (Leads › Soumissions › Commandes ›
   Production) puis le suivi, en retrait. CSS isolé (scoped) — ne touche pas app.css.
   Couleurs via tokens d'app.css. */
.section-nav[b-ho34x1x8p0] {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 2px 4px;
    justify-content: center;
}

/* Un groupe reste soudé : le flux ne se coupe pas au milieu d'un chevron. */
.nav-groupe[b-ho34x1x8p0] { display: inline-flex; align-items: center; gap: 2px; }

/* Le chevron dit que ces quatre écrans sont UNE chaîne, pas quatre destinations. */
.nav-chevron[b-ho34x1x8p0] {
    color: var(--text-muted);
    font-size: 15px;
    line-height: 1;
    user-select: none;
}

/* Le suivi est transversal, pas une étape : séparé, et visuellement plus léger. */
.nav-suivi[b-ho34x1x8p0] {
    margin-left: 10px;
    padding-left: 10px;
    border-left: 1px solid var(--border);
}
.nav-suivi .section-link[b-ho34x1x8p0] { font-size: 13px; }

.section-link[b-ho34x1x8p0] {
    padding: 7px 14px;
    border-radius: var(--radius-sm);
    font-size: 14px;
    font-weight: 500;
    color: var(--text-secondary);
    text-decoration: none;
    transition: background-color var(--transition), color var(--transition);
}

.section-link:hover[b-ho34x1x8p0] {
    color: var(--text-primary);
    background: var(--bg-glass);
}

.section-link.is-active[b-ho34x1x8p0] {
    color: var(--accent);
    background: var(--accent-soft);
}

@media (max-width: 1100px) {
    .section-link[b-ho34x1x8p0] { padding: 6px 9px; font-size: 13px; }
    .nav-chevron[b-ho34x1x8p0] { display: none; }
    .nav-suivi[b-ho34x1x8p0] { margin-left: 6px; padding-left: 6px; }
}

/* La navigation occupe sa propre rangée (voir app.css). Quand cette rangée elle-même ne
   suffit plus — la barre mesure 1073 px + 48 px de marges, soit ~1120 px —, elle DÉFILE
   horizontalement plutôt que de se replier sur plusieurs lignes ou de forcer la largeur de
   la page. Chaque destination reste atteignable au doigt, et le flux garde son ordre —
   c'est justement lui qu'il ne faut pas casser en le repliant dans un menu.
   `justify-content: flex-start` est obligatoire ici : centré, le début d'un conteneur qui
   déborde devient inatteignable au défilement. */
@media (max-width: 1130px) {
    .section-nav[b-ho34x1x8p0] {
        flex-wrap: nowrap;
        justify-content: flex-start;
        overflow-x: auto;
        scrollbar-width: none;
        -webkit-overflow-scrolling: touch;
    }
    .section-nav[b-ho34x1x8p0]::-webkit-scrollbar { display: none; }
    .nav-groupe[b-ho34x1x8p0]   { flex: none; }
    .section-link[b-ho34x1x8p0] { white-space: nowrap; }
}

@media (max-width: 640px) {
    .section-link[b-ho34x1x8p0] { padding: 5px 7px; font-size: 12.5px; }
    .nav-suivi .section-link[b-ho34x1x8p0] { font-size: 12.5px; }
}

/* Point "Prêt" de l'entête — override du .status-dot partagé (voir app.css), scopé à cette page. */
.appbar .status-dot[b-ho34x1x8p0] {
    background: #3366ff;
    box-shadow: 0 0 0 3px rgba(51, 102, 255, 0.18);
}

/* Recherche globale — un formulaire GET, donc utilisable sans circuit interactif. */
.recherche-globale[b-ho34x1x8p0] {
    display: flex;
    align-items: center;
    gap: 6px;
    padding: 0 10px;
    height: 32px;
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    background: var(--bg-surface);
    color: var(--text-muted);
}
.recherche-globale:focus-within[b-ho34x1x8p0] { border-color: var(--accent); color: var(--accent); }
.recherche-champ[b-ho34x1x8p0] {
    border: none;
    background: none;
    outline: none;
    font: inherit;
    font-size: 13px;
    color: var(--text-primary);
    width: 190px;
}
.recherche-champ[b-ho34x1x8p0]::placeholder { color: var(--text-muted); }
@media (max-width: 900px) {
    .recherche-champ[b-ho34x1x8p0] { width: 110px; }
}

/* Cloche : pastille du nombre de notifications non lues. */
.btn-icon[b-ho34x1x8p0] { position: relative; }
.badge-cloche[b-ho34x1x8p0] {
    position: absolute;
    top: 1px;
    right: 1px;
    min-width: 15px;
    height: 15px;
    padding: 0 3px;
    border-radius: 8px;
    background: #dc2626;
    color: #fff;
    font-size: 9.5px;
    font-weight: 700;
    line-height: 15px;
    text-align: center;
}

/* Identité courante — cliquable, mène à l'écran de sélection. */
.chip-identite[b-ho34x1x8p0] {
    display: flex;
    align-items: center;
    gap: 7px;
    padding: 3px 10px 3px 3px;
    border: 1px solid var(--border);
    border-radius: 999px;
    text-decoration: none;
    color: var(--text-secondary);
    font-size: 13px;
}
.chip-identite:hover[b-ho34x1x8p0] { border-color: var(--accent); color: var(--accent); }
.chip-initiales[b-ho34x1x8p0] {
    width: 24px;
    height: 24px;
    border-radius: 50%;
    display: grid;
    place-items: center;
    /* --accent-fill, pas --accent : le second s'éclaircit en thème sombre pour rester
       lisible en TEXTE, ce qui ruinerait le contraste du blanc par-dessus. */
    background: var(--accent-fill);
    color: #fff;
    font-size: 10.5px;
    font-weight: 700;
}
@media (max-width: 720px) {
    .chip-nom[b-ho34x1x8p0] { display: none; }
}
/* /Components/Layout/PersonnificationSelecteur.razor.rz.scp.css */
/* Sélecteur « voir en tant que » de la barre d'app (patron visuel du starter kit). */
.personnification[b-rfa7g2lmxn] {
    display: inline-flex;
    align-items: center;
    gap: 8px;
}

.personnification-select[b-rfa7g2lmxn] {
    height: 32px;
    width: auto;
    max-width: 180px;
    padding: 4px 28px 4px 8px; /* la place du chevron du <select>, norme maison */
    font-size: 12.5px;
}

/* Personnification EN COURS : le sélecteur passe à l'accent — « ceci n'est pas ma vue »
   doit se voir d'un coup d'œil, pas se déduire. */
.personnification.est-active .personnification-select[b-rfa7g2lmxn] {
    border-color: var(--accent);
    color: var(--accent);
    background: var(--accent-soft);
}

.personnification-badge[b-rfa7g2lmxn] {
    display: inline-block;
    font-weight: 700;
    font-size: 9.5px;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    padding: 3px 8px;
    border-radius: var(--radius-full);
    white-space: nowrap;
    color: var(--accent);
    background: var(--accent-soft);
}
/* /Components/Pages/CataloguePage.razor.rz.scp.css */
/* Styles de la page Catalogue.
   La disposition (barre latérale groupée, cartes, zone de danger) vient du design
   system global (app.css → « Configuration — barre latérale groupée ») ; ne
   restent ici que les grilles éditables, partagées d'idiome avec les autres
   écrans de réglage. */

/* ── Tables éditables ─────────────────────────────────────────────────────────── */
.edit-scroll[b-jx2l8lqq3d] { overflow-x: auto; }
.edit-table td[b-jx2l8lqq3d] { padding: 5px 6px; vertical-align: middle; }
.edit-table .input[b-jx2l8lqq3d] { font-size: 13px; padding: 6px 8px; min-width: 130px; }
.edit-table .input.lg[b-jx2l8lqq3d] { min-width: 260px; }
.edit-table .input.sm[b-jx2l8lqq3d] { min-width: 110px; }
.edit-table .input.xs[b-jx2l8lqq3d] { min-width: 70px; max-width: 110px; }
.edit-table .input.num[b-jx2l8lqq3d] { text-align: right; font-variant-numeric: tabular-nums; }

/* ── En-tête d'une carte recette : le sélecteur d'article produit à gauche,
   le ✕ de retrait à sa droite — sur UNE ligne, quel que soit le libellé. */
.recette-head[b-jx2l8lqq3d] { display: flex; align-items: center; gap: 10px; margin-bottom: 12px; }
.recette-head .input[b-jx2l8lqq3d] { flex: 1; min-width: 0; }
/* /Components/Pages/ClientDetail.razor.rz.scp.css */
.detail-2col[b-zre76rnla4] {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    gap: 18px;
    align-items: start;
    margin-bottom: 18px;
}
@media (max-width: 900px) {
    .detail-2col[b-zre76rnla4] { grid-template-columns: 1fr; }
}

.totaux-liste[b-zre76rnla4] { list-style: none; margin: 0; padding: 0; }
.totaux-liste li[b-zre76rnla4] {
    display: flex;
    justify-content: space-between;
    gap: 12px;
    padding: 7px 0;
    border-bottom: 1px solid var(--border-subtle);
    font-size: 13.5px;
}
.totaux-liste li:last-child[b-zre76rnla4] { border-bottom: none; }
.totaux-liste li span[b-zre76rnla4] { color: var(--text-secondary); }
.totaux-liste li strong[b-zre76rnla4] { text-align: right; }

.kpi-grid[b-zre76rnla4] { margin-bottom: 18px; }

/* L'état « contact principal » utilise la pastille `.chip.is-on` du style guide,
   définie globalement dans app.css — plus rien à surcharger ici. */

/* ── Les projets du compte ──────────────────────────────────────────────────
   La rangée d'en-tête d'un projet et l'indentation de ses pièces : c'est
   l'écart visuel entre les deux qui fait lire le regroupement d'un coup d'œil.
   Les jetons suivent le thème, donc clair et sombre restent d'accord. */
.data-table tr.row-projet td[b-zre76rnla4] {
    background: var(--bg-tertiary);
    font-weight: 600;
    padding-top: 10px;
    padding-bottom: 10px;
}
.data-table tr.row-projet td .pill[b-zre76rnla4] { margin-left: 8px; }
.data-table tr.row-projet td .text-muted[b-zre76rnla4] { font-weight: 400; margin-left: 6px; }

/* Le décalage dit « cette pièce appartient au projet du dessus » sans une ligne
   de plus dans le tableau. */
.data-table td.cell-membre[b-zre76rnla4] { padding-left: 24px; }
/* /Components/Pages/CommandeDetail.razor.rz.scp.css */
/* La fiche commande — ce qui reste propre à la PAGE. Le gros du style vit
   désormais dans le CSS scoped de chaque composant (Commande/…), et les deux
   utilitaires partagés entre eux (.totaux-liste, .commande-bloc) sont montés
   dans app.css. */

/* Mise en page à deux colonnes (client / dossier, totaux / dépôt) — même grille
   que l'écran soumission, pour que les deux dossiers se lisent pareil. */
.detail-2col[b-ukfan67smk] {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    gap: 18px;
    align-items: start;
    margin-bottom: 18px;
}
@media (max-width: 900px) {
    .detail-2col[b-ukfan67smk] { grid-template-columns: 1fr; }
}

/* Le rail de sections colle sous la barre d'app, comme sur /configuration ; le
   panneau empile ses cartes. */
.config-nav[b-ukfan67smk] { top: 76px; }
.config-panel[b-ukfan67smk] { display: flex; flex-direction: column; gap: 18px; }

/* Indicateur de charge d'acier — bleu, pour ne pas se confondre avec le vert
   « terminé » que porte .pill-ok ailleurs. */
.card-head .status-dot[b-ukfan67smk] {
    background: #3366ff;
    box-shadow: 0 0 0 3px rgba(51, 102, 255, 0.18);
}
/* /Components/Pages/CommandesChangements.razor.rz.scp.css */
/* La carte d'une COMMANDE qui attend une décision : le dossier en tête, puis ce
   qu'on lui demande de changer. Une carte plutôt qu'une rangée de tableau, parce
   que la JUSTIFICATION est le contenu principal et qu'elle ne tient pas en cellule. */

.chg-carte[b-hr615e548l] {
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    padding: 14px 16px;
    margin-bottom: 12px;
    background: var(--bg-secondary);
}

.chg-carte:last-child[b-hr615e548l] { margin-bottom: 0; }

.chg-tete[b-hr615e548l] {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px;
    margin-bottom: 8px;
}

/* Les demandes en attente sur cette commande — en retrait, sous le dossier :
   c'est la commande qu'on ouvre, elles ne sont que ce qu'on lui demande. */
.chg-demandes[b-hr615e548l] {
    list-style: none;
    margin: 0 0 10px;
    padding: 0 0 0 12px;
    border-left: 2px solid var(--border);
}

.chg-demandes li + li[b-hr615e548l] {
    margin-top: 10px;
    padding-top: 10px;
    border-top: 1px solid var(--border-subtle);
}

.chg-demande-tete[b-hr615e548l] {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px;
}

.chg-justif[b-hr615e548l] {
    margin: 4px 0 0;
    font-size: 13.5px;
    line-height: 1.5;
    color: var(--text-secondary);
    white-space: pre-wrap;
}
/* /Components/Pages/Compte.razor.rz.scp.css */
/* Ce que l'application sait de la session, une ligne par fait : l'étiquette à gauche, la valeur
   à droite — lisible d'un coup d'œil, comme un reçu. */
.compte-faits[b-8yyrxli4sb] {
    list-style: none;
    margin: 0 0 16px;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 8px;
}

.compte-faits li[b-8yyrxli4sb] {
    display: flex;
    justify-content: space-between;
    gap: 16px;
    padding-bottom: 8px;
    border-bottom: 1px solid var(--border);
    font-size: 13.5px;
}

.compte-faits span[b-8yyrxli4sb] { color: var(--text-muted); }
.compte-faits strong[b-8yyrxli4sb] { text-align: right; color: var(--text-primary); }
/* /Components/Pages/CompteDoubleAuthentification.razor.rz.scp.css */
/* Le code QR : un carré blanc à marge calme, même en thème sombre — un lecteur lit mal un code
   inversé. Taille bornée : lisible par un téléphone tenu à 30 cm, sans dévorer la page. */
.qr-double-auth[b-kl35kcjsgl] {
    width: min(240px, 100%);
    margin: 12px 0 16px;
    border-radius: 8px;
    overflow: hidden;
    border: 1px solid var(--border);
}

.qr-double-auth[b-kl35kcjsgl]  svg {
    display: block;
    width: 100%;
    height: auto;
}

.cle-manuelle[b-kl35kcjsgl] {
    font-size: 1.05rem;
    letter-spacing: 0.04em;
    word-break: break-word;
}

/* Deux colonnes de codes : ils se recopient ou s'impriment d'un coup d'œil. */
.codes-secours[b-kl35kcjsgl] {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 6px 24px;
    margin: 12px 0;
    padding-left: 1.4em;
    font-size: 1.05rem;
}
/* /Components/Pages/Configurateur.razor.rz.scp.css */
/* Plan d'entrepôt : le panneau à gauche, le plan et la réponse vivante à droite. */

.plan-layout[b-vop3ze126g] {
    display: grid;
    grid-template-columns: minmax(340px, 420px) 1fr;
    gap: 18px;
    align-items: start;
}

.plan-form[b-vop3ze126g] { display: flex; flex-direction: column; gap: 14px; }
.plan-result[b-vop3ze126g] { display: flex; flex-direction: column; gap: 14px; }

.plan-sous-titre[b-vop3ze126g] {
    margin: 14px 0 8px;
    font-size: 12px;
    font-weight: 600;
    letter-spacing: .04em;
    text-transform: uppercase;
    color: var(--text-secondary);
}

/* ── Le plan ─────────────────────────────────────────────────────────────── */
.plan-vue .card-body[b-vop3ze126g] { padding: 8px 8px 10px; }
.plan-scene[b-vop3ze126g] { border-radius: 10px; outline: none; color: var(--text-primary); }
.plan-scene:focus-visible[b-vop3ze126g] { box-shadow: 0 0 0 2px var(--accent); }
.plan-scene[b-vop3ze126g]  svg { display: block; width: 100%; height: auto; max-height: 70vh; user-select: none; }
.plan-scene.est-editable[b-vop3ze126g]  .plan-section,
.plan-scene.est-editable[b-vop3ze126g]  .plan-obstacle { touch-action: none; }
.plan-scene[b-vop3ze126g]  .plan-section.est-choisie .plan-emprise { filter: drop-shadow(0 0 4px rgba(51,102,255,0.6)); }

.plan-legende[b-vop3ze126g] {
    display: flex;
    flex-wrap: wrap;
    gap: 6px 14px;
    padding: 8px 6px 0;
    font-size: 12px;
    color: var(--text-secondary);
}
.plan-legende-item[b-vop3ze126g] { display: inline-flex; align-items: center; gap: 6px; }

/* Les pastilles de légende et de liste : les mêmes couleurs que le SVG. */
.plan-pastille[b-vop3ze126g] {
    display: inline-block;
    width: 12px; height: 12px;
    border-radius: 3px;
    flex: 0 0 auto;
    border: 1px solid transparent;
}
.plan-pastille.est-acier[b-vop3ze126g] { background: rgba(51,102,255,0.35); border-color: #3366ff; }
.plan-pastille.est-retire[b-vop3ze126g] { background: repeating-linear-gradient(45deg, #dc2626 0 2px, transparent 2px 5px); border-color: #dc2626; }
.plan-pastille.est-colonne[b-vop3ze126g] { background: rgba(70,74,90,0.85); border-color: rgba(40,42,52,1); }
.plan-pastille.est-porte[b-vop3ze126g] { background: rgba(249,115,22,0.35); border-color: #f97316; }
.plan-pastille.est-exclu[b-vop3ze126g] { background: repeating-linear-gradient(45deg, rgba(128,132,150,0.7) 0 2px, transparent 2px 5px); border-color: rgba(128,132,150,0.9); }

/* ── Les listes d'obstacles et de sections ──────────────────────────────── */
.plan-liste[b-vop3ze126g] { margin: 0; }
.plan-item[b-vop3ze126g] {
    display: grid;
    grid-template-columns: auto 1fr auto auto auto;
    align-items: center;
    gap: 8px;
    cursor: pointer;
    border-radius: 8px;
    padding: 6px 8px;
}
.plan-item:hover[b-vop3ze126g] { background: var(--bg-glass-hover); }
.plan-item.est-choisi[b-vop3ze126g] { background: var(--accent-soft); }
.plan-item.est-impossible .plan-item-nom[b-vop3ze126g] { color: #dc2626; }
.plan-item-nom[b-vop3ze126g] { font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.plan-edition[b-vop3ze126g] {
    margin-top: 12px;
    padding-top: 12px;
    border-top: 1px dashed var(--border);
}

.plan-messages[b-vop3ze126g] { margin: 6px 0 0; padding-left: 18px; }
.plan-messages li[b-vop3ze126g] { margin: 3px 0; }

.plan-kpi[b-vop3ze126g] { grid-template-columns: repeat(4, minmax(0, 1fr)); }

@media (max-width: 1100px) {
    .plan-layout[b-vop3ze126g] { grid-template-columns: 1fr; }
    .plan-kpi[b-vop3ze126g] { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* ── Repris du configurateur (CSS scopé : chaque page porte le sien) ─────── */
.plan-mention-legale[b-vop3ze126g] {
    margin: 0;
    padding: 11px 14px;
    border: 1px solid var(--border);
    border-left: 3px solid var(--accent);
    border-radius: var(--radius-sm);
    background: var(--bg-secondary);
    color: var(--text-secondary);
    font-size: 12.5px;
    line-height: 1.5;
}
.plan-mention-legale strong[b-vop3ze126g] { color: var(--text-primary); }

.recap-list[b-vop3ze126g] { list-style: none; padding: 0; margin: 0; }
.recap-list li[b-vop3ze126g] {
    display: grid;
    grid-template-columns: 160px 1fr;
    gap: 12px;
    padding: 9px 0;
    border-bottom: 1px solid var(--border-subtle);
}
.recap-list li:last-child[b-vop3ze126g] { border-bottom: none; }
.recap-list li span[b-vop3ze126g] { color: var(--text-secondary); font-size: 13px; }
.recap-list li strong[b-vop3ze126g] { color: var(--text-primary); font-weight: 500; }

.plan-desc[b-vop3ze126g] { flex: 1; min-width: 0; }
.plan-qte[b-vop3ze126g] { flex: none; width: 70px; text-align: right; font-variant-numeric: tabular-nums; }
.plan-mnt[b-vop3ze126g] { flex: none; width: 110px; text-align: right; font-variant-numeric: tabular-nums; }

/* ── La visite 3D : cohabite avec le plan dans le DOM (three.js garde sa scène) ── */
.plan-cadre[b-vop3ze126g] { position: relative; }
.plan-3d[b-vop3ze126g] { display: none; border-radius: 10px; overflow: hidden; }
.plan-3d[b-vop3ze126g]  canvas { display: block; width: 100% !important; height: auto !important; }
.plan-cadre.est-3d .plan-scene[b-vop3ze126g] { display: none; }
.plan-cadre.est-3d .plan-3d[b-vop3ze126g] { display: block; }
.plan-bascule[b-vop3ze126g] { padding: 8px 6px 0; flex-wrap: wrap; }
.plan-modes3d[b-vop3ze126g] { display: inline-flex; gap: 6px; margin-left: 12px; }
.plan-livrables[b-vop3ze126g] { flex-wrap: wrap; }

/* ── Le schéma isométrique de la section choisie (cliquable) ─────────────── */
/* Le SVG serveur est là dès le premier rendu ; la toile interactive prend sa place
   quand le module a démarré. Sans lui, on garde le SVG. La toile de sélection ne
   s'affiche jamais : elle sert à lire un pixel au clic — hors flux et invisible,
   mais pas display:none (un canvas caché ainsi garde quand même son contenu). */
.plan-schema[b-vop3ze126g] { display: none; position: relative; }
.plan-cadre.est-schema .plan-scene[b-vop3ze126g] { display: none; }
.plan-cadre.est-schema .plan-schema[b-vop3ze126g] { display: block; }
.plan-schema-svg[b-vop3ze126g]  svg { display: block; width: 100%; height: auto; }
.plan-toile[b-vop3ze126g] { display: none; width: 100%; height: auto; cursor: grab; outline: none; border-radius: 10px; }
.plan-toile:active[b-vop3ze126g] { cursor: grabbing; }
.plan-toile:focus-visible[b-vop3ze126g] { box-shadow: 0 0 0 2px var(--accent); }
.plan-schema.est-interactive .plan-schema-svg[b-vop3ze126g] { display: none; }
.plan-schema.est-interactive .plan-toile[b-vop3ze126g] { display: block; }
.plan-toile-selection[b-vop3ze126g] { position: absolute; left: -99999px; top: 0; pointer-events: none; }
.plan-selection-desc[b-vop3ze126g] { margin: 0 0 8px; font-weight: 500; }
.plan-modes3d .btn-icon[b-vop3ze126g] { width: 30px; height: 30px; }

/* ── Le dossier du plan ──────────────────────────────────────────────────── */
.plan-dossier-ligne[b-vop3ze126g] { display: flex; gap: 8px; align-items: center; }
.plan-dossier-ligne .input[b-vop3ze126g] { flex: 1; min-width: 0; }
.plan-non-enregistre[b-vop3ze126g] { color: #d97706; font-weight: 600; }
.plan-alignement[b-vop3ze126g] { color: var(--accent); }
/* /Components/Pages/ConfigurationGenerale.razor.rz.scp.css */
/* Styles de la page Configuration générale.
   La disposition (barre latérale groupée, cartes, formulaires) vient du design
   system global (app.css → « Configuration — barre latérale groupée ») ; ne
   restent ici que les grilles éditables, partagées d'idiome avec CataloguePage. */

/* ── Tables éditables (vendeurs, délais, termes présentés en grille) ──────────── */
.edit-scroll[b-b2tap0fjo5] { overflow-x: auto; }
.edit-table td[b-b2tap0fjo5] { padding: 5px 6px; vertical-align: middle; }
.edit-table .input[b-b2tap0fjo5] { font-size: 13px; padding: 6px 8px; min-width: 130px; }
.edit-table th:last-child[b-b2tap0fjo5], .edit-table td:last-child[b-b2tap0fjo5] { width: 1%; white-space: nowrap; }

/* ── Le tableau de la règle d'approbation ─────────────────────────────────────
   Il n'est PAS éditable : il rend lisible ce que les champs au-dessus viennent de
   régler. Il est donc posé sur un fond distinct, pour qu'on ne cherche pas à taper
   dedans — un tableau de lecture au milieu d'un formulaire prête sinon à confusion. */
.regle-appr[b-b2tap0fjo5] {
    margin-top: 18px;
    padding: 14px 16px 16px;
    border: 1px solid var(--border-subtle, #d7dde4);
    border-radius: 10px;
    background: var(--bg-glass, rgba(0, 0, 0, 0.02));
}

.regle-appr .data-table[b-b2tap0fjo5] { margin-bottom: 0; }
.regle-appr .data-table td[b-b2tap0fjo5] { vertical-align: middle; }

/* Un déclencheur coupé reste VISIBLE, en retrait : le lecteur doit voir qu'il existe
   et qu'il est éteint, pas le croire absent de la règle. */
.regle-appr tr.is-off td[b-b2tap0fjo5] { opacity: 0.55; }

/* Une règle maison : un petit formulaire encadré, répété. Le cadre est ce qui
   empêche deux règles voisines de se lire comme une seule. */
.regle-maison[b-b2tap0fjo5] {
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    padding: 12px 14px;
    margin-bottom: 12px;
}

.regle-maison:last-of-type[b-b2tap0fjo5] { margin-bottom: 0; }

/* Les champs de PHRASE prennent toute la largeur de la grille. Sans ça ils héritent
   d'une colonne de 155 px (« .form-grid.tight ») et on écrit une recommandation de
   deux lignes dans une fenêtre de trois mots. « span-3 » ne les sauvait pas : le
   design system ne définit que « span-2 ». */
.regle-maison .form-field.champ-large[b-b2tap0fjo5] { grid-column: 1 / -1; }

/* Ce qui déclenche la règle — système, mesure, comparaison, seuil — se lit d'un bloc.
   Le fond les rassemble en une phrase avant même de lire celle qui suit. */
.regle-maison .form-grid[b-b2tap0fjo5] { align-items: start; }

/* ── Le registre des règles ──────────────────────────────────────────────────
   Le code, le repère et la valeur du jour sont des SECONDES lignes : elles
   documentent la règle sans concurrencer son titre du regard. */

.regle-code[b-b2tap0fjo5] {
    font-size: 11px;
    letter-spacing: 0.02em;
    color: var(--text-muted);
}

/* Une table qui porte des PHRASES, pas des chiffres : elle revient à la ligne.
   Le design system met .data-table en nowrap — juste pour des colonnes courtes,
   fatal pour celle-ci, qui sortait de l'écran et cachait ses dernières colonnes.
   L'en-tête, lui, reste sur une ligne : ses libellés sont courts. */
.regle-table td[b-b2tap0fjo5] { white-space: normal; }
.regle-table td strong[b-b2tap0fjo5] { display: inline-block; }

/* Les deux pastilles de gravité tiennent ensemble, jamais coupées en deux lignes. */
.regle-table td .pill[b-b2tap0fjo5] { white-space: nowrap; }

/* Le code et la source, sous le titre de la règle : deux repères courts sur une
   ligne, plutôt que deux colonnes qui poussent la table hors de l'écran. */
.regle-meta[b-b2tap0fjo5] {
    display: flex;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
    margin-top: 3px;
}

.regle-repere[b-b2tap0fjo5],
.regle-valeur[b-b2tap0fjo5] {
    margin-top: 4px;
    font-size: 12px;
    line-height: 1.45;
    color: var(--text-muted);
}

/* La valeur courante du seuil : c'est le chiffre qu'on vient vérifier ici. */
.regle-valeur strong[b-b2tap0fjo5] { color: var(--text-secondary); }

/* Les gravités possibles d'une règle : deux pastilles au plus, sur une ligne. */
.data-table .pill + .pill[b-b2tap0fjo5] { margin-left: 4px; }

/* La règle maison RELUE, sous son formulaire : la phrase que le moteur applique. */
.regle-relue[b-b2tap0fjo5] {
    margin: 10px 0 0;
    padding: 8px 10px;
    border-left: 3px solid var(--accent);
    border-radius: var(--radius-sm);
    background: var(--bg-glass, rgba(0, 0, 0, 0.02));
    font-size: 13px;
    line-height: 1.5;
    color: var(--text-secondary);
}

/* Le bloc à copier-coller pour le webmestre : une commande curl se lit en chasse fixe,
   et déborde horizontalement plutôt que de se replier n'importe où. */
.bloc-code[b-b2tap0fjo5] {
    margin: 0;
    padding: 12px 14px;
    border: 1px solid var(--border);
    border-radius: 8px;
    background: var(--bg-tertiary);
    color: var(--text-secondary);
    font-family: 'JetBrains Mono', 'Fira Code', ui-monospace, monospace;
    font-size: 12px;
    line-height: 1.6;
    overflow-x: auto;
    white-space: pre;
}
/* /Components/Pages/Connexion.razor.rz.scp.css */
/* Une section par groupe de sécurité — le groupe est l'information, pas la décoration :
   c'est lui qui décide de ce que l'écran proposera une fois l'identité choisie. */
.bloc-groupe[b-73jrt2cnck] { margin-bottom: 18px; }

.bloc-tete[b-73jrt2cnck] {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 12px;
    padding-bottom: 6px;
    border-bottom: 1px solid var(--border);
}
.bloc-titre[b-73jrt2cnck] { margin: 0; font-size: 14px; font-weight: 600; color: var(--text-primary); }
.bloc-desc[b-73jrt2cnck] { margin: 6px 0 10px; font-size: 12px; color: var(--text-muted); }

.grille-identites[b-73jrt2cnck] {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(230px, 1fr));
    gap: 10px;
    margin-bottom: 16px;
}

.carte-identite[b-73jrt2cnck] {
    width: 100%;
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 12px 14px;
    border: 1px solid var(--border);
    border-radius: 10px;
    background: var(--bg-surface);
    cursor: pointer;
    font: inherit;
    text-align: left;
}
.carte-identite:hover[b-73jrt2cnck] { border-color: var(--accent); }
.carte-identite.is-on[b-73jrt2cnck] { border-color: var(--accent); background: var(--accent-soft); }

.identite-avatar[b-73jrt2cnck] {
    width: 36px;
    height: 36px;
    border-radius: 50%;
    display: grid;
    place-items: center;
    background: var(--accent-fill);
    color: #fff;
    font-weight: 600;
    font-size: 13px;
    flex: none;
}
.identite-txt[b-73jrt2cnck] { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.identite-nom[b-73jrt2cnck] { font-weight: 600; font-size: 14px; color: var(--text-primary); }
.identite-titre[b-73jrt2cnck] {
    font-size: 12px;
    color: var(--text-muted);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
/* /Components/Pages/FicheCommande/ChangementsCommande.razor.rz.scp.css */
/* ─────────────────────────────────────────────────────────────────────────────
   LA SECTION « CHANGEMENTS » d'une commande.

   Elle a une hiérarchie à tenir, et c'est tout le travail de cette feuille : le
   RÉGIME en tête (est-ce que je peux encore changer quelque chose, et à quel
   prix), puis chaque demande comme une CARTE fermée sur elle-même — parce que
   deux demandes ouvertes sur le même dossier se lisent séparément ou ne se
   lisent pas.

   Les autorisations, les cases de composantes et le fil réutilisent les classes de
   app.css (.autorisations, .autorisation, .cases-lignes, .cycle-detail) : elles sont partagées
   avec le cycle de vie, d'où elles viennent, et les dupliquer ici ferait deux
   apparences pour un même objet.
   ───────────────────────────────────────────────────────────────────────────── */

/* ── Le régime, en tête ─────────────────────────────────────────────────────
   Un bandeau, pas une pastille : ce qu'il annonce tient en trois lignes et
   décide de tout ce qui suit. */
.chg-regime[b-xmo9r9vmxi] {
    border: 1px solid var(--border);
    border-left: 3px solid var(--accent);
    border-radius: 8px;
    padding: 10px 14px;
    margin-bottom: 16px;
    background: var(--bg-tertiary);
    font-size: 13px;
    line-height: 1.55;
    color: var(--text-secondary);
}
.chg-regime strong[b-xmo9r9vmxi] { color: var(--text-primary); }
.chg-regime.est-rigide[b-xmo9r9vmxi] { border-left-color: var(--status-danger); }

/* ── Une demande = une carte ────────────────────────────────────────────────
   Le filet de gauche passe au rouge en régime rigide : trois signatures et de
   l'acier coupé ne se lisent pas comme une correction de couleur. */
.chg-demande[b-xmo9r9vmxi] {
    border: 1px solid var(--border);
    border-left: 3px solid var(--border);
    border-radius: 10px;
    padding: 12px 14px;
    background: var(--bg-secondary);
}
.chg-demande + .chg-demande[b-xmo9r9vmxi] { margin-top: 12px; }
.chg-demande.est-rigide[b-xmo9r9vmxi] { border-left-color: var(--status-danger); }

.chg-demande-tete[b-xmo9r9vmxi] {
    display: flex; flex-wrap: wrap; align-items: center; gap: 8px;
    font-size: 14px; margin-bottom: 6px;
}
.chg-justification[b-xmo9r9vmxi] {
    margin: 0 0 10px; font-size: 13px; line-height: 1.55;
    color: var(--text-secondary); white-space: pre-wrap;
}

/* ── Ce que la demande fait au CONTENU ──────────────────────────────────────
   Vert pour ce qui entre, rouge pour ce qui sort : c'est la seule chose de
   cette carte qui change ce que l'atelier fabrique et ce que le client paie. */
.chg-contenu[b-xmo9r9vmxi] {
    border: 1px dashed var(--border);
    border-radius: 8px;
    padding: 10px 12px;
    margin-bottom: 10px;
    background: var(--bg-glass);
}
.chg-mouvement + .chg-mouvement[b-xmo9r9vmxi] { margin-top: 10px; }
.chg-mouvement-titre[b-xmo9r9vmxi] {
    display: block; font-size: 12.5px; font-weight: 600;
    letter-spacing: 0.02em; margin-bottom: 4px;
}
.chg-mouvement.est-ajout   .chg-mouvement-titre[b-xmo9r9vmxi] { color: var(--status-success); }
.chg-mouvement.est-retrait .chg-mouvement-titre[b-xmo9r9vmxi] { color: var(--status-danger); }
.chg-mouvement.est-quantite .chg-mouvement-titre[b-xmo9r9vmxi] { color: var(--status-warning, var(--accent)); }

.chg-mouvement ul[b-xmo9r9vmxi] { list-style: none; margin: 0; padding: 0; }
.chg-mouvement li[b-xmo9r9vmxi] {
    display: flex; flex-wrap: wrap; align-items: baseline; gap: 6px;
    font-size: 13px; padding: 2px 0;
}

/* ── Les incohérences ───────────────────────────────────────────────────────
   Jaune tant que ça ne fait qu'attirer l'œil, rouge dès qu'une seule bloque :
   l'encadré doit dire, sans être lu, si le bouton « Accepter » servira. */
.chg-incoherences[b-xmo9r9vmxi] {
    border: 1px solid var(--status-warning);
    border-radius: 8px;
    padding: 10px 12px;
    margin: 10px 0;
    background: var(--bg-glass);
}
.chg-incoherences.est-bloquante[b-xmo9r9vmxi] { border-color: var(--status-danger); }
.chg-incoherences ul[b-xmo9r9vmxi] { list-style: none; margin: 6px 0 0; padding: 0; }
.chg-incoherences li[b-xmo9r9vmxi] {
    display: flex; flex-wrap: wrap; align-items: baseline; gap: 8px;
    padding: 5px 0; font-size: 13px;
}
.chg-incoherences li + li[b-xmo9r9vmxi] { border-top: 1px solid var(--border-subtle); }
.chg-incoherence-quoi[b-xmo9r9vmxi] {
    flex-basis: 100%; color: var(--text-secondary);
    font-size: 12.5px; line-height: 1.5;
}

/* La raison d'un bouton grisé — jamais silencieuse. */
.chg-barre[b-xmo9r9vmxi] { display: block; margin-top: 8px; }

/* ── La capture de l'acceptation ────────────────────────────────────────────
   Le dépôt de fichier se lit comme une ligne de formulaire, pas comme un
   bouton d'action : ce n'est pas lui qui consigne l'accord. */
.chg-preuve[b-xmo9r9vmxi] {
    display: flex; flex-wrap: wrap; align-items: center; gap: 10px;
    margin: 8px 0; font-size: 13px;
}

/* ── Le formulaire, replié derrière un bouton ───────────────────────────────
   Fermé, il tient en une ligne : un mot sur le régime et le bouton. La section
   se lit d'abord pour ce qui attend une décision. */
.chg-invite[b-xmo9r9vmxi] {
    display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between;
    gap: 12px;
}
.chg-invite-texte[b-xmo9r9vmxi] { min-width: 0; flex: 1 1 320px; }
.chg-invite-texte .stitle[b-xmo9r9vmxi] { margin: 0 0 2px; }
.chg-invite-texte .form-hint[b-xmo9r9vmxi] { margin: 0; }

.chg-form-tete[b-xmo9r9vmxi] {
    display: flex; align-items: center; justify-content: space-between;
    margin-bottom: 12px;
}
.chg-form-tete .stitle[b-xmo9r9vmxi] { margin: 0; }

/* ── Les étapes ─────────────────────────────────────────────────────────────
   Numérotées, parce que la demande se lit dans cet ordre : ce qui change et
   pourquoi, les produits touchés, ce qu'on ajoute. */
.chg-etape[b-xmo9r9vmxi] { padding: 14px 0; border-top: 1px solid var(--border-subtle); }
.chg-etape:first-of-type[b-xmo9r9vmxi] { border-top: none; padding-top: 4px; }
.chg-etape-titre[b-xmo9r9vmxi] {
    display: flex; align-items: center; gap: 8px;
    margin: 0 0 10px; font-size: 14px; font-weight: 600; color: var(--text-primary);
}
.chg-etape-num[b-xmo9r9vmxi] {
    display: inline-flex; align-items: center; justify-content: center;
    width: 22px; height: 22px; border-radius: 50%;
    background: var(--accent-soft); color: var(--accent);
    font-size: 12px; font-weight: 700;
}
.chg-etape-action[b-xmo9r9vmxi] { margin-left: auto; }

.chg-champs[b-xmo9r9vmxi] {
    display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 12px;
}
.chg-champ-large[b-xmo9r9vmxi] { grid-column: span 3; }
.chg-champ-plein[b-xmo9r9vmxi] { grid-column: 1 / -1; }
.chg-champs textarea[b-xmo9r9vmxi] { resize: vertical; min-height: 56px; }

@media (max-width: 700px) {
    .chg-champs[b-xmo9r9vmxi] { grid-template-columns: 1fr 1fr; }
    .chg-champ-large[b-xmo9r9vmxi], .chg-champ-plein[b-xmo9r9vmxi] { grid-column: 1 / -1; }
}

/* ── Le tableau des produits de la commande ─────────────────────────────────
   Une ligne par composante et tous ses gestes sur la même ligne. Une ligne
   modifiée se souligne, une ligne retirée se barre : l'état se lit sans
   relire les nombres. */
.chg-table[b-xmo9r9vmxi] { white-space: normal; }
.chg-table tbody td[b-xmo9r9vmxi] { vertical-align: middle; }
.chg-table .num[b-xmo9r9vmxi] { white-space: nowrap; }
.chg-produit[b-xmo9r9vmxi] { min-width: 220px; }
.chg-produit .pill[b-xmo9r9vmxi] { margin-left: 6px; font-size: 11px; padding: 1px 8px; }
.chg-produit-desc[b-xmo9r9vmxi] { font-weight: 500; }
.chg-table tr.est-changee td[b-xmo9r9vmxi] { background: var(--accent-soft); }
.chg-table tr.est-retiree td[b-xmo9r9vmxi] { background: var(--bg-glass); }
.chg-table tr.est-retiree .chg-produit-desc[b-xmo9r9vmxi],
.chg-table tr.est-retiree td.num > span:first-child[b-xmo9r9vmxi] {
    text-decoration: line-through; color: var(--text-muted);
}
.chg-avant[b-xmo9r9vmxi] {
    display: block; font-size: 11.5px; color: var(--text-muted);
    text-decoration: none; margin-top: 2px;
}
.chg-col-revue[b-xmo9r9vmxi] { text-align: center; width: 1%; white-space: nowrap; }
.chg-col-action[b-xmo9r9vmxi] { text-align: right; width: 1%; white-space: nowrap; }
.chip.chip-retirer:hover:not(:disabled)[b-xmo9r9vmxi] {
    color: var(--status-danger); border-color: var(--status-danger); background: transparent;
}
.chip:disabled[b-xmo9r9vmxi] { opacity: 0.45; cursor: not-allowed; }

/* La quantité se change en place : une petite case numérique, soulignée dès
   qu'elle diffère du dossier. */
.chg-qte[b-xmo9r9vmxi] { width: 80px; text-align: right; }
.chg-qte.est-changee[b-xmo9r9vmxi] { border-color: var(--accent); font-weight: 600; }

/* L'aide se déplie à la demande : on la lit une fois, pas à chaque demande. */
.chg-aide[b-xmo9r9vmxi] { margin-top: 8px; font-size: 12.5px; color: var(--text-secondary); }
.chg-aide summary[b-xmo9r9vmxi] { cursor: pointer; color: var(--accent); font-weight: 500; }
.chg-aide ul[b-xmo9r9vmxi] { margin: 6px 0 0; padding-left: 18px; line-height: 1.55; }
.chg-aide li + li[b-xmo9r9vmxi] { margin-top: 4px; }

.chg-vide[b-xmo9r9vmxi] { margin: 0; font-size: 13px; }

/* ── L'ajout d'un produit ──────────────────────────────────────────────────── */
.chg-ajout[b-xmo9r9vmxi] {
    margin-top: 10px; padding: 12px;
    border: 1px solid var(--border); border-radius: 8px;
    background: var(--bg-tertiary);
}
.chg-ajout-grille[b-xmo9r9vmxi] {
    display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 10px;
}
@media (max-width: 700px) {
    .chg-ajout-grille[b-xmo9r9vmxi] { grid-template-columns: 1fr 1fr; }
    .chg-ajout-grille .chg-champ-large[b-xmo9r9vmxi] { grid-column: 1 / -1; }
}
.chg-ajout .form-hint[b-xmo9r9vmxi] { margin: 8px 0 0; }
.chg-ajout-actions[b-xmo9r9vmxi] { margin-top: 10px; }

/* ── Le dépôt ───────────────────────────────────────────────────────────────
   Le résumé à gauche, les boutons à droite : on relit ce qu'on envoie au
   moment même où on l'envoie. */
.chg-depot[b-xmo9r9vmxi] {
    display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between;
    gap: 12px; margin-top: 12px; padding: 12px 14px;
    border: 1px solid var(--border); border-radius: 8px;
    background: var(--bg-tertiary);
}
.chg-resume[b-xmo9r9vmxi] { display: flex; flex-wrap: wrap; gap: 6px 14px; font-size: 13px; min-width: 0; }
.chg-resume-morceau[b-xmo9r9vmxi] { color: var(--text-secondary); }
.chg-resume-morceau + .chg-resume-morceau[b-xmo9r9vmxi]::before {
    content: "·"; margin-right: 14px; color: var(--text-muted);
}
.chg-depot-boutons[b-xmo9r9vmxi] { display: flex; align-items: center; gap: 10px; margin-left: auto; }

/* ── Le panier des produits à ajouter ───────────────────────────────────────
   Ils n'existent nulle part tant que la demande n'est pas déposée : la liste
   se lit donc comme un brouillon, pas comme le contenu de la commande. */
.chg-panier[b-xmo9r9vmxi] {
    list-style: none; margin: 12px 0 0; padding: 10px 12px;
    border: 1px dashed var(--status-success);
    border-radius: 8px;
    background: var(--bg-glass);
}
.chg-panier li[b-xmo9r9vmxi] {
    display: flex; flex-wrap: wrap; align-items: center; gap: 8px;
    padding: 4px 0; font-size: 13px;
}
.chg-panier li + li[b-xmo9r9vmxi] { border-top: 1px solid var(--border-subtle); }
.chg-panier li .text-muted[b-xmo9r9vmxi] { flex: 1; }

/* ── L'historique des demandes tranchées ────────────────────────────────────
   Une ligne par décision, la pastille de statut en tête : on y cherche « qu'a-
   t-on déjà refusé sur ce dossier », et la réponse doit se balayer. */
.chg-historique[b-xmo9r9vmxi] { list-style: none; margin: 0; padding: 0; }
.chg-historique li[b-xmo9r9vmxi] {
    display: flex; flex-wrap: wrap; align-items: center; gap: 8px;
    padding: 7px 0; font-size: 13px;
}
.chg-historique li + li[b-xmo9r9vmxi] { border-top: 1px solid var(--border-subtle); }
.chg-historique-mot[b-xmo9r9vmxi] {
    flex-basis: 100%; color: var(--text-secondary);
    font-size: 12.5px; line-height: 1.5;
}
.chg-depot + .form-hint[b-xmo9r9vmxi] { margin-top: 8px; }
/* /Components/Pages/FicheCommande/EnteteCommande.razor.rz.scp.css */
/* L'entête de la commande — l'identité, l'état (trois concepts NOMMÉS), les quatre
   chiffres qui décident, et un seul bouton. Tokens Proxima uniquement. */

.cmd-entete[b-ey1q05dzvm] {
    background: var(--bg-secondary);
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    padding: 18px 20px 14px;
    display: flex;
    flex-direction: column;
    gap: 14px;
}

.cmd-entete-haut[b-ey1q05dzvm] { display: flex; justify-content: space-between; gap: 24px; align-items: flex-start; flex-wrap: wrap; }
.cmd-ident[b-ey1q05dzvm] { min-width: 0; display: flex; flex-direction: column; gap: 6px; }
.cmd-ident .back-link[b-ey1q05dzvm] { margin: 0 0 2px; }
.cmd-titre[b-ey1q05dzvm] { margin: 0; font-size: 24px; font-weight: 600; letter-spacing: -0.02em; color: var(--text-primary); }
.cmd-client[b-ey1q05dzvm] { color: var(--text-secondary); font-weight: 500; }
.cmd-refs[b-ey1q05dzvm] { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; font-size: 13px; color: var(--text-secondary); }
.cmd-refs strong[b-ey1q05dzvm] { color: var(--text-primary); font-weight: 600; }
.cmd-sep[b-ey1q05dzvm] { color: var(--text-muted); }

/* Le prochain geste : UN bloc, UN bouton primaire. */
.cmd-geste[b-ey1q05dzvm] {
    min-width: 300px;
    max-width: 400px;
    background: var(--bg-tertiary);
    border: 1px solid var(--border);
    border-left: 3px solid var(--accent);
    border-radius: var(--radius-md);
    padding: 12px 14px;
    display: flex;
    flex-direction: column;
    gap: 4px;
}
.cmd-geste.est-lecture[b-ey1q05dzvm] { border-left-color: var(--text-muted); }
.cmd-geste-quoi[b-ey1q05dzvm] { font-size: 15px; font-weight: 600; color: var(--text-primary); line-height: 1.35; }
.cmd-geste-pourquoi[b-ey1q05dzvm] { font-size: 12.5px; color: var(--text-secondary); line-height: 1.45; }
.cmd-geste-actions[b-ey1q05dzvm] { display: flex; gap: 8px; margin-top: 8px; flex-wrap: wrap; }

.cmd-geste-lbl[b-ey1q05dzvm],
.cmd-etat-lbl[b-ey1q05dzvm],
.cmd-chiffre-lbl[b-ey1q05dzvm] {
    font-size: 10.5px;
    font-weight: 600;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--text-muted);
}

/* L'état : phase, statut et version ne sont PAS la même chose — chacun sous son nom. */
.cmd-entete-bas[b-ey1q05dzvm] {
    display: flex;
    align-items: flex-end;
    gap: 26px;
    flex-wrap: wrap;
    border-top: 1px solid var(--border-subtle);
    padding-top: 12px;
}
.cmd-etat[b-ey1q05dzvm] { display: flex; flex-direction: column; gap: 6px; }

/* Le rail de phases est celui d'app.css (.cycle-rail) : ici seulement en plus serré,
   parce qu'il partage sa ligne avec le statut, la version et quatre chiffres. */
.cycle-rail.est-compact[b-ey1q05dzvm] { margin: 0; gap: 4px; }
.cycle-rail.est-compact .cycle-phase-nom[b-ey1q05dzvm] { padding: 3px 10px; font-size: 11.5px; }

.cmd-chiffres[b-ey1q05dzvm] { margin-left: auto; display: flex; gap: 28px; }
.cmd-chiffre[b-ey1q05dzvm] { display: flex; flex-direction: column; gap: 4px; }
.cmd-chiffre-val[b-ey1q05dzvm] {
    font-size: 17px;
    font-weight: 600;
    color: var(--text-primary);
    font-variant-numeric: tabular-nums;
    display: flex;
    align-items: center;
    gap: 8px;
}
.cmd-chiffre-note[b-ey1q05dzvm] { font-style: normal; font-size: 12px; font-weight: 500; color: var(--text-secondary); }
.cmd-chiffre-note.est-retard[b-ey1q05dzvm] { color: #b91c1c; }
[data-theme="dark"] .cmd-chiffre-note.est-retard[b-ey1q05dzvm] { color: #f87171; }

/* Les alertes sont des RACCOURCIS : chacune ouvre la section qui la traite. */
.cmd-alertes[b-ey1q05dzvm] { display: flex; gap: 8px; flex-wrap: wrap; }
.cmd-alertes .pill[b-ey1q05dzvm] {
    border: 0;
    font-family: inherit;
    cursor: pointer;
    text-align: left;
    transition: filter 0.12s ease;
}
.cmd-alertes .pill:hover[b-ey1q05dzvm] { filter: brightness(0.96); }

@media (max-width: 900px) {
    .cmd-chiffres[b-ey1q05dzvm] { margin-left: 0; gap: 20px; }
    .cmd-geste[b-ey1q05dzvm] { max-width: none; }
}
/* /Components/Pages/FicheCommande/LignesCommande.razor.rz.scp.css */
/* La table des lignes — les trois tableaux d'hier réduits à des groupes de colonnes.
   Le basculement se fait en CSS depuis `data-groupe` sur la carte : aucune colonne
   n'est re-rendue, elle s'affiche ou pas. */

.lignes-table[b-mq43q6drte] { width: 100%; }

/* `.data-table` est en `white-space: nowrap` (app.css) : sans ces deux exceptions, la
   table dépasse la largeur de sa carte et la DERNIÈRE colonne — celle des boutons de
   décision — se fait couper sans que rien ne le signale. */
.lignes-table .lig-desc[b-mq43q6drte],
.lignes-table .col-mot[b-mq43q6drte] { white-space: normal; }
.lignes-table .lig-desc[b-mq43q6drte] { min-width: 240px; }
.lignes-table .col-mot[b-mq43q6drte] { min-width: 160px; max-width: 300px; }
.lignes-table .col-decision[b-mq43q6drte] { min-width: 300px; }
.lignes-table .col-dessin[b-mq43q6drte] { min-width: 130px; }
.lignes-table .input.col-ref[b-mq43q6drte] { min-width: 120px; }
.lignes-table .col-envoi[b-mq43q6drte] { min-width: 120px; }
.lignes-table .input.col-motif[b-mq43q6drte] { flex: 1 1 150px; min-width: 130px; }
.lignes-table .pointage-btns[b-mq43q6drte] { flex-wrap: wrap; row-gap: 6px; }
.lignes-table .verdicts[b-mq43q6drte] { display: inline-flex; gap: 4px; flex: none; }

.lig-nom[b-mq43q6drte] { font-weight: 500; }
.lignes-table .pill-tag[b-mq43q6drte] { background: var(--bg-tertiary); color: var(--text-secondary); margin-left: 6px; }
.lignes-table .tag-retenue[b-mq43q6drte] { margin-left: 6px; }

/* Une composante retenue est un ARRÊT : la rangée le porte, pas seulement une pastille
   au milieu d'une colonne qu'on peut avoir masquée. */
.lignes-table tbody tr.est-retenue[b-mq43q6drte] { background: rgba(239, 68, 68, 0.045); }
.lignes-table tbody tr.est-retenue td:first-child[b-mq43q6drte] { box-shadow: inset 3px 0 0 rgba(239, 68, 68, 0.75); }

/* « Non revue » n'est pas un statut à crier : elle attend, c'est tout. */
.pill-neutre[b-mq43q6drte] { background: var(--bg-tertiary); color: var(--text-secondary); }

.seg-colonnes .chip[b-mq43q6drte] { padding: 4px 11px; font-size: 12px; }
.lignes-table .chip-oui[b-mq43q6drte] { color: var(--accent); border-color: var(--accent); }

/* ── Les groupes de colonnes ─────────────────────────────────────────────────── */
[data-groupe="commercial"] .g-revue[b-mq43q6drte],
[data-groupe="commercial"] .g-atelier[b-mq43q6drte],
[data-groupe="revue"] .g-commercial[b-mq43q6drte],
[data-groupe="revue"] .g-atelier[b-mq43q6drte],
[data-groupe="atelier"] .g-commercial[b-mq43q6drte],
[data-groupe="atelier"] .g-revue[b-mq43q6drte] { display: none; }

/* La colonne Verdict le dit déjà : pas deux fois la même pastille sur la même rangée. */
[data-groupe="revue"] .tag-retenue[b-mq43q6drte] { display: none; }

/* « Tout » montre les trois grains d'un coup. Pour que la rangée tienne à l'écran, les
   quatre étapes se replient en quatre jauges, et les deux colonnes de texte long
   sortent — elles restent à un clic, dans « Revue ». */
.g-compact[b-mq43q6drte] { display: none; }
[data-groupe="tout"] .g-compact[b-mq43q6drte] { display: table-cell; }
[data-groupe="tout"] .g-etape[b-mq43q6drte],
[data-groupe="tout"] .g-avct[b-mq43q6drte],
[data-groupe="tout"] .g-par[b-mq43q6drte],
[data-groupe="tout"] .col-mot[b-mq43q6drte],
[data-groupe="tout"] .col-dessin[b-mq43q6drte],
[data-groupe="tout"] .col-decision[b-mq43q6drte] { display: none; }
[data-groupe="tout"] .lignes-table thead th[b-mq43q6drte],
[data-groupe="tout"] .lignes-table tbody td[b-mq43q6drte],
[data-groupe="tout"] .lignes-table tfoot td[b-mq43q6drte] { padding-left: 10px; padding-right: 10px; }
[data-groupe="tout"] .lignes-table .lig-desc[b-mq43q6drte] { min-width: 200px; }

.mini-etapes[b-mq43q6drte] { display: inline-flex; gap: 3px; }
.mini-etape[b-mq43q6drte] {
    display: block;
    width: 22px;
    height: 7px;
    border-radius: var(--radius-full, 999px);
    background: var(--border-subtle);
    overflow: hidden;
}
.mini-etape i[b-mq43q6drte] { display: block; height: 100%; background: #3366ff; }

/* Une étape finie est BLEUE, pas verte : le vert (.pill-ok) dit « dossier terminé »
   partout ailleurs dans l'app, et une étape close n'est pas une commande close. */
.pointage .pill-ok[b-mq43q6drte] { background: rgba(51, 102, 255, 0.14); color: #1d4ed8; }
[data-theme="dark"] .pointage .pill-ok[b-mq43q6drte] { color: #93b4ff; }
/* /Components/Pages/ForgeDemande.razor.rz.scp.css */
/* ── Onglets (Nouvelle demande / Historique) ──────────────────────────────────── */
.onglets[b-4spv98q09p] {
    display: flex;
    gap: 4px;
    border-bottom: 1px solid var(--border);
    margin-bottom: 18px;
}
.onglet[b-4spv98q09p] {
    background: none;
    border: none;
    border-bottom: 2px solid transparent;
    padding: 9px 14px;
    font-family: inherit;
    font-size: 14px;
    font-weight: 500;
    color: var(--text-secondary);
    cursor: pointer;
}
.onglet:hover[b-4spv98q09p] { color: var(--text-primary); }
.onglet.is-active[b-4spv98q09p] { color: var(--accent); border-bottom-color: var(--accent); }

/* ── Escalier : étapes numérotées reliées par un rail ─────────────────────────── */
.stepper[b-4spv98q09p] { max-width: 640px; }

.step[b-4spv98q09p] { display: flex; gap: 16px; }

.rail[b-4spv98q09p] { display: flex; flex-direction: column; align-items: center; flex: none; }

.num[b-4spv98q09p] {
    width: 28px;
    height: 28px;
    border-radius: 50%;
    background: var(--accent-fill);
    color: #fff;
    display: flex;
    align-items: center;
    justify-content: center;
    font-weight: 600;
    font-size: 13px;
    flex: none;
}

/* Le trait qui relie une étape à la suivante (l'effet « escalier »). */
.line[b-4spv98q09p] { flex: 1; width: 2px; background: var(--border); margin: 5px 0; }

.scontent[b-4spv98q09p] { flex: 1; min-width: 0; padding-bottom: 22px; }
.step:last-child .scontent[b-4spv98q09p] { padding-bottom: 0; }

.stitle[b-4spv98q09p] { font-size: 15px; font-weight: 600; color: var(--text-primary); margin-bottom: 2px; }
.sdesc[b-4spv98q09p] { font-size: 12px; color: var(--text-muted); margin-bottom: 11px; }

/* Zone de dépôt d'une capture pour pré-remplir (reconnaissance d'image). */
.drop-capture[b-4spv98q09p] {
    display: flex;
    align-items: center;
    gap: 10px;
    margin-top: 14px;
    padding: 11px 13px;
    border: 1px dashed var(--border);
    border-radius: var(--radius-sm);
    background: var(--bg-elevated);
    cursor: pointer;
    font-size: 13px;
    color: var(--text-secondary);
    transition: border-color 0.15s ease, color 0.15s ease;
}
.drop-capture:hover[b-4spv98q09p] { border-color: var(--accent); color: var(--text-primary); }
/* Le champ fichier natif est masqué (app.css, « Champ fichier ») : l'anneau de
   focus se pose donc sur la zone elle-même, sinon le clavier passe sur un
   contrôle invisible. */
.drop-capture:focus-within[b-4spv98q09p] {
    border-color: var(--accent);
    color: var(--text-primary);
    box-shadow: 0 0 0 3px var(--accent-soft);
}
/* Pendant la reconnaissance, la zone dit qu'elle n'accepte rien de plus. */
.drop-capture.est-occupe[b-4spv98q09p] {
    cursor: progress;
    color: var(--text-muted);
    border-color: var(--border-subtle);
}

/* Contrôle segmenté (type, portée, priorité) — une rangée de pastilles `.chip`. */
.seg[b-4spv98q09p] {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
}

/* ── Écran de confirmation ────────────────────────────────────────────────────── */
.recap-phrase[b-4spv98q09p] {
    font-size: 16px;
    line-height: 1.5;
    color: var(--text-primary);
    background: var(--accent-soft);
    border: 1px solid var(--accent);
    border-radius: var(--radius-sm);
    padding: 14px 16px;
    margin-bottom: 18px;
}

.recap-list[b-4spv98q09p] {
    list-style: none;
    padding: 0;
    margin: 0;
}

.recap-list li[b-4spv98q09p] {
    display: grid;
    grid-template-columns: 160px 1fr;
    gap: 12px;
    padding: 9px 0;
    border-bottom: 1px solid var(--border-subtle);
}

.recap-list li span[b-4spv98q09p] {
    color: var(--text-secondary);
    font-size: 13px;
}

.recap-list li strong[b-4spv98q09p] {
    color: var(--text-primary);
    font-weight: 500;
}

/* Point "SourceLabel" — override du .status-dot partagé (voir app.css). */
.status-dot[b-4spv98q09p] {
    background: #3366ff;
    box-shadow: 0 0 0 3px rgba(51, 102, 255, 0.18);
}
/* /Components/Pages/GroupesSecuritePage.razor.rz.scp.css */
/* Styles de la page Groupes de sécurité.
   La matrice de comparaison (composant MatriceAcces) puis une carte par groupe : le nom,
   les droits (composant AccesGroupe), et la formulation d'origine de la liste d'accès. Les
   deux composants portent leur propre mise en forme. Tout vient des variables du design system — aucune couleur en dur, pour que le
   thème sombre suive sans retouche. */

/* ── Une carte par groupe ─────────────────────────────────────────────────────── */
.groupe-carte[b-tq2c86ynfi] { margin-bottom: 14px; padding: 16px 18px; }

.groupe-tete[b-tq2c86ynfi] {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 12px;
    margin-bottom: 10px;
}

.groupe-tete h3[b-tq2c86ynfi] { margin: 0 0 2px; }

.groupe-desc[b-tq2c86ynfi] {
    margin: 0;
    color: var(--text-muted);
    font-size: 13px;
}

.groupe-origine[b-tq2c86ynfi],
.groupe-membres[b-tq2c86ynfi] {
    margin: 0;
    font-size: 12px;
    color: var(--text-muted);
}

.groupe-origine[b-tq2c86ynfi] {
    padding-top: 8px;
    border-top: 1px solid var(--border);
    font-style: italic;
}

.groupe-membres[b-tq2c86ynfi] { margin-top: 4px; }
/* /Components/Pages/Home.razor.rz.scp.css */
/* Deux colonnes pour le travail du jour (rappels dus / soumissions à relancer). */
.deux-col[b-rxt05qc87s] {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    gap: 18px;
    align-items: start;
    margin-bottom: 18px;
}
@media (max-width: 900px) {
    .deux-col[b-rxt05qc87s] { grid-template-columns: 1fr; }
}

/* Les tuiles cliquables se comportent comme des cartes, pas comme des liens. */
a.kpi-card[b-rxt05qc87s] { text-decoration: none; }
a.kpi-card:hover[b-rxt05qc87s] { border-color: var(--accent); }
/* /Components/Pages/Journal.razor.rz.scp.css */
/* Journal des changements — la mise en forme sert UNE idée : replié, l'écran doit se lire
   d'un balayage vertical ; c'est la synthèse qui porte, tout le reste s'efface. */

.jrn-outils[b-nx9lkvvhx7] { display: flex; gap: 10px; align-items: center; }
.jrn-rech[b-nx9lkvvhx7] { min-width: 220px; }

.jrn-compte[b-nx9lkvvhx7] {
    font-size: 12.5px;
    color: var(--text-muted);
    margin: 0;
    font-variant-numeric: tabular-nums;
}

.jrn-mois[b-nx9lkvvhx7] { display: flex; flex-direction: column; gap: 10px; }

.jrn-mois-titre[b-nx9lkvvhx7] {
    margin: 8px 0 0;
    font-size: 12px;
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--text-muted);
}

.jrn-liste[b-nx9lkvvhx7] { list-style: none; margin: 0; padding: 0; display: grid; gap: 10px; }

.jrn-entree[b-nx9lkvvhx7] { padding: 0; transition: var(--transition); }
.jrn-entree:hover[b-nx9lkvvhx7] { border-color: var(--text-muted); }

/* La synthèse EST la ligne cliquable : toute la largeur, pas juste le triangle. */
/* ⚠️ PAS de display:flex ici. La synthèse contient du `code` injecté : en flex, CHAQUE
   nœud devient un élément flex et le texte se disloque autour du chiffon de code. Le texte
   doit rester en flux INLINE — le chevron est donc positionné en absolu, pas empilé. */
.jrn-entree summary[b-nx9lkvvhx7] {
    cursor: pointer;
    position: relative;
    padding: 14px 18px 14px 40px;
    font-size: 14.5px;
    line-height: 1.5;
    color: var(--text-primary);
    list-style: none;
}
.jrn-entree summary[b-nx9lkvvhx7]::-webkit-details-marker { display: none; }

/* Chevron maison : tourne à l'ouverture. Le marqueur natif n'est pas stylable partout. */
.jrn-entree summary[b-nx9lkvvhx7]::before {
    content: "\203A";
    position: absolute;
    left: 20px;
    top: 15px;
    font-size: 17px;
    line-height: 1;
    color: var(--text-muted);
    transition: transform 0.15s ease;
}
.jrn-entree details[open] summary[b-nx9lkvvhx7]::before { transform: rotate(90deg); }

.jrn-entree summary:hover[b-nx9lkvvhx7] { background: var(--bg-tertiary); }
.jrn-entree details[open] summary[b-nx9lkvvhx7] { font-weight: 600; }

.jrn-meta[b-nx9lkvvhx7] {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    align-items: center;
    padding: 0 18px 0 40px;
    font-size: 12px;
    color: var(--text-muted);
}
.jrn-date[b-nx9lkvvhx7] { font-variant-numeric: tabular-nums; }
.jrn-auteur[b-nx9lkvvhx7]::before { content: "· "; }

/* La couleur des catégories vient du nuancier `.tag.cat-color-N` d'app.css (PR 57), déjà
   décliné clair/sombre — on ne redéfinit RIEN ici, sinon les deux nuanciers divergent.
   La correspondance catégorie → teinte vit dans EntreeJournal.CategorieCss. */

/* Numéro et catégorie dans la ligne repliée : des éléments INLINE (voir l'avertissement
   flex ci-dessus), calés sur la ligne de texte. */
.jrn-num[b-nx9lkvvhx7] {
    font-family: 'JetBrains Mono', 'Fira Code', ui-monospace, monospace;
    font-size: 12px;
    font-variant-numeric: tabular-nums;
    color: var(--text-muted);
    margin-right: 8px;
}
.jrn-cat[b-nx9lkvvhx7] {
    margin-right: 10px;
    vertical-align: 1px;
}
/* La graisse à l'ouverture s'applique à la synthèse, pas aux repères. */
.jrn-entree details[open] summary .jrn-num[b-nx9lkvvhx7] { font-weight: 400; }

/* Filtres rapides : les puces de catégorie portent leur vraie couleur — le filtre sert
   aussi de légende du nuancier. Éteint = assourdi, allumé = plein + liseré. */
.jrn-filtres[b-nx9lkvvhx7] {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    align-items: center;
}
.jrn-filtres-nom[b-nx9lkvvhx7] {
    font-size: 11px;
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--text-muted);
    min-width: 72px;
}
.jrn-filtre[b-nx9lkvvhx7] {
    cursor: pointer;
    border: 1px solid transparent;
    opacity: 0.55;
    transition: var(--transition);
    font: inherit;
    font-size: 12px;
}
.jrn-filtre:hover[b-nx9lkvvhx7] { opacity: 1; }
.jrn-filtre-actif[b-nx9lkvvhx7] { opacity: 1; border-color: currentColor; }
.jrn-filtre-n[b-nx9lkvvhx7] { opacity: 0.7; font-variant-numeric: tabular-nums; }

.jrn-detail[b-nx9lkvvhx7] {
    margin: 10px 0 0;
    padding: 0 18px 16px 40px;
    display: grid;
    gap: 7px;
    font-size: 13.5px;
    line-height: 1.6;
    color: var(--text-secondary);
    list-style: none;
}
.jrn-detail li[b-nx9lkvvhx7] { position: relative; padding-left: 14px; }
.jrn-detail li[b-nx9lkvvhx7]::before {
    content: "";
    position: absolute;
    left: 0; top: 9px;
    width: 4px; height: 4px;
    border-radius: 50%;
    background: var(--border);
}

/* Captures d'écran : bordées et bornées — une capture illustre, elle n'envahit pas. */
.jrn-captures[b-nx9lkvvhx7] {
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
    padding: 0 18px 16px 40px;
}
.jrn-capture[b-nx9lkvvhx7] { margin: 0; }
.jrn-capture img[b-nx9lkvvhx7] {
    display: block;
    max-width: min(420px, 100%);
    max-height: 320px;
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
}

.jrn-alerte[b-nx9lkvvhx7] {
    padding: 11px 15px;
    border-radius: var(--radius-sm);
    border: 1px solid var(--status-warning);
    color: var(--status-warning);
    font-size: 13px;
}

@media (max-width: 640px) {
    .jrn-outils[b-nx9lkvvhx7] { width: 100%; }
    .jrn-rech[b-nx9lkvvhx7] { flex: 1; min-width: 0; }
    .jrn-meta[b-nx9lkvvhx7], .jrn-detail[b-nx9lkvvhx7] { padding-left: 18px; }
    .jrn-captures[b-nx9lkvvhx7] { padding-left: 18px; }
    .jrn-filtres-nom[b-nx9lkvvhx7] { min-width: 100%; }
}

/* `code` et `**gras**` arrivent par MarkupString : ces éléments n'existent pas dans le .razor,
   donc ils NE PORTENT PAS l'attribut de portée. ::deep est obligatoire ici — sans lui la règle
   ne s'applique à rien, en silence. */
.jrn-entree[b-nx9lkvvhx7]  code {
    font-family: 'JetBrains Mono', 'Fira Code', ui-monospace, monospace;
    font-size: 0.88em;
    padding: 1px 5px;
    border-radius: var(--radius-sm);
    background: var(--bg-tertiary);
    color: var(--text-primary);
}
.jrn-entree[b-nx9lkvvhx7]  strong { color: var(--text-primary); font-weight: 650; }
/* /Components/Pages/LeadDetail.razor.rz.scp.css */
.detail-2col[b-6vclz372f4] {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    gap: 18px;
    align-items: start;
    margin-bottom: 18px;
}
@media (max-width: 900px) {
    .detail-2col[b-6vclz372f4] { grid-template-columns: 1fr; }
}

/* Blocs secondaires de la carte Actions (motif de perte, affectation). */
.bloc-perte[b-6vclz372f4] {
    border-top: 1px solid var(--border);
    margin-top: 14px;
    padding-top: 12px;
}

.stitre[b-6vclz372f4] {
    font-size: 11px;
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--text-muted);
}
/* /Components/Pages/NouvelleSoumission.razor.rz.scp.css */
/* ── Escalier : étapes numérotées reliées par un rail (patron ForgeDemande) ──── */
.stepper[b-eywv18keuk] { max-width: 100%; }
.step[b-eywv18keuk] { display: flex; gap: 16px; }
.rail[b-eywv18keuk] { display: flex; flex-direction: column; align-items: center; flex: none; }
/* Scopé à .rail : « num » est aussi la classe des cellules numériques de la table. */
.rail .num[b-eywv18keuk] {
    width: 28px;
    height: 28px;
    border-radius: 50%;
    background: var(--accent-fill);
    color: #fff;
    display: flex;
    align-items: center;
    justify-content: center;
    font-weight: 600;
    font-size: 13px;
    flex: none;
}
.line[b-eywv18keuk] { flex: 1; width: 2px; background: var(--border); margin: 5px 0; }
.scontent[b-eywv18keuk] { flex: 1; min-width: 0; padding-bottom: 26px; }
.step:last-child .scontent[b-eywv18keuk] { padding-bottom: 0; }
.stitle[b-eywv18keuk] { font-size: 15px; font-weight: 600; color: var(--text-primary); margin-bottom: 2px; }
.sdesc[b-eywv18keuk] { font-size: 12px; color: var(--text-muted); margin-bottom: 11px; }

/* Contrôle segmenté (familles de composantes). */
.seg[b-eywv18keuk] { display: flex; flex-wrap: wrap; gap: 8px; }

/* ── Aperçu de la ligne en cours (description + poids décomposé) ─────────────── */
.apercu-ligne[b-eywv18keuk] {
    margin-top: 12px;
    padding: 11px 14px;
    border: 1px solid var(--accent);
    border-radius: var(--radius-sm);
    background: var(--accent-soft);
}
.apercu-desc[b-eywv18keuk] { font-size: 13px; font-weight: 600; color: var(--text-primary); }
.apercu-detail[b-eywv18keuk] { font-size: 12px; color: var(--text-secondary); margin-top: 4px; }

/* ── Lignes ajoutées + suggestions ────────────────────────────────────────────── */
.lignes-ajoutees[b-eywv18keuk] { margin-top: 18px; overflow-x: auto; }

.sugg-banner[b-eywv18keuk] {
    margin-top: 12px;
    padding: 11px 14px;
    border: 1px dashed var(--border-strong, var(--border));
    border-radius: var(--radius-sm);
    background: var(--bg-elevated);
    font-size: 13px;
    color: var(--text-secondary);
}

/* ── Écran de révision ────────────────────────────────────────────────────────── */
.recap-phrase[b-eywv18keuk] {
    font-size: 16px;
    line-height: 1.5;
    color: var(--text-primary);
    background: var(--accent-soft);
    border: 1px solid var(--accent);
    border-radius: var(--radius-sm);
    padding: 14px 16px;
    margin-bottom: 18px;
}
.recap-list[b-eywv18keuk] { list-style: none; padding: 0; margin: 0; }
.recap-list li[b-eywv18keuk] {
    display: grid;
    grid-template-columns: 160px 1fr;
    gap: 12px;
    padding: 9px 0;
    border-bottom: 1px solid var(--border-subtle);
}
.recap-list li span[b-eywv18keuk] { color: var(--text-secondary); font-size: 13px; }
.recap-list li strong[b-eywv18keuk] { color: var(--text-primary); font-weight: 500; }

/* Le bloc de quincaillerie d'une composante — encadré, parce qu'il répond à des
   questions DIFFÉRENTES de celles de la composante elle-même et qu'il produit ses
   propres lignes dans la soumission. */
.quinc-bloc[b-eywv18keuk] {
    border: 1px dashed var(--border);
    border-radius: var(--radius-sm);
    padding: 10px 12px;
    margin: 12px 0;
}

.quinc-bloc .stitle[b-eywv18keuk] { margin-bottom: 2px; }
.quinc-ligne[b-eywv18keuk] { margin-top: 8px; }
/* /Components/Pages/Production.razor.rz.scp.css */
/* ============================================================
   Vue plancher — la liste des pièces, projet ▸ commande ▸ ligne.
   Tout est en variables du design system (voir app.css) : la page
   suit le thème clair/sombre sans une seule couleur codée en dur,
   à l'exception des trois teintes d'état (à faire / en cours / fait)
   qui portent une INFORMATION et non une marque.
   ============================================================ */

/* ---- Barre d'outils : les filtres rapides ---- */
.prod-toolbar[b-wbexfxvmmz] { display: flex; flex-direction: column; gap: 12px; }
.prod-toolbar-row[b-wbexfxvmmz] { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }

.filter-group[b-wbexfxvmmz] { display: inline-flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.filter-group .filter-label[b-wbexfxvmmz] {
    font-size: 10.5px; font-weight: 600; letter-spacing: 0.06em; text-transform: uppercase;
    color: var(--text-muted); margin-right: 2px;
}
.filter-sep[b-wbexfxvmmz] { width: 1px; align-self: stretch; background: var(--border); margin: 2px 6px; }

.chip-count[b-wbexfxvmmz] {
    margin-left: 5px; padding: 0 5px; border-radius: var(--radius-full);
    background: var(--bg-glass-hover); font-size: 10.5px; font-variant-numeric: tabular-nums;
}
.chip.is-on .chip-count[b-wbexfxvmmz] { background: rgba(255, 255, 255, 0.22); }
.chip.chip-alerte:not(.is-on)[b-wbexfxvmmz] { color: #b91c1c; border-color: rgba(239, 68, 68, 0.35); }

/* ---- Niveau 1 : le PROJET (= le numéro de dossier) ---- */
.projet-groupe[b-wbexfxvmmz] {
    border: 1px solid var(--border); border-radius: var(--radius-lg);
    background: var(--bg-secondary); overflow: hidden; box-shadow: var(--shadow-sm);
}
.projet-head[b-wbexfxvmmz] {
    display: flex; align-items: center; gap: 12px; flex-wrap: wrap; padding: 12px 16px;
    background: var(--bg-tertiary); border-bottom: 1px solid var(--border);
    cursor: pointer; user-select: none;
}
.projet-head:hover[b-wbexfxvmmz] { background: var(--bg-glass-hover); }
.projet-head:focus-visible[b-wbexfxvmmz] { outline: 2px solid var(--accent); outline-offset: -2px; }
.projet-caret[b-wbexfxvmmz] { color: var(--text-muted); font-size: 12px; width: 12px; flex-shrink: 0; }
.projet-kicker[b-wbexfxvmmz] {
    font-size: 10.5px; font-weight: 600; letter-spacing: 0.07em; text-transform: uppercase;
    color: var(--accent);
}
.projet-nom[b-wbexfxvmmz] {
    font-weight: 650; font-size: 15px; letter-spacing: -0.01em; color: var(--text-primary);
    font-variant-numeric: tabular-nums;
}
.projet-meta[b-wbexfxvmmz] { font-size: 12.5px; color: var(--text-muted); font-variant-numeric: tabular-nums; }
.projet-right[b-wbexfxvmmz] { margin-left: auto; display: flex; align-items: center; gap: 12px; }
.projet-pct[b-wbexfxvmmz] {
    font-weight: 700; font-size: 13px; font-variant-numeric: tabular-nums;
    min-width: 38px; text-align: right;
}

/* ---- Niveau 2 : la COMMANDE ---- */
.cmd-bloc + .cmd-bloc[b-wbexfxvmmz] { border-top: 1px solid var(--border); }
.cmd-head[b-wbexfxvmmz] {
    display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
    padding: 10px 16px 10px 40px; background: var(--bg-glass);
}
.cmd-num[b-wbexfxvmmz] { font-weight: 700; font-size: 13.5px; color: var(--accent); font-variant-numeric: tabular-nums; }
.cmd-num:hover[b-wbexfxvmmz] { text-decoration: underline; }
.cmd-client[b-wbexfxvmmz] { font-weight: 600; font-size: 13.5px; color: var(--text-primary); }
.cmd-meta[b-wbexfxvmmz] { font-size: 12.5px; color: var(--text-muted); display: inline-flex; align-items: center; gap: 8px; }
.cmd-right[b-wbexfxvmmz] { margin-left: auto; display: inline-flex; align-items: center; gap: 10px; }

.cmd-foot[b-wbexfxvmmz] {
    display: flex; align-items: center; gap: 14px; flex-wrap: wrap;
    padding: 8px 16px 10px 40px;
    font-size: 12px; color: var(--text-muted); font-variant-numeric: tabular-nums;
}
.cmd-foot strong[b-wbexfxvmmz] { color: var(--text-secondary); }

/* ---- Niveau 3 : la table des pièces ---- */
.piece-table[b-wbexfxvmmz] { font-size: 13px; }
.piece-table thead th[b-wbexfxvmmz] { font-size: 10.5px; letter-spacing: 0.05em; }
.piece-table thead th.etape-th[b-wbexfxvmmz] { text-align: center; width: 102px; }
.piece-table tbody td[b-wbexfxvmmz] { padding: 7px 12px; vertical-align: middle; }
.piece-table tbody td:first-child[b-wbexfxvmmz] { padding-left: 40px; }

.piece-ligne-no[b-wbexfxvmmz] {
    font-family: 'JetBrains Mono', 'Fira Code', monospace;
    font-size: 11.5px; color: var(--text-muted); font-variant-numeric: tabular-nums;
    white-space: nowrap;
}
/* Les descriptions générées sont longues (« MONTANT 100" X 42" X 3.25" X 3" 13GA. DB AV/AR
   4" + 4 DIAG. BOX 2" ET PLAQUE 8" X 8" X 1/2" (2 TROUS) »). Sans borne elles poussent les
   colonnes d'étape hors de l'écran — et c'est justement là que le plancher clique.
   Le « nowrap » vient de .data-table (app.css) : il faut le lever ici, sinon le max-width
   ne sert à rien et la ligne s'étire quand même. */
.piece-desc[b-wbexfxvmmz] {
    line-height: 1.35; max-width: 430px;
    white-space: normal; overflow-wrap: anywhere;
}
.piece-produit[b-wbexfxvmmz] { font-weight: 550; color: var(--text-primary); }
.piece-fam[b-wbexfxvmmz] {
    display: inline-block; margin-right: 7px; padding: 1px 6px; border-radius: var(--radius-sm);
    font-size: 10px; font-weight: 700; letter-spacing: 0.05em; text-transform: uppercase;
    background: var(--bg-tertiary); color: var(--text-secondary); vertical-align: 1px;
    white-space: nowrap;
}
.piece-fam.fam-montant[b-wbexfxvmmz] { background: rgba(59, 130, 246, 0.16); color: #1d4ed8; }
.piece-fam.fam-poutre[b-wbexfxvmmz] { background: rgba(139, 92, 246, 0.16); color: #6d28d9; }

/* Micro-champs sous la description (poste, mention « acheté ») — la feuille Proplan
   présente les cotes en COLONNES parce qu'un profileur lit des cotes, pas des phrases. */
.dims[b-wbexfxvmmz] { display: flex; flex-wrap: wrap; gap: 4px; margin-top: 3px; }
.dim[b-wbexfxvmmz] {
    display: inline-flex; align-items: baseline; gap: 4px;
    padding: 1px 6px; border-radius: var(--radius-sm);
    background: var(--bg-glass); border: 1px solid var(--border-subtle);
    font-size: 11.5px; font-variant-numeric: tabular-nums; color: var(--text-primary);
}
.dim i[b-wbexfxvmmz] {
    font-style: normal; font-size: 9px; font-weight: 700; letter-spacing: 0.05em;
    text-transform: uppercase; color: var(--text-muted);
}

.note-prod[b-wbexfxvmmz] {
    display: inline-block; padding: 2px 8px; border-radius: var(--radius-sm);
    background: rgba(245, 158, 11, 0.14); color: #92400e;
    border-left: 3px solid var(--status-warning);
    font-size: 11.5px; font-weight: 600; line-height: 1.35;
}
.note-prod.note-stock[b-wbexfxvmmz] {
    background: var(--bg-tertiary); color: var(--text-secondary);
    border-left-color: var(--text-muted);
}

.couleur-puce[b-wbexfxvmmz] {
    display: inline-block; width: 10px; height: 10px; border-radius: 3px;
    border: 1px solid var(--border); margin-right: 6px; vertical-align: -1px;
}

/* Une ligne achetée s'atténue — mais JAMAIS par une `opacity` posée sur la cellule
   d'étape : `opacity` crée un contexte d'empilement, et le panneau de pointage, qui vit
   dans cette cellule, s'y retrouvait enfermé. Son `z-index` ne valait plus rien hors du
   contexte et les rangées SUIVANTES lui passaient par-dessus. On atténue donc le contenu
   (la jauge, le « s. o. »), jamais la cellule qui porte le panneau. */
.piece-table tbody tr.is-achat td:not(.etape-cell)[b-wbexfxvmmz] { opacity: 0.82; }
.piece-table tbody tr.is-achat .etape-na[b-wbexfxvmmz],
.piece-table tbody tr.is-achat .etape-btn:not(.is-attente)[b-wbexfxvmmz] { opacity: 0.82; }
.etape-na[b-wbexfxvmmz] { color: var(--text-muted); font-size: 11.5px; }

/* Ligne en retard : un liseré, pas un fond rouge — le plancher balaie la table,
   un aplat coloré sur dix lignes ne veut plus rien dire. */
.piece-table tbody tr.is-retard td:first-child[b-wbexfxvmmz] { box-shadow: inset 3px 0 0 var(--status-danger); }

/* ---- LA cible du plancher : une jauge cliquable par étape ----
   Le FOND porte l'avancement, le CHIFFRE porte le compte : à deux mètres d'un poste
   de soudure on lit la couleur, à quarante centimètres on lit « 24/40 ». */
.etape-cell[b-wbexfxvmmz] { text-align: center; padding: 5px 6px !important; position: relative; }
.etape-btn[b-wbexfxvmmz] {
    position: relative; display: inline-flex; flex-direction: column; align-items: center;
    justify-content: center; gap: 1px; width: 88px; padding: 5px 4px;
    border: 1px solid var(--border); border-radius: var(--radius-sm);
    background: var(--bg-tertiary); cursor: pointer; overflow: hidden;
    font-family: inherit; transition: border-color 0.12s ease, transform 0.1s ease;
}
.etape-btn[b-wbexfxvmmz]::before {
    content: ""; position: absolute; inset: 0 auto 0 0; width: var(--p, 0%);
    background: var(--jauge, transparent); transition: width 0.2s ease;
}
.etape-btn > *[b-wbexfxvmmz] { position: relative; }
.etape-btn:hover:not(:disabled)[b-wbexfxvmmz] { border-color: var(--accent); }
.etape-btn:active:not(:disabled)[b-wbexfxvmmz] { transform: scale(0.97); }
.etape-btn:disabled[b-wbexfxvmmz] { cursor: default; }
.etape-btn:focus-visible[b-wbexfxvmmz] { outline: 2px solid var(--accent); outline-offset: 1px; }

.etape-val[b-wbexfxvmmz] { font-size: 12.5px; font-weight: 650; font-variant-numeric: tabular-nums; color: var(--text-primary); }
.etape-sub[b-wbexfxvmmz] {
    font-size: 9px; white-space: nowrap; max-width: 100%; overflow: hidden; text-overflow: ellipsis;
    letter-spacing: 0.04em; text-transform: uppercase; color: var(--text-muted);
}

.etape-btn.is-todo[b-wbexfxvmmz] { --jauge: transparent; }
.etape-btn.is-partial[b-wbexfxvmmz] { --jauge: rgba(245, 158, 11, 0.28); border-color: rgba(245, 158, 11, 0.45); }
.etape-btn.is-done[b-wbexfxvmmz] { --jauge: rgba(34, 197, 94, 0.22); border-color: rgba(34, 197, 94, 0.45); }
.etape-btn.is-done .etape-val[b-wbexfxvmmz] { color: #15803d; }

/* L'étape qui attend la précédente se lit comme « pas à moi », pas comme du retard. */
.etape-btn.is-attente[b-wbexfxvmmz] { --jauge: transparent; opacity: 0.55; }
.etape-btn.is-attente .etape-val[b-wbexfxvmmz] { color: var(--text-muted); }

/* ---- Le pointage, ouvert au clic sur une jauge ---- */
.pointage-pop[b-wbexfxvmmz] {
    position: absolute; z-index: 20; left: 50%; transform: translateX(-50%); margin-top: 4px;
    display: flex; flex-direction: column; gap: 8px; width: 264px; padding: 12px;
    border: 1px solid var(--border); border-radius: var(--radius-md);
    background: var(--bg-elevated); box-shadow: var(--shadow-lg); text-align: left;
    /* `.data-table` est en `white-space: nowrap` (app.css) et ça DESCEND jusqu'ici : sans
       ce retour à la ligne, la phrase d'aide sortait du panneau et traversait la table
       d'un bord à l'autre. Le panneau est un encart, pas une cellule. */
    white-space: normal;
}
.pointage-pop-titre[b-wbexfxvmmz] {
    display: flex; align-items: center; gap: 8px;
    font-size: 11px; font-weight: 700; letter-spacing: 0.05em;
    text-transform: uppercase; color: var(--text-muted);
}
.pointage-pop-fermer[b-wbexfxvmmz] {
    margin-left: auto; border: 0; background: none; cursor: pointer;
    color: var(--text-muted); font-size: 12px; line-height: 1; padding: 2px 4px;
    border-radius: var(--radius-sm);
}
.pointage-pop-fermer:hover[b-wbexfxvmmz] { color: var(--text-primary); background: var(--bg-glass-hover); }

/* « ✓ Tout » est une ACTION. Elle emprunte la forme d'une puce mais jamais « is-on »,
   qui ne signifie qu'une chose dans l'app : « ce filtre est actif ». */
.chip.chip-action[b-wbexfxvmmz] { border-color: var(--accent); color: var(--accent); }
.chip.chip-action:hover[b-wbexfxvmmz] { background: var(--accent-soft); }
.pointage-pop-row[b-wbexfxvmmz] { display: flex; align-items: center; flex-wrap: wrap; gap: 6px; }
.pointage-pop .input.qte[b-wbexfxvmmz] {
    width: 70px; padding: 5px 8px; font-size: 13px;
    text-align: right; font-variant-numeric: tabular-nums;
}
.pointage-pop-aide[b-wbexfxvmmz] { font-size: 11px; color: var(--text-muted); line-height: 1.45; }

/* La table DÉFILE dans sa carte (`.data-scroll` est en `overflow: auto`) : un panneau
   ouvert sur l'une des dernières lignes se faisait couper net par le bas de la carte.
   Tant qu'un pointage est ouvert, la table qui le porte — elle seule — réserve sous sa
   dernière ligne la hauteur d'un panneau. */
.data-scroll.a-pointage[b-wbexfxvmmz] { padding-bottom: 232px; }

/* ---- Thème sombre : seules les teintes d'état ont besoin d'être relevées ---- */
[data-theme="dark"] .piece-fam.fam-montant[b-wbexfxvmmz] { color: #93b4ff; }
[data-theme="dark"] .piece-fam.fam-poutre[b-wbexfxvmmz] { color: #c4b5fd; }
[data-theme="dark"] .note-prod[b-wbexfxvmmz] { color: #fcd34d; }
[data-theme="dark"] .chip.chip-alerte:not(.is-on)[b-wbexfxvmmz] { color: #f87171; }
[data-theme="dark"] .etape-btn.is-done .etape-val[b-wbexfxvmmz] { color: #4ade80; }

/* ---- Écrans étroits (tablette d'atelier) ---- */
@media (max-width: 900px) {
    .piece-table tbody td:first-child[b-wbexfxvmmz],
    .cmd-head[b-wbexfxvmmz],
    .cmd-foot[b-wbexfxvmmz] { padding-left: 16px; }
    .projet-right[b-wbexfxvmmz] { margin-left: 0; width: 100%; }
}
/* /Components/Pages/Rapports.razor.rz.scp.css */
.detail-2col[b-v74epbyhzw] {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    gap: 18px;
    align-items: start;
    margin-bottom: 18px;
}
@media (max-width: 900px) {
    .detail-2col[b-v74epbyhzw] { grid-template-columns: 1fr; }
}

.kpi-grid[b-v74epbyhzw] { margin-bottom: 18px; }

/* Barres de répartition (sources, motifs de perte) — pas de librairie, du CSS. */
.barres[b-v74epbyhzw] { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 12px; }
.barre-entete[b-v74epbyhzw] {
    display: flex;
    justify-content: space-between;
    gap: 10px;
    font-size: 13px;
    color: var(--text-secondary);
    margin-bottom: 4px;
}
.barre-entete strong[b-v74epbyhzw] { color: var(--text-primary); font-variant-numeric: tabular-nums; }
.barre[b-v74epbyhzw] {
    height: 8px;
    border-radius: 4px;
    background: var(--bg-glass);
    overflow: hidden;
}
.barre-remplie[b-v74epbyhzw] {
    display: block;
    height: 100%;
    border-radius: 4px;
    background: var(--accent);
}
.barre-remplie.perte[b-v74epbyhzw] { background: #dc2626; }
/* /Components/Pages/Recherche.razor.rz.scp.css */
.groupe-resultats[b-2h0ttrrdha] { margin-top: 16px; }
.groupe-resultats:first-of-type[b-2h0ttrrdha] { margin-top: 8px; }

.stitre[b-2h0ttrrdha] {
    font-size: 11px;
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--text-muted);
    padding-bottom: 6px;
    border-bottom: 1px solid var(--border-subtle);
    margin-bottom: 8px;
}
/* /Components/Pages/SoumissionDetail.razor.rz.scp.css */
.detail-2col[b-13dn2ak1cl] {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    gap: 18px;
    align-items: start;
}
@media (max-width: 900px) {
    .detail-2col[b-13dn2ak1cl] { grid-template-columns: 1fr; }
}

.totaux-liste[b-13dn2ak1cl] { list-style: none; margin: 0; padding: 0; }
.totaux-liste li[b-13dn2ak1cl] {
    display: flex;
    justify-content: space-between;
    gap: 12px;
    padding: 7px 0;
    border-bottom: 1px solid var(--border-subtle);
    font-size: 13.5px;
}
.totaux-liste li span[b-13dn2ak1cl] { color: var(--text-secondary); }
.totaux-liste li strong[b-13dn2ak1cl] { font-variant-numeric: tabular-nums; }
.totaux-liste li.total[b-13dn2ak1cl] {
    border-bottom: none;
    border-top: 2px solid var(--accent);
    margin-top: 4px;
    padding-top: 10px;
    font-size: 16px;
}
.totaux-liste li.total strong[b-13dn2ak1cl] { color: var(--accent); }

.actions-pile[b-13dn2ak1cl] { display: flex; flex-wrap: wrap; gap: 10px; margin-bottom: 16px; }

.commande-bloc[b-13dn2ak1cl] {
    border-top: 1px solid var(--border);
    padding-top: 14px;
}
.commande-bloc .stitle[b-13dn2ak1cl] { font-size: 14px; font-weight: 600; color: var(--text-primary); }

/* Point "lb d'acier" — override du .status-dot partagé (voir app.css). */
.status-dot[b-13dn2ak1cl] {
    background: #3366ff;
    box-shadow: 0 0 0 3px rgba(51, 102, 255, 0.18);
}
/* /Components/Pages/UtilisateursPage.razor.rz.scp.css */
/* Styles de la page Utilisateurs.
   La disposition (en-tête, carte, formulaires) vient du design system global, la grille
   des comptes du composant DataTable — comme Clients, Soumissions et Commandes — et la
   matrice des accès du composant MatriceAcces, qui porte sa propre mise en forme. Ne
   reste ici que ce qui distingue une grille ÉDITABLE d'une grille de lecture. */

/* ── La grille éditable des comptes ───────────────────────────────────────────────
   ::deep est obligatoire — les éléments sont rendus par le DataTable, ils ne portent
   donc pas la portée de cette page. */
.comptes-grille[b-0d2svlayan]  .data-table tbody td { padding: 5px 6px; vertical-align: middle; }
.comptes-grille[b-0d2svlayan]  .data-table .input { font-size: 13px; padding: 6px 8px; min-width: 130px; }
.comptes-grille[b-0d2svlayan]  .data-table .input.xs { min-width: 70px; max-width: 110px; }

/* La colonne d'action reste au plus juste, collée à droite du tableau. */
.comptes-grille[b-0d2svlayan]  .data-table .col-action { width: 1%; white-space: nowrap; }

/* Une ligne de compte n'est pas cliquable : elle s'édite. Le survol qui allume la ligne
   ferait croire à un lien. */
.comptes-grille[b-0d2svlayan]  .data-table tbody tr:hover { background: transparent; }

/* ── La section « Qui a le droit de quoi » ────────────────────────────────────────
   La cible du lien « plus bas sur cette page » ne doit pas se cacher sous la barre
   d'app collante. */
#groupes[b-0d2svlayan] { scroll-margin-top: calc(var(--appbar-h) + 28px); }   /* l'ancre ne doit pas finir sous la barre d'app */

.groupe-sans[b-0d2svlayan] { margin-top: 14px; }

/* ── L'accès d'un compte ──────────────────────────────────────────────────────────
   Le mot de passe généré se lit et se recopie d'un coup : police à chasse fixe, sélection
   d'un clic. Il n'est affiché qu'une fois. */
#acces[b-0d2svlayan] { scroll-margin-top: calc(var(--appbar-h) + 28px); }
.mdp-genere[b-0d2svlayan] { font-size: 1.05rem; letter-spacing: 0.03em; user-select: all; }
/* /Components/Shared/AccesGroupe.razor.rz.scp.css */
/* Les droits d'un accès, rendus lisibles.
   Tout vient des variables du design system — aucune couleur en dur, pour que le
   thème sombre suive sans retouche. */

/* Les droits accordés en pleine encre, les refusés estompés. Le « · » garde la ligne
   alignée sur le « ✓ » — une case vide ferait sauter la colonne. */
.acces-droits[b-t2hiet98hx] {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
    gap: 2px 14px;
    margin: 0 0 10px;
    padding: 0;
    list-style: none;
    font-size: 13px;
}

.acces-droits li[b-t2hiet98hx] { display: flex; align-items: baseline; gap: 7px; }
.acces-droits .puce[b-t2hiet98hx] { width: 10px; flex: none; text-align: center; }
.acces-droits .oui[b-t2hiet98hx] { color: var(--text-primary); }
.acces-droits .oui .puce[b-t2hiet98hx] { color: var(--accent); font-weight: 600; }
.acces-droits .non[b-t2hiet98hx] { color: var(--text-muted); opacity: .5; }

.acces-portee[b-t2hiet98hx] { margin: 0 0 6px; font-size: 12px; color: var(--text-muted); }
/* /Components/Shared/HistoriqueVersions.razor.rz.scp.css */
/* Le fil des versions : une entrée par papier sorti de la maison.
   Volontairement plus calme que le cycle de vie d'une commande — ici on ne
   décide rien, on relit. */

.versions-fil[b-46gamujop7] {
    list-style: none;
    margin: 0;
    padding: 0;
    display: grid;
    gap: 14px;
}

.version-entree[b-46gamujop7] {
    border: 1px solid var(--border);
    border-left: 3px solid var(--accent);
    border-radius: 8px;
    padding: 10px 14px;
    background: var(--bg-secondary);
}

/* La première version ne se compare à rien : son filet reste neutre, pour que
   l'œil n'y cherche pas un changement qui n'existe pas. */
.version-entree.est-premiere[b-46gamujop7] { border-left-color: var(--border); }

.version-tete[b-46gamujop7] {
    display: flex;
    align-items: baseline;
    flex-wrap: wrap;
    gap: 8px;
    margin-bottom: 6px;
}

.version-numero[b-46gamujop7] {
    font-weight: 700;
    font-size: 15px;
    letter-spacing: 0.02em;
    color: var(--text-primary);
    text-decoration: none;
}
.version-numero:hover[b-46gamujop7] { text-decoration: underline; }

/* Le montant va à droite : c'est la colonne que l'œil descend quand il cherche
   « à partir de quand le prix a bougé ». */
.version-total[b-46gamujop7] {
    margin-left: auto;
    font-variant-numeric: tabular-nums;
    font-weight: 600;
}

.version-changements[b-46gamujop7] {
    margin: 0 0 6px;
    padding-left: 18px;
    font-size: 13px;
    line-height: 1.55;
}

.version-pied[b-46gamujop7] {
    margin: 0;
    font-size: 12px;
}

/* LES RENVOIS — le même papier reparti. Décalés et discrets : ce ne sont pas des
   versions, et les montrer au même rang ferait exactement la confusion qu'on corrige. */
.version-renvois[b-46gamujop7] {
    margin: 0 0 6px;
    padding-left: 10px;
    border-left: 2px dashed var(--border);
}

.version-renvois .version-changements[b-46gamujop7] {
    list-style: none;
    padding-left: 0;
    margin: 4px 0 0;
    font-size: 12px;
    color: var(--text-muted);
}

/* Les gestes d'une ligne (revoir le papier, le reprendre) — calés à GAUCHE, sous
   le contenu qu'ils visent, et non à droite comme les gestes d'un formulaire :
   ils appartiennent à la version, pas à la page. */
.version-gestes[b-46gamujop7] {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 8px;
    margin-top: 10px;
}
/* /Components/Shared/JournalDossier.razor.rz.scp.css */
/* Onglets du fil (mêmes proportions que le catalogue, scopés au composant). */
.onglets[b-oozgbq5fjr] {
    display: flex;
    gap: 2px;
    flex-wrap: wrap;
}
.onglet[b-oozgbq5fjr] {
    background: none;
    border: none;
    border-bottom: 2px solid transparent;
    padding: 6px 10px;
    font: inherit;
    font-size: 13px;
    color: var(--text-muted);
    cursor: pointer;
}
.onglet:hover[b-oozgbq5fjr] { color: var(--text-primary); }
.onglet.is-active[b-oozgbq5fjr] { color: var(--accent); border-bottom-color: var(--accent); }

/* ── Mode déplié : tous les volets sur le même écran ──────────────────────────
   L'historique (le plus long) prend la colonne de gauche ; rappels et fichiers
   s'empilent à droite. Sur écran étroit, tout retombe en une colonne.

   Tout visible en même temps ne suffit pas : sans frontière, le fil de
   l'historique et la liste des rappels se lisaient comme un seul bloc. D'où
   DEUX marqueurs qui se répondent — un filet qui sépare, un intitulé qui
   annonce. */
.panneaux.est-deplie[b-oozgbq5fjr] { display: grid; gap: 24px; }

/* Le filet entre deux volets empilés. Le trait tombe au milieu du creux :
   24 px de gouttière au-dessus, 24 px de retrait en dessous. */
.panneaux.est-deplie .panneau + .panneau[b-oozgbq5fjr] {
    border-top: 1px solid var(--border);
    padding-top: 24px;
}

@media (min-width: 1100px) {
    .panneaux.est-deplie[b-oozgbq5fjr] {
        grid-template-columns: minmax(0, 3fr) minmax(0, 2fr);
        column-gap: 0;
        align-items: start;

        /* Le filet vertical est peint sur le CONTENEUR, à la frontière des
           colonnes (3fr sur 5 = 60 %), et non en bordure d'un volet : il court
           ainsi sur toute la hauteur de la carte, que l'historique soit plus
           court ou plus long que la colonne de droite. */
        background: linear-gradient(var(--border), var(--border)) no-repeat 60% 0;
        background-size: 1px 100%;
    }
    .panneaux.est-deplie .panneau[b-oozgbq5fjr] { grid-column: 2; padding-left: 28px; }
    .panneaux.est-deplie .panneau-historique[b-oozgbq5fjr] {
        grid-column: 1;
        grid-row: 1;
        padding-left: 0;
        padding-right: 28px;
    }
    /* En colonnes, l'historique ne précède plus les rappels à la verticale :
       c'est le filet vertical qui fait la séparation. */
    .panneaux.est-deplie .panneau-historique + .panneau[b-oozgbq5fjr] {
        border-top: none;
        padding-top: 0;
    }
}

/* Intitulé de volet : la barre d'accent est le repère que l'œil accroche —
   en petites capitales grises seules, le titre se noyait dans le contenu. */
.panneau-titre[b-oozgbq5fjr] {
    display: flex;
    align-items: center;
    gap: 8px;
    font-size: 11px;
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--text-secondary);
    margin-bottom: 12px;
}
.panneau-titre[b-oozgbq5fjr]::before {
    content: "";
    width: 3px;
    height: 13px;
    border-radius: var(--radius-full);
    background: var(--accent);
    flex: none;
}

.saisie-activite[b-oozgbq5fjr] {
    border-bottom: 1px solid var(--border-subtle);
    padding-bottom: 12px;
    margin-bottom: 14px;
}

/* Le fil : une ligne de temps verticale, l'automatique en retrait visuel. */
.fil[b-oozgbq5fjr] { list-style: none; margin: 0; padding: 0; }
.fil-item[b-oozgbq5fjr] { display: flex; gap: 12px; padding: 10px 0; border-bottom: 1px solid var(--border-subtle); }
.fil-item:last-child[b-oozgbq5fjr] { border-bottom: none; }
.fil-marque[b-oozgbq5fjr] {
    width: 8px;
    height: 8px;
    margin-top: 6px;
    border-radius: 50%;
    background: var(--accent);
    flex: none;
}
.fil-item.est-systeme .fil-marque[b-oozgbq5fjr] { background: var(--border); }
.fil-item.est-systeme .fil-entete strong[b-oozgbq5fjr] { font-weight: 500; color: var(--text-secondary); }
.fil-corps[b-oozgbq5fjr] { min-width: 0; flex: 1; }
.fil-entete[b-oozgbq5fjr] { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; font-size: 13.5px; }
.fil-texte[b-oozgbq5fjr] { margin: 4px 0 0; font-size: 13px; color: var(--text-secondary); }
.fil-meta[b-oozgbq5fjr] { margin-top: 4px; font-size: 11.5px; color: var(--text-muted); display: flex; align-items: center; gap: 8px; }

.depot-fichier[b-oozgbq5fjr] {
    border-bottom: 1px solid var(--border-subtle);
    padding-bottom: 12px;
    margin-bottom: 14px;
}
/* /Components/Shared/MatriceAcces.razor.rz.scp.css */
/* La matrice « qui a le droit de quoi ».
   Le tableau lui-même vient du design system (.data-table dans un .data-scroll) ; ne
   restent ici que les réglages propres à une matrice — des colonnes nombreuses et
   étroites, et des cases qui se lisent d'une colonne à l'autre. */

.matrice-acces .mat-droit[b-ve4m9tuj9a] {
    /* Les en-têtes de droits sont étroites et nombreuses : le libellé s'y écrit sur
       deux lignes plutôt que d'étirer la table sur trois écrans. */
    white-space: normal;
    min-width: 74px;
    max-width: 92px;
    text-align: center;
}

.matrice-acces .mat-groupe[b-ve4m9tuj9a] { font-weight: 600; color: var(--text-primary); }
.matrice-acces .mat-case[b-ve4m9tuj9a] { text-align: center; }
.matrice-acces .mat-case.oui[b-ve4m9tuj9a] { color: var(--accent); font-weight: 700; }
.matrice-acces .mat-case.non[b-ve4m9tuj9a] { color: var(--text-muted); opacity: .4; }
.matrice-acces .mat-portee[b-ve4m9tuj9a] { color: var(--text-secondary); font-style: italic; }
/* /Components/Shared/PanneauConseilIngenierie.razor.rz.scp.css */
/* ─────────────────────────────────────────────────────────────────────────────
   Le panneau du conseil d'ingénierie.

   Un liseré à gauche porte la gravité la plus haute du lot : on sait au coup
   d'œil, sans lire, si le dossier a un point rouge. Les couleurs reprennent la
   grammaire de l'app — rouge = corriger, jaune = vérifier, bleu = améliorer,
   vert = rien de relevé — et les mêmes teintes que les pastilles d'app.css,
   avec le même relevé en thème sombre (le fond translucide tient, le TEXTE
   doit s'éclaircir).
   ───────────────────────────────────────────────────────────────────────────── */

.avis-carte[b-r7gqpam302] {
    border-left: 3px solid var(--border);
}

.avis-carte.est-bloquant[b-r7gqpam302]  { border-left-color: var(--status-danger); }
.avis-carte.est-attention[b-r7gqpam302] { border-left-color: var(--status-warning); }
.avis-carte.est-conseil[b-r7gqpam302]   { border-left-color: var(--accent); }
.avis-carte.est-sain[b-r7gqpam302]      { border-left-color: var(--status-success); }

.avis-liste[b-r7gqpam302] {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 10px;
}

.avis-item[b-r7gqpam302] {
    display: flex;
    gap: 10px;
    padding: 10px 12px;
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    background: var(--bg-glass);
}

/* Le symbole double la couleur : lisible à l'impression et pour un daltonien. */
.avis-symbole[b-r7gqpam302] {
    flex: 0 0 auto;
    width: 20px;
    height: 20px;
    border-radius: var(--radius-full);
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 12px;
    font-weight: 700;
    line-height: 1;
}

.avis-item.est-bloquant  .avis-symbole[b-r7gqpam302] { background: rgba(239, 68, 68, 0.15);  color: #b91c1c; }
.avis-item.est-attention .avis-symbole[b-r7gqpam302] { background: rgba(250, 204, 21, 0.22); color: #854d0e; }
.avis-item.est-conseil   .avis-symbole[b-r7gqpam302] { background: rgba(59, 130, 246, 0.16); color: #1d4ed8; }

[data-theme="dark"] .avis-item.est-bloquant  .avis-symbole[b-r7gqpam302] { color: #f87171; }
[data-theme="dark"] .avis-item.est-attention .avis-symbole[b-r7gqpam302] { color: #facc15; }
[data-theme="dark"] .avis-item.est-conseil   .avis-symbole[b-r7gqpam302] { color: #60a5fa; }

.avis-corps[b-r7gqpam302] { flex: 1; min-width: 0; }

.avis-entete[b-r7gqpam302] {
    display: flex;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
    margin-bottom: 4px;
}

.avis-titre[b-r7gqpam302] { font-size: 14px; color: var(--text-primary); }

.avis-constat[b-r7gqpam302],
.avis-reco[b-r7gqpam302],
.avis-reference[b-r7gqpam302] {
    margin: 0;
    font-size: 13px;
    line-height: 1.5;
}

.avis-constat[b-r7gqpam302] { color: var(--text-secondary); }
.avis-reco[b-r7gqpam302]    { color: var(--text-primary); margin-top: 4px; }

.avis-reference[b-r7gqpam302] {
    margin-top: 4px;
    font-size: 12px;
    color: var(--text-muted);
}

/* L'avertissement suit les avis comme la mention légale suit le prix : jamais l'un sans l'autre. */
.avis-avertissement[b-r7gqpam302] {
    margin: 14px 0 0;
    padding-top: 10px;
    border-top: 1px dashed var(--border);
    font-size: 12px;
    line-height: 1.55;
    color: var(--text-muted);
}

/* Le code de la règle : discret, mais c'est la clé qui mène au registre. */
.avis-code[b-r7gqpam302] {
    font-size: 11px;
    letter-spacing: 0.02em;
    color: var(--text-muted);
    background: var(--bg-glass);
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    padding: 1px 5px;
}

/* Ce que le robot a regardé — au-dessus de l'avertissement, dans le même ton. */
.avis-portee[b-r7gqpam302] {
    margin: 14px 0 0;
    padding-top: 10px;
    border-top: 1px dashed var(--border);
    font-size: 12px;
    line-height: 1.55;
    color: var(--text-muted);
}

.avis-portee strong[b-r7gqpam302] { color: var(--text-secondary); }
.avis-portee .btn-link[b-r7gqpam302] { margin-left: 8px; }

/* Les deux blocs de pied se suivent : un seul filet entre eux. */
.avis-portee + .avis-avertissement[b-r7gqpam302] {
    border-top: 0;
    margin-top: 6px;
    padding-top: 0;
}
/* /Components/Shared/PreferencesNotifications.razor.rz.scp.css */
/* Les types de notification : une grille de cases, lisible d'un coup d'œil plutôt
   qu'une longue colonne qu'il faut faire défiler. */
.pref-notif-types[b-ekrpa44oy8] {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
    gap: 4px 16px;
}
/* /Components/Shared/RapportsSurDemande.razor.rz.scp.css */
/* Les filtres : des pastilles `.chip` (style guide, section Buttons) sur une rangée
   qui se replie — un filtre de plus ne casse pas la mise en page. */
.chip-rangee[b-wh4i5h7gjb] {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 6px;
}

.case-a-cocher[b-wh4i5h7gjb] {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    font-size: 13px;
    font-weight: 400;
    color: var(--text-secondary);
}

/* Un rapport a autant de colonnes qu'il a de postes : la table défile dans sa carte,
   la page, elle, ne défile jamais latéralement. */
.table-large[b-wh4i5h7gjb] {
    overflow-x: auto;
    margin-top: 16px;
}

/* Entête de groupe (un poste = pcs / lb / $) — séparé du groupe voisin. */
.groupe-poste[b-wh4i5h7gjb] {
    border-left: 1px solid var(--border);
    text-align: center;
}

/* Une période sans production reste visible, en retrait : un trou de production
   qu'on ne voit pas est un trou qu'on n'explique pas. */
.periode-vide[b-wh4i5h7gjb] { color: var(--text-muted); }

.etape-choisie[b-wh4i5h7gjb] { background: var(--accent-soft); }

.kpi-grid[b-wh4i5h7gjb] { margin-top: 16px; }
