﻿/* =================================================================
   S3-Hub — COMMON STYLES (refactorisé)
   ================================================================= */

/* =================================================================
   1. VARIABLES
   ================================================================= */
:root {
    /* ── Palette S3 Hub ───────────────────────────────────────── */
    --color-navy: #0B2E47;
    --color-navy-light: #163C58;
    --color-cyan: #35C6EE;
    --color-cyan-dark: #009DC4;
    --color-surface: #F4F6F8;
    /* ── Tokens hérités (mappés sur la nouvelle palette) ─────── */
    --common-background-principal: var(--color-navy);
    --common-gradient: linear-gradient(135deg, var(--color-cyan-dark) 0%, var(--color-navy) 100%);
    --common-background-secondaire: #E8F6FB;
    --common-borders: #D0DDE8;
    --common-div-cornerradius: 8px;
    /* Texte */
    --text-primary: #1A2B38;
    --text-secondary: #4A6070;
    --text-muted: #8A9BAA;
    /* Bordures */
    --border-light: #E8EEF3;
    --border-medium: #D0DDE8;
    /* Fonds */
    --background-hover: var(--color-surface);
    --background-active: #E8F6FB;
    /* Spacing */
    --spacing-xs: 4px;
    --spacing-sm: 8px;
    --spacing-md: 12px;
    --spacing-lg: 16px;
    --spacing-xl: 20px;
    --spacing-xxl: 24px;
    /* Couleurs sémantiques */
    --color-primary: var(--color-cyan-dark);
    --color-danger: #e74c3c;
    --color-warning: #f0a500;
    --color-info: var(--color-cyan);
    --color-success: #27ae60;
}

/* =================================================================
   2. RESET & BASE
   ================================================================= */
*,
*::before,
*::after {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}

body, html {
    margin: 0;
    padding: 0;
    height: 100%;
    overflow: hidden;
}

/* ── Bandeau dev travaux ── */
.dev-banner {
    background: repeating-linear-gradient( -45deg, #f5c518, #f5c518 10px, #1a1a1a 10px, #1a1a1a 20px );
    color: #fff;
    text-align: center;
    padding: 6px 0;
    font-size: 12px;
    font-weight: 800;
    letter-spacing: 2px;
    text-transform: uppercase;
    flex-shrink: 0;
    z-index: 9999;
    text-shadow: 0 1px 3px rgba(0,0,0,0.7);
}

.dev-banner-span {
    background: #f5c518;
    color: #1a1a1a;
    padding: 3px 16px;
    border-radius: 4px;
    text-shadow: none;
}

/* =================================================================
   3. MAIN LAYOUT
   ================================================================= */
.app-root {
    display: flex;
    flex-direction: column;
    height: 100dvh;
    overflow: hidden;
}

.page {
    background: #f5f5f5;
    display: flex;
    flex-direction: row;
    flex: 1;
    min-height: 0;
    margin: 0;
    padding: 0;
}

.sidebar {
    width: 264px;
    flex-shrink: 0;
    background: white;
    position: relative;
}

    .sidebar::after {
        content: '';
        position: absolute;
        top: 0;
        right: 0;
        width: 1px;
        height: 100%;
        background: var(--border-light);
    }

/* ── Hamburger mobile : masqué sur desktop, fixed en haut à DROITE en mobile,
   en overlay du contenu (pas de réserve d'espace pour qu'il prenne le moins
   possible). Au clic, toggle de .mobile-menu-open sur .app-root. */
.nav-mobile-toggle {
    display: none; /* visible uniquement via @media (max-width: 900px) plus bas */
    position: fixed;
    top: 8px;
    right: 8px;
    z-index: 1100;
    width: 38px;
    height: 38px;
    border-radius: 8px;
    border: 1px solid rgba(11, 46, 71, 0.18);
    /* Fond translucide blanc pour rester lisible sur tout fond ; backdrop-filter
       blur pour brouiller légèrement le contenu derrière (effet glass). */
    background: rgba(255, 255, 255, 0.85);
    -webkit-backdrop-filter: blur(8px);
    backdrop-filter: blur(8px);
    color: #0B2E47;
    font-size: 20px;
    line-height: 1;
    cursor: pointer;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.12);
    align-items: center;
    justify-content: center;
    padding: 0;
}

    .nav-mobile-toggle:hover {
        background: rgba(255, 255, 255, 0.95);
        border-color: rgba(11, 46, 71, 0.3);
    }

.nav-mobile-backdrop {
    display: none;
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0.5);
    z-index: 999;
    backdrop-filter: blur(2px);
}

/* Responsive : sidebar masquée hors écran sur ≤ 900 px (tablette portrait
   et mobile), révélée via translateX(0) quand .app-root.mobile-menu-open.
   Le scroll de la page devient natif (au lieu du flex magic desktop) pour
   que les headers de page ne soient pas figés et défilent avec le contenu. */
@media (max-width: 900px) {
    .nav-mobile-toggle {
        display: flex;
    }

    .nav-mobile-backdrop {
        display: block;
    }

    /* Scroll natif du document — sinon body/html overflow:hidden + .app-root
       height:100dvh bloquent tout scroll au niveau document. */
    html, body {
        height: auto;
        overflow-y: auto;
        overflow-x: hidden;
        -webkit-overflow-scrolling: touch; /* inertie iOS Safari */
    }

    .app-root {
        height: auto;
        min-height: 100dvh;
        overflow: visible;
    }

    .page {
        position: relative;
        min-height: 100dvh;
        flex-direction: column;
    }

    main {
        overflow: visible;
        flex: none;
        height: auto;
    }

    /* .content / .container / .content-scrollable : annulation du flex magic
       pour que tout le contenu coule en bloc et scrolle naturellement avec
       le document. min-height:0 reste utile pour les enfants flex internes. */
    .content {
        flex: none;
        height: auto;
        min-height: 0;
    }

    .container {
        flex: none;
        height: auto;
        min-height: 0;
        overflow: visible;
        padding: 12px;
    }

    .content-scrollable {
        overflow: visible;
        flex: none;
        height: auto;
        min-height: 0;
    }

    /* Pas de padding-top sur le main : le bouton ☰ est en overlay top-right
       (semi-transparent, par-dessus le contenu) — il ne réserve pas d'espace. */

    .sidebar {
        position: fixed;
        top: 0;
        left: 0;
        bottom: 0;
        z-index: 1000;
        transform: translateX(-100%);
        transition: transform 0.25s ease;
        box-shadow: 4px 0 16px rgba(0, 0, 0, 0.15);
    }

    .app-root.mobile-menu-open .sidebar {
        transform: translateX(0);
    }
}

main {
    flex-grow: 1;
    margin: 0;
    padding: 0;
    overflow: hidden;
    display: flex;
    flex-direction: column;
    background: #f5f5f5;
}

.content {
    flex: 1;
    min-height: 0;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
}

/* =================================================================
   4. PAGE LAYOUT — Container & Header
   ================================================================= */
.container {
    display: flex;
    flex-direction: column;
    flex: 1;
    min-height: 0;
    background: var(--common-background-secondaire);
    padding: 20px;
}

.page-header {
    flex-shrink: 0;
    background: white;
    padding: 20px;
    border-radius: var(--common-div-cornerradius);
    margin-bottom: 20px;
    box-shadow: 0 2px 4px rgba(0,0,0,0.1);
    display: flex;
    justify-content: space-between;
    align-items: center;
}

.page-header-title {
    font-size: 24px;
    font-weight: 700;
    color: #2c3e50;
    margin-bottom: 8px;
}

.page-header-subtitle {
    color: #7f8c8d;
    font-size: 14px;
}

.content-scrollable {
    flex: 1;
    min-height: 0;
    overflow-y: auto;
    padding: 0;
}


/* =================================================================
   5. TITRES
   ================================================================= */
h1, h2, h3, h4, h5, h6 {
    margin: 0;
    padding: 0;
    font-weight: 600;
    color: var(--text-primary);
}

h1 {
    font-size: 1.75rem;
    margin-bottom: 0.875rem;
}

h2 {
    font-size: 1.5rem;
    margin-bottom: 0.75rem;
}

h3 {
    /* 1.125rem = 18px (avant 1.25rem = 20px). Réduction de 2pt pour
       alléger l'impact visuel des titres de blocs (cartes paramétrage,
       sections de pages). Les dialogs gardent leur propre taille via
       le sélecteur spécifique `.header-title h3` plus bas. */
    font-size: 1.125rem;
}

/* Titre de bloc paramétrage — style centralisé, à appliquer sur toutes les
   pages de paramétrage (briques Lavage et Facturation). Calque le rendu jugé
   nominal sur la page TVA & comptes : font 13px semi-bold, couleur sombre,
   séparateur fin sous le titre qui clarifie visuellement la lecture entre
   le titre et le contenu du bloc.
   Remplace les anciens `<h3 style="margin:0 0 12px 0;">📷 Titre</h3>`. */
.s3-block-title {
    font-size: 13px;
    font-weight: 600;
    color: #334155;
    border-bottom: 1px solid #e2e8f0;
    padding-bottom: 6px;
    margin: 0 0 14px 0;
    display: flex;
    align-items: center;
    gap: 8px;
}

/* ============================================================
   DIALOG TOKENS — variables centrales pour tous les dialogs.
   Modifier ces valeurs propage à TOUS les S3Dialog de l'app.
   ============================================================ */
:root {
    /* Padding horizontal commun header/content/footer (alignement vertical) */
    --s3-dialog-padding-x: 24px;

    /* Header */
    --s3-dialog-header-padding-y: 14px;
    --s3-dialog-header-bg: white;
    --s3-dialog-header-border: 1px solid var(--border-light);
    --s3-dialog-title-size: 15px;
    --s3-dialog-title-weight: 700;
    --s3-dialog-subtitle-size: 12px;
    --s3-dialog-icon-size: 20px;
    --s3-dialog-title-gap: 10px;

    /* Content */
    --s3-dialog-content-padding-y: 20px;
    --s3-dialog-content-font-size: 13px;
    --s3-dialog-content-gap: 16px;

    /* Footer */
    --s3-dialog-footer-padding-y: 12px;
    --s3-dialog-footer-bg: #f8fafc;
    --s3-dialog-footer-border: 1px solid var(--border-light);
    --s3-dialog-footer-gap: 8px;

    /* Panel — radius, shadow, scrim */
    --s3-dialog-panel-radius: 12px;
    --s3-dialog-panel-shadow: 0 8px 32px rgba(0, 0, 0, 0.3);
    --s3-dialog-scrim-color: rgba(0, 0, 0, 0.5);
}

/* Header-title — bloc titre avec séparation (S3Dialog, drawers, dialogs) */
.header-title {
    padding: var(--s3-dialog-header-padding-y) var(--s3-dialog-padding-x);
    margin: 0;
    border-bottom: var(--s3-dialog-header-border);
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: var(--s3-dialog-title-gap);
    background: var(--s3-dialog-header-bg);
    flex-shrink: 0;
}

    .header-title h2,
    .header-title h3 {
        font-size: var(--s3-dialog-title-size);
        font-weight: var(--s3-dialog-title-weight);
        color: var(--text-primary);
        margin: 0;
        white-space: nowrap;
        overflow: hidden;
        text-overflow: ellipsis;
    }

/* =================================================================
   6. BOUTONS
   ================================================================= */

/* — Base — */
.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 4px;
    vertical-align: middle;
    padding: 8px 20px;
    border: none;
    border-radius: var(--common-div-cornerradius);
    font-size: 13px;
    font-weight: 600;
    cursor: pointer;
    transition: all 0.2s;
    font-family: inherit;
    text-decoration: none;
}

/* — Variantes — */
.btn-primary {
    background: #3b82f6;
    color: white;
    border: none;
}

    .btn-primary:hover {
        background: #2563eb;
    }

    .btn-primary:disabled {
        background: #e5e7eb;
        color: #9ca3af;
        cursor: not-allowed;
    }

.btn-secondary {
    background: #f0f0f0;
    color: var(--text-primary);
    border: 1px solid #e0e0e0;
    padding: 8px 16px;
}

    .btn-secondary:hover {
        background: #e8e8e8;
        border-color: #d0d0d0;
    }

    .btn-secondary:disabled {
        opacity: 0.5;
        cursor: not-allowed;
    }

.btn-cancel {
    background: white;
    color: var(--text-secondary);
    border: 1px solid var(--border-medium);
}

    .btn-cancel:hover {
        background: var(--background-hover);
    }

.btn-danger {
    background: var(--color-danger);
    color: white;
    border: none;
    padding: 8px 16px;
    border-radius: var(--common-div-cornerradius);
    cursor: pointer;
    font-weight: 600;
    transition: all 0.3s;
}

    .btn-danger:hover {
        background: #c0392b;
    }

.btn-warning {
    background: var(--color-warning);
    color: white;
    border: none;
    padding: 8px 16px;
    border-radius: var(--common-div-cornerradius);
    cursor: pointer;
    font-weight: 600;
    transition: all 0.3s;
}

    .btn-warning:hover {
        background: #d18f00;
    }

.btn-success {
    background: linear-gradient(135deg, #f39c12 0%, #27ae60 100%);
    color: white;
    box-shadow: 0 2px 8px rgba(39, 174, 96, 0.4);
}

    .btn-success:hover {
        background: linear-gradient(135deg, #e67e22 0%, #219a52 100%);
        transform: translateY(-1px);
        box-shadow: 0 4px 12px rgba(39, 174, 96, 0.5);
    }

/* — Action (rond petit, icône) — */
.btn-action {
    width: 23px;
    height: 23px;
    border-radius: 50%;
    border: none;
    cursor: pointer;
    display: inline-flex !important;
    align-items: center !important;
    justify-content: center !important;
    font-size: 12px;
    transition: transform .15s, box-shadow .15s, opacity .15s;
    flex-shrink: 0;
    line-height: 1 !important;
    padding: 0 !important;
}

    .btn-action .material-icons {
        font-size: 16px;
        color: white;
        line-height: 1;
    }

    .btn-action .mud-icon-root {
        display: flex !important;
        font-size: 16px !important;
        color: white !important;
        width: 14px !important;
        height: 14px !important;
    }

    .btn-action svg {
        width: 14px !important;
        height: 14px !important;
        display: block;
    }

    .btn-action:hover {
        transform: scale(1.12);
        box-shadow: 0 3px 10px rgba(0,0,0,.2);
    }

    .btn-action:active {
        transform: scale(.95);
    }

    .btn-action:disabled {
        opacity: .4;
        cursor: default;
        transform: none;
        box-shadow: none;
    }

.btn-action-green {
    background: #e8f8f0 !important;
    border: 1.5px solid #6fcf97 !important;
    color: #27ae60 !important;
}

    .btn-action-green .mud-icon-root,
    .btn-action-green svg,
    .btn-action-green .material-icons {
        color: #27ae60 !important;
    }

.btn-action-red {
    background: #fdecea !important;
    border: 1.5px solid #e9908a !important;
    color: #e53935 !important;
}

    .btn-action-red .mud-icon-root,
    .btn-action-red svg,
    .btn-action-red .material-icons {
        color: #e53935 !important;
    }

.btn-action-orange {
    background: #fff4e5 !important;
    border: 1.5px solid #f0b27a !important;
    color: #e67e22 !important;
}

    .btn-action-orange .mud-icon-root,
    .btn-action-orange svg,
    .btn-action-orange .material-icons {
        color: #e67e22 !important;
    }

.btn-action-blue {
    background: #E8F6FB !important;
    border: 1.5px solid var(--color-cyan) !important;
    color: var(--color-cyan-dark) !important;
}

    .btn-action-blue .mud-icon-root,
    .btn-action-blue svg,
    .btn-action-blue .material-icons {
        color: var(--color-cyan-dark) !important;
    }

.btn-action-grey {
    background: #f2f3f4 !important;
    border: 1.5px solid #bdc3c7 !important;
    color: #7f8c8d !important;
}

    .btn-action-grey .mud-icon-root,
    .btn-action-grey svg,
    .btn-action-grey .material-icons {
        color: #7f8c8d !important;
    }

/* ── Bouton retour ── */
.btn-back {
    width: 32px;
    height: 32px;
    border-radius: 50%;
    border: 1.5px solid var(--border-light);
    background: white;
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    transition: background .15s, border-color .15s, transform .15s;
    flex-shrink: 0;
    padding: 0;
    color: var(--text-secondary);
}

    .btn-back:hover {
        background: #f0f0f0;
        border-color: #aaa;
        transform: scale(1.08);
    }

    .btn-back .material-icons {
        font-size: 18px;
        color: var(--text-secondary);
    }

/* =================================================================
   7. FORMULAIRES
   ================================================================= */
.form-grid {
    display: grid;
    grid-template-columns: repeat(12, 1fr);
    gap: var(--spacing-lg);
}

.form-group {
    display: flex;
    flex-direction: column;
}

.col-12 {
    grid-column: span 12;
}

.col-8 {
    grid-column: span 8;
}

.col-6 {
    grid-column: span 6;
}

.col-4 {
    grid-column: span 4;
}

.col-3 {
    grid-column: span 3;
}

.col-2 {
    grid-column: span 2;
}

@media (max-width: 768px) {
    .col-8, .col-6, .col-4, .col-3, .col-2 {
        grid-column: span 12;
    }
}

label {
    font-size: 13px;
    color: var(--text-secondary);
    margin-bottom: 6px;
    font-weight: 500;
}

    label .required {
        color: #f44336;
    }

/* ── Style unifié des inputs natifs : blanc, 32px, 12px, radius 10px ─── */
input[type="text"],
input[type="number"],
input[type="password"],
input[type="email"],
input[type="search"],
input[type="tel"],
input[type="url"],
input[type="date"],
input[type="datetime-local"],
input[type="time"],
select {
    height: 32px;
    padding: 0 12px;
    border: 1px solid #e2e8f0;
    border-radius: 10px;
    font-size: 12px;
    font-family: inherit;
    transition: border-color 0.15s, box-shadow 0.15s;
    background: white;
    box-sizing: border-box;
}

textarea {
    min-height: 32px;
    padding: 8px 12px;
    border: 1px solid #e2e8f0;
    border-radius: 10px;
    font-size: 12px;
    font-family: inherit;
    transition: border-color 0.15s, box-shadow 0.15s;
    background: white;
    line-height: 1.5;
    box-sizing: border-box;
}

    input[type="text"]:focus,
    input[type="number"]:focus,
    input[type="password"]:focus,
    input[type="email"]:focus,
    input[type="search"]:focus,
    input[type="tel"]:focus,
    input[type="url"]:focus,
    input[type="date"]:focus,
    input[type="datetime-local"]:focus,
    input[type="time"]:focus,
    textarea:focus,
    select:focus {
        outline: none;
        /* Aucun changement visuel au focus : pas de border-color change
           ni de box-shadow. La bordure d'arrière-plan de l'input reste la seule visible. */
        box-shadow: none;
    }

/* ── Champ modifié (non sauvegardé) ──────────────────────── */
input.field-dirty,
textarea.field-dirty,
select.field-dirty {
    border-color: #e8910c !important;
    box-shadow: 0 0 0 2px rgba(232, 145, 12, 0.15) !important;
}

input[type="checkbox"].field-dirty {
    outline: 2px solid #e8910c !important;
    outline-offset: 2px;
    box-shadow: none !important;
}

/* MudBlazor : encadrer le conteneur mud quand dirty */
.mud-input-control.field-dirty .mud-input-outlined-border,
.mud-input-control.field-dirty .mud-input > input {
    border-color: #e8910c !important;
}

.mud-input-control.field-dirty .mud-input-slot {
    border-color: #e8910c !important;
    box-shadow: 0 0 0 2px rgba(232, 145, 12, 0.15) !important;
}

/* MudSelect / MudAutocomplete / MudDatePicker */
.mud-select.field-dirty .mud-input-outlined-border,
.mud-picker.field-dirty .mud-input-outlined-border {
    border-color: #e8910c !important;
}

/* Radio horizontal */
.radio-group-horizontal {
    display: flex;
    gap: var(--spacing-lg);
    flex-wrap: wrap;
}

.radio-label-inline {
    display: flex;
    align-items: center;
    gap: var(--spacing-sm);
    cursor: pointer;
    padding: 8px 12px;
    border: 1px solid var(--border-light);
    border-radius: var(--common-div-cornerradius);
    transition: all 0.2s;
    background: white;
}

    .radio-label-inline:hover {
        border-color: var(--color-primary);
        background: var(--background-active);
    }

    .radio-label-inline input[type="radio"] {
        margin: 0;
        cursor: pointer;
    }

/* Erreurs */
.error-message {
    color: #f44336;
    font-size: 12px;
    margin-top: 4px;
    display: none;
}

input:invalid ~ .error-message,
textarea:invalid ~ .error-message {
    display: block;
}

/* =================================================================
   8. SWITCH TOGGLE
      Utilisation :
        <label class="switch-toggle">            (bleu par défaut)
        <label class="switch-toggle switch-red">  (rouge)
        <label class="switch-toggle switch-warning"> (jaune-orangé)
        <label class="switch-toggle switch-info">    (bleu clair)
            <input type="checkbox" ...>
            <span class="switch-slider"></span>
        </label>
   ================================================================= */
.switch-toggle {
    position: relative;
    display: inline-block;
    width: 44px;
    height: 22px;
    flex-shrink: 0;
}

    .switch-toggle input {
        opacity: 0;
        width: 0;
        height: 0;
    }

.switch-slider {
    position: absolute;
    cursor: pointer;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    background-color: #ccc;
    transition: 0.3s;
    border-radius: 22px;
}

    .switch-slider::before {
        position: absolute;
        content: "";
        height: 16px;
        width: 16px;
        left: 3px;
        bottom: 3px;
        background-color: white;
        transition: 0.3s;
        border-radius: 50%;
    }

/* — Checked : couleur par défaut (bleu primary) — */
.switch-toggle input:checked + .switch-slider {
    background-color: var(--color-primary);
}

    .switch-toggle input:checked + .switch-slider::before {
        transform: translateX(22px);
    }

/* — Variante rouge — */
.switch-toggle.switch-red input:checked + .switch-slider {
    background-color: var(--color-danger);
}

/* — Variante jaune-orangé — */
.switch-toggle.switch-warning input:checked + .switch-slider {
    background-color: var(--color-warning);
}

/* — Variante bleu clair — */
.switch-toggle.switch-info input:checked + .switch-slider {
    background-color: var(--color-info);
}

.switch-toggle.switch-orange input:checked + .switch-slider {
    background-color: #ff9800;
}

    .switch-toggle.switch-orange input:checked + .switch-slider::before {
        transform: translateX(20px);
    }

/* — Disabled — */
.switch-toggle input:disabled + .switch-slider {
    opacity: 0.5;
    cursor: not-allowed;
}

/* Conteneur label + switch */
.switch-container {
    display: flex;
    align-items: center;
    gap: 12px;
}

/* =================================================================
   9. DIALOGS
   ================================================================= */

/* Reset MudBlazor defaults pour laisser nos classes gérer l'espacement */
.mud-dialog {
    background: white !important;
    overflow: hidden !important;
}

.mud-dialog-content {
    padding: 0 !important;
    max-height: 80vh !important;
    overflow-y: auto !important;
}

/* Le click-away du S3RichSelect est un <div> natif transparent — pas un
   MudOverlay (qui masquait le scrim sombre du dialog parent dans certaines
   versions MudBlazor). Pas de styles CSS nécessaires : tout est inline. */

/* — Corps du dialog (S3Dialog, MudDialog wrappés, etc.) — */
.dialog-content {
    padding: var(--s3-dialog-content-padding-y) var(--s3-dialog-padding-x);
    overflow-y: auto;
    font-size: var(--s3-dialog-content-font-size);
    /* Espacement vertical entre champs : appliqué via flex-direction column */
    display: flex;
    flex-direction: column;
    gap: var(--s3-dialog-content-gap);
}

/* Quand le dialog-content est dans un .s3-dialog-panel, sa hauteur est
   gérée par flex (panel = flex column, content = flex:1). Sinon (MudDialog),
   on fixe une max-height pour éviter le débordement viewport. */
.dialog-content:not(.s3-dialog-panel > .dialog-content) {
    max-height: calc(90vh - 120px);
}

/* — Footer du dialog — */
.dialog-actions {
    display: flex;
    justify-content: flex-end;
    align-items: center;
    gap: var(--s3-dialog-footer-gap);
    padding: var(--s3-dialog-footer-padding-y) var(--s3-dialog-padding-x);
    border-top: var(--s3-dialog-footer-border);
    background: var(--s3-dialog-footer-bg);
    flex-shrink: 0;
}

/* — Bouton fermeture × — */
.close-btn {
    background: none;
    border: none;
    font-size: 20px;
    color: var(--text-secondary);
    cursor: pointer;
    padding: 2px 6px;
    border-radius: 4px;
    transition: color 0.15s;
    line-height: 1;
    flex-shrink: 0;
}

    .close-btn:hover {
        color: var(--color-danger, #e53e3e);
    }

/* =================================================================
   9b. S3DIALOG — composant dialog standard de l'app
   Voir Components/Shared/S3Dialog.razor
   100% paramétrable via les variables --s3-dialog-* en haut du fichier.
   Aucun style inline ne doit override ces classes — modifier les vars
   pour propagation globale.
   ================================================================= */

/* Scrim sombre couvrant la page (z-index appliqué inline par le composant) */
.s3-dialog-scrim {
    position: fixed;
    inset: 0;
    background: var(--s3-dialog-scrim-color);
}

/* Panneau central — centré via transform. width/max-height/z-index inline. */
.s3-dialog-panel {
    position: fixed;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    width: var(--s3-dialog-width, 600px);
    max-width: calc(100vw - 32px);
    max-height: var(--s3-dialog-max-height, 90vh);
    background: white;
    border-radius: var(--s3-dialog-panel-radius);
    box-shadow: var(--s3-dialog-panel-shadow);
    display: flex;
    flex-direction: column;
    overflow: hidden;
    /* Contenu scrolle, header/footer restent collés */
}

.s3-dialog-panel > .dialog-content {
    flex: 1 1 auto;
    min-height: 0;
    max-height: none;
}

/* Bloc icône + titres dans le header */
.s3-dialog-title-wrap {
    display: flex;
    align-items: center;
    gap: var(--s3-dialog-title-gap);
    min-width: 0;
    flex: 1 1 auto;
}

.s3-dialog-icon {
    font-size: var(--s3-dialog-icon-size);
    flex-shrink: 0;
    line-height: 1;
}

.s3-dialog-titles {
    min-width: 0;
    display: flex;
    flex-direction: column;
}

.s3-dialog-subtitle {
    font-size: var(--s3-dialog-subtitle-size);
    color: var(--text-muted);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.s3-dialog-header-actions {
    display: flex;
    align-items: center;
    gap: 8px;
    flex-shrink: 0;
}

/* =================================================================
   10. DATAGRID / MUD TABLE
   ================================================================= */

.S3-Hub-datagrid {
    border-radius: var(--common-div-cornerradius) !important;
    overflow: hidden;
}

/* — Champ de recherche compact (filled) dans les toolbars datagrid — */
.S3-Hub-datagrid .mud-toolbar .mud-input-control-input-container .mud-input.mud-input-filled {
    height: 34px !important;
    border-radius: 6px !important;
    padding-left: 5px !important;
    font-size: 13px !important;
    background: #f5f6f8 !important;
}
.S3-Hub-datagrid .mud-toolbar .mud-input-control-input-container .mud-input.mud-input-filled::before,
.S3-Hub-datagrid .mud-toolbar .mud-input-control-input-container .mud-input.mud-input-filled::after {
    border-bottom: none !important;
}
.S3-Hub-datagrid .mud-toolbar .mud-input-control-input-container .mud-input-filled .mud-input-slot {
    padding-top: 5px !important;
    padding-bottom: 5px !important;
    padding-left: 5px !important;
}
.S3-Hub-datagrid .mud-toolbar .mud-input-control {
    margin: 0 12px !important;
}
.S3-Hub-datagrid .mud-toolbar .mud-input-control-input-container .mud-input-adornment-start {
    margin-left: 4px !important;
    margin-top: -4px !important;
}

/* — Taille de police compacte sur toutes les cellules — */
.S3-Hub-datagrid .mud-table-cell {
    font-size: 12px !important;
    line-height: 1.35 !important;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    max-width: 220px;
}

.S3-Hub-datagrid .mud-table-cell .mud-typography {
    font-size: 12px !important;
    line-height: 1.35 !important;
    margin: 0 !important;
}

/* — En-têtes compacts + sticky — */
.S3-Hub-datagrid .mud-table-head th {
    font-size: 11px !important;
    font-weight: 700 !important;
    white-space: nowrap;
    position: sticky;
    top: 0;
    z-index: 2;
    background: white;
}

/* Conteneur scrollable nécessaire pour sticky thead */
.S3-Hub-datagrid .mud-table-container {
    overflow-y: auto;
}

/* — Cellules autorisées à wrapper (libellés longs) — */
.S3-Hub-datagrid .mud-table-cell.cell-wrap {
    white-space: normal !important;
    overflow: visible !important;
    text-overflow: unset !important;
}

.S3-Hub-datagrid .mud-table-body .mud-table-row {
    cursor: pointer;
}

/* — Arrondi uniforme — */
.mud-table-root,
.mud-table,
.mud-paper.mud-table-container-root {
    border-radius: var(--common-div-cornerradius) !important;
    overflow: hidden !important;
}

/* — Container scrollable + header fixe — */
.mud-table-container {
    max-height: calc(100vh - 270px);
    overflow-y: auto !important;
    position: relative;
    border-radius: var(--common-div-cornerradius) !important;
}

.mud-table-head {
    position: sticky !important;
    top: 0 !important;
    z-index: 10 !important;
}

    .mud-table-head th {
        position: sticky !important;
        top: 0 !important;
        background: white !important;
        z-index: 10 !important;
        box-shadow: 0 1px 3px rgba(0,0,0,0.1) !important;
    }

.mud-table-toolbar {
    position: sticky !important;
    top: 0 !important;
    z-index: 11 !important;
    background: white !important;
}

/* — Clickable rows — */
.clickable-row {
    cursor: pointer;
}

    .clickable-row:hover {
        background-color: rgba(0,0,0,0.04) !important;
    }

/* — Compact grid — */
.compact-grid .mud-table-cell {
    font-size: 12px !important;
    padding: 6px 10px !important;
}

.compact-grid .mud-table-head .mud-table-cell {
    font-size: 12px !important;
    padding: 8px 10px !important;
    font-weight: 600 !important;
}

.compact-grid .mud-table-row {
    height: 38px !important;
    cursor: pointer;
}

/* — Selected row — */
.mud-table-row.selected-row td {
    background-color: var(--background-active) !important;
}

/* =================================================================
   11. SECTIONS
   ================================================================= */
.section-title {
    font-size: 14px;
    font-weight: 600;
    color: var(--text-primary);
    margin-bottom: var(--spacing-md);
}

/* =================================================================
   12. CARDS & CONTAINERS
   ================================================================= */

/* Data grid wrapper */
.data-grid-container {
    background: white;
    border-radius: var(--common-div-cornerradius);
    padding: 20px;
    box-shadow: 0 2px 4px rgba(0,0,0,0.1);
}

/* Settings card */
.settings-card {
    background: white;
    border-radius: 12px;
    padding: 24px;
    margin-bottom: 20px;
    border: 1px solid var(--border-light);
    box-shadow: 0 2px 8px rgba(0,0,0,.06);
}

.settings-card-title {
    font-size: 14px;
    font-weight: 700;
    color: #3d4f5f;
    margin-bottom: 16px;
    display: flex;
    align-items: center;
    gap: 8px;
}

/* ── Brick permission card — regroupe toggle + permissions par brique ── */
.brick-card {
    border: 1px solid #e0e0e0;
    border-radius: 10px;
    padding: 16px;
    margin-bottom: 12px;
    background: #fff;
}

.brick-card-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
}

.brick-card-header.has-content {
    padding-bottom: 12px;
    border-bottom: 1px solid #f0f0f0;
    margin-bottom: 12px;
}

.brick-card-title {
    font-size: 14px;
    font-weight: 700;
    color: #3d4f5f;
}

.settings-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 10px 0;
    border-bottom: 1px solid #f0f0f0;
    font-size: 13px;
    color: #4a5568;
}

    .settings-row:last-child {
        border-bottom: none;
    }

.settings-label {
    font-size: 13px;
    font-weight: 600;
    color: #3d4f5f;
}

.settings-sublabel {
    font-size: 11px;
    color: #888;
    margin-top: 2px;
}

/* =================================================================
   13. EMPTY STATE
   ================================================================= */
.empty-state {
    text-align: center;
    padding: 60px 20px;
    color: #7f8c8d;
}

.empty-state-icon {
    font-size: 64px;
    margin-bottom: 20px;
}

.empty-state-title {
    font-size: 20px;
    font-weight: 600;
    margin-bottom: 8px;
}

.empty-state-text {
    font-size: 14px;
}

/* =================================================================
   14. BADGES
   ================================================================= */
.total-badge {
    background: var(--common-gradient);
    color: white;
    padding: 8px 16px;
    border-radius: 20px;
    font-weight: 600;
    display: inline-block;
}


.badge {
    font-size: 11px;
    font-weight: 600;
    padding: 2px 8px;
    border-radius: 12px;
}

.badge-bleu {
    background: #e8f0fe;
    color: #1a73e8;
}

.badge-rouge {
    background: #e6f4ea;
    color: #137333;
}

.badge-access {
    font-size: 10px;
    font-weight: 600;
    padding: 2px 8px;
    border-radius: 10px;
    white-space: nowrap;
}

.badge-web {
    background: #e8f0fe;
    color: #1a73e8;
}

.badge-connect {
    background: #e6f4ea;
    color: #137333;
}

/* =================================================================
   TAG CHIPS (véhicules / salariés)
   Forme carrée (border-radius 3px) pour distinguer des badges ronds.
   Couleur de fond dynamique, texte auto-contraste via var --tag-fg.
   ================================================================= */
.tag-chip {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    font-size: 11px;
    font-weight: 600;
    line-height: 1.2;
    padding: 2px 8px;
    border-radius: 3px;
    white-space: nowrap;
    letter-spacing: 0.2px;
}

.tag-chip.tag-chip-sm {
    font-size: 10px;
    padding: 1px 6px;
}

.tag-chip .tag-chip-remove {
    cursor: pointer;
    opacity: 0.7;
    font-size: 12px;
    line-height: 1;
}

    .tag-chip .tag-chip-remove:hover {
        opacity: 1;
    }

.tag-chip-list {
    display: inline-flex;
    flex-wrap: wrap;
    gap: 4px;
    align-items: center;
}

.tag-palette-swatch {
    width: 28px;
    height: 28px;
    border-radius: 3px;
    cursor: pointer;
    border: 2px solid transparent;
    transition: transform 0.1s, border-color 0.1s;
}

    .tag-palette-swatch:hover {
        transform: scale(1.1);
    }

    .tag-palette-swatch.selected {
        border-color: #000;
    }


/* =================================================================
   15. DROP ZONE (Upload)
   ================================================================= */
.drop-zone-upload {
    border: 2px dashed var(--color-primary);
    border-radius: var(--common-div-cornerradius);
    padding: 32px;
    text-align: center;
    background: var(--background-active);
    cursor: pointer;
    margin-top: var(--spacing-md);
    transition: all 0.2s;
    display: block;
    min-height: 160px;
}

    .drop-zone-upload:hover {
        background: var(--background-active);
        border-color: #5566dd;
        transform: translateY(-2px);
        box-shadow: 0 4px 12px rgba(102, 126, 234, 0.2);
    }

    .drop-zone-upload .mud-icon-root {
        margin-bottom: var(--spacing-md);
    }

/* =================================================================
   TREE ITEM — Composants arborescents avec drag & drop
   Utilisé par : ZoneSettings / ZoneTreeItemComponent
                 CategoriesArticles / CatTreeItemComponent
                 (et tout futur composant arborescent)
   ================================================================= */

/* ── Brique item ─────────────────────────────────────────────── */
.zone-item {
    display: flex;
    align-items: center;
    gap: 6px;
    padding: 6px 10px;
    background: white;
    border: 1px solid #e8e8e8;
    border-radius: 8px;
    transition: box-shadow 0.15s;
    min-height: 40px;
    min-width: 0;
}

    .zone-item:hover {
        box-shadow: 0 2px 8px rgba(0,0,0,0.08);
    }

/* ── Contenu central ─────────────────────────────────────────── */
.zone-content {
    display: flex;
    align-items: center;
    gap: 8px;
    flex: 1;
    font-size: 13px;
    min-width: 0;
    overflow: hidden;
}

.zone-name {
    font-weight: 500;
    color: #333;
    font-size: 13px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.zone-badge {
    background: #f0f0f0;
    color: #777;
    padding: 1px 7px;
    border-radius: 10px;
    font-size: 11px;
    white-space: nowrap;
    flex-shrink: 0;
}

/* ── Boutons d'action ronds ──────────────────────────────────── */
.zone-actions {
    display: flex;
    gap: 5px;
    opacity: 0;
    transition: opacity 0.15s;
    flex-shrink: 0;
    align-items: center;
}

.zone-item:hover .zone-actions {
    opacity: 1;
}

.action-btn-round {
    width: 26px;
    height: 26px;
    border-radius: 50%;
    border: none;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    transition: transform 0.1s, filter 0.1s;
    flex-shrink: 0;
    padding: 0;
}

    .action-btn-round:hover {
        transform: scale(1.12);
        filter: brightness(1.1);
    }

    .action-btn-round:active {
        transform: scale(0.95);
    }

.btn-add {
    background: #43a047;
}

.btn-edit {
    background: #667eea;
}

.btn-delete {
    background: #e53935;
}

/* ── Poignée drag ────────────────────────────────────────────── */
.drag-handle {
    display: flex;
    align-items: center;
    padding: 0 4px;
    cursor: grab;
    flex-shrink: 0;
    color: #ccc;
    transition: color 0.15s;
}

    .drag-handle:hover {
        color: #999;
    }

    .drag-handle:active {
        cursor: grabbing;
    }

/* ── Bouton expand ───────────────────────────────────────────── */
.expand-button {
    min-width: 22px !important;
    width: 22px !important;
    height: 22px !important;
    padding: 0 !important;
    flex-shrink: 0;
}

/* ── Sous-niveaux : séparation du parent + espacement interne ── */
.sub-zones {
    display: flex;
    flex-direction: column;
    gap: 4px;
    margin-left: 16px;
    padding-left: 8px;
    border-left: 2px solid #e8e8e8;
    margin-top: 4px;
    padding-bottom: 0;
    min-width: 0;
}

/* ── Drag & drop visuels ─────────────────────────────────────── */
.drag-chosen {
    opacity: 0.95;
    box-shadow: 0 6px 20px rgba(102,126,234,0.35) !important;
    border-color: #667eea !important;
}

.drag-ghost {
    opacity: 0.35;
    background: #e8ecff !important;
    border: 2px dashed #667eea !important;
    border-radius: 8px;
}

/* ── Empty state (page sans données) ────────────────────────── */
.empty-state {
    text-align: center;
    padding: 60px 20px;
    background: white;
    border-radius: 12px;
    margin-top: 20px;
}

/* =================================================================
   16. ANIMATIONS
   ================================================================= */
@keyframes slideIn {
    from {
        opacity: 0;
        transform: translateY(-20px);
    }

    to {
        opacity: 1;
        transform: translateY(0);
    }
}

@keyframes slideInRight {
    from {
        transform: translateX(100%);
    }

    to {
        transform: translateX(0);
    }
}

/* =================================================================
   17. MUD INPUT — Overrides globaux (inputs plus fins et harmonieux)
   ================================================================= */

.mud-input input,
.mud-input textarea {
    font-size: 14px !important;
}

.mud-input-label {
    font-size: 14px !important;
}

.mud-select-input .mud-input-slot {
    font-size: 14px !important;
}

.mud-list-item .mud-typography-body1 {
    font-size: 14px !important;
}

/* =================================================================
   MUD SELECT — Style compact unifié
   Appliquer Class="mud-select-compact" sur le MudDialog ou le
   conteneur parent pour activer le rendu compact sur tous les
   MudSelect enfants.
   ================================================================= */

.mud-select-compact .mud-input-label-inputcontrol {
    display: none !important;
}

.mud-select-compact .mud-input.mud-input-outlined {
    margin-top: 0 !important;
}

.mud-select-compact .mud-input-outlined .mud-input-slot {
    padding: 10px 14px !important;
    font-size: 13px !important;
    font-family: inherit !important;
    min-height: unset !important;
}

.mud-select-compact .mud-input-outlined fieldset {
    border-radius: 8px !important;
}

/* Popover — items de liste réduits */
.mud-select-popover-compact .mud-typography-body1 {
    font-size: 12px !important;
    line-height: 1.2 !important;
}

.mud-select-popover-compact li {
    min-height: 32px !important;
    height: 32px !important;
    padding: 0 12px !important;
}

/* =================================================================
   18. SIDEBAR NAV — Overrides MudBlazor (global scope requis)
   ================================================================= */

.mud-nav-link:hover {
    background-color: rgba(0, 0, 0, 0.20) !important;
}

.mud-nav-link.active,
.mud-nav-link[aria-current="page"],
a[href].mud-nav-link.active {
    border: none !important;
    border-radius: 0 !important;
    box-shadow: inset 3px 0 0 #35C6EE, inset 0 0 0 9999px #11455f !important;
}

/* =================================================================
   SNACKBAR CUSTOM — Style Infomaniak
   Fond sombre, icône colorée, barre de progression, croix
   Centrage : la position MudBlazor (BottomCenter, etc.) est calculée par
   rapport à la fenêtre entière, ce qui décentre visuellement les snackbars
   à cause du nav-rail à gauche (48px). On compense en décalant le conteneur
   parent de la largeur du nav-rail divisée par 2 → snackbar visuellement
   centré sur la zone de contenu.
   ================================================================= */
/* Ciblage limité à MainLayout (.app-root) pour ne pas décaler les snackbars
   d'OnboardingLayout qui n'a pas de nav-rail. */
.app-root .mud-snackbar-provider {
    padding-left: 48px;  /* largeur du .nav-rail (cf NavMenu.razor) */
}

/* Spinner inline pour boutons d'action en attente. Remplace le label le temps
   du round-trip serveur (clic « Enregistrer » / « Créer le devis » / etc.). */
.s3-btn-spinner {
    display: inline-block;
    width: 14px;
    height: 14px;
    border: 2px solid currentColor;
    border-right-color: transparent;
    border-radius: 50%;
    animation: s3-btn-spin 0.7s linear infinite;
    vertical-align: middle;
}
@keyframes s3-btn-spin {
    to { transform: rotate(360deg); }
}

/* Z-index global du provider et des snackbars : 100001, au-dessus de :
     - nos dialogs custom (.s3-dialog-panel à 10000)
     - spinner overlay FichePrestation (99998)
     - flash plein écran post-validation FichePrestation (99999)
   Les snackbars d'erreur/warning doivent TOUJOURS rester visibles, même
   pendant un overlay plein écran qui dure 2-3 secondes. Sans ça, un
   warning « Brouillon Pennylane non créé » posé pendant le flash de
   confirmation serait caché derrière l'overlay et invisible à
   l'utilisateur. */
:root {
    --mud-zindex-snackbar: 100001;
}
.mud-snackbar-provider,
div.mud-snackbar-provider {
    position: fixed !important;
    z-index: 100001 !important;
}

.mud-snackbar {
    background: var(--color-navy) !important;
    color: #fff !important;
    border-radius: 8px !important;
    box-shadow: 0 8px 32px rgba(0,0,0,0.25) !important;
    min-width: 340px !important;
    max-width: 520px !important;
    position: relative !important;
    overflow: hidden !important;
    padding-bottom: 8px !important;
    z-index: 100001 !important;
}
.mud-snackbar .mud-snackbar-content-message {
    color: #fff !important;
    font-size: 13px !important;
    font-weight: 500 !important;
}
/* Icône colorée à gauche */
.mud-snackbar.mud-alert-filled-success .mud-snackbar-icon { color: #4caf50 !important; }
.mud-snackbar.mud-alert-filled-error .mud-snackbar-icon { color: #f44336 !important; }
.mud-snackbar.mud-alert-filled-warning .mud-snackbar-icon { color: #ff9800 !important; }
.mud-snackbar.mud-alert-filled-info .mud-snackbar-icon { color: #2196f3 !important; }
.mud-snackbar.mud-alert-filled-normal .mud-snackbar-icon { color: #90a4ae !important; }

/* Forcer fond identique pour toutes les variantes */
.mud-snackbar.mud-alert-filled-success,
.mud-snackbar.mud-alert-filled-error,
.mud-snackbar.mud-alert-filled-warning,
.mud-snackbar.mud-alert-filled-info,
.mud-snackbar.mud-alert-filled-normal {
    background: var(--color-navy) !important;
}

/* Bouton fermer (croix) */
.mud-snackbar .mud-snackbar-close-button {
    color: rgba(255,255,255,0.6) !important;
}
.mud-snackbar .mud-snackbar-close-button:hover {
    color: #fff !important;
}

/* Barre de progression en bas */
.mud-snackbar::after {
    content: '';
    position: absolute;
    bottom: 0;
    left: 0;
    height: 3px;
    width: 100%;
    animation: snackbar-progress 3.5s linear forwards;
}
.mud-snackbar.mud-alert-filled-success::after { background: #4caf50; }
.mud-snackbar.mud-alert-filled-error::after { background: #f44336; }
.mud-snackbar.mud-alert-filled-warning::after { background: #ff9800; }
.mud-snackbar.mud-alert-filled-info::after { background: #2196f3; }
.mud-snackbar.mud-alert-filled-normal::after { background: #90a4ae; }

@keyframes snackbar-progress {
    from { width: 100%; }
    to { width: 0%; }
}

/* ═══════════════════════════════════════════════════════
   DASHBOARD / KPI — styles réutilisés par Home + dashboards briques
   ═══════════════════════════════════════════════════════ */

.dashboard-container {
    padding: 24px;
    background: var(--common-background-secondaire);
    flex: 1;
    overflow-y: auto;
}

.welcome-banner {
    background: var(--common-gradient);
    box-shadow: 0 4px 20px rgba(0,157,196,.3);
    border-radius: 12px;
    padding: 28px 32px;
    margin-bottom: 24px;
    display: flex;
    align-items: center;
    justify-content: space-between;
    position: relative;
    overflow: hidden;
}
.welcome-banner::before {
    content: '';
    position: absolute;
    top: -40px; right: -40px;
    width: 180px; height: 180px;
    background: rgba(255,255,255,.07);
    border-radius: 50%;
}
.welcome-banner::after {
    content: '';
    position: absolute;
    bottom: -60px; right: 80px;
    width: 220px; height: 220px;
    background: rgba(255,255,255,.05);
    border-radius: 50%;
}
.welcome-text { position: relative; z-index: 1; }
.welcome-greeting {
    font-size: 22px; font-weight: 800;
    color: white; margin-bottom: 4px; letter-spacing: -.3px;
}
.welcome-sub { font-size: 13px; color: rgba(255,255,255,.7); }
.welcome-date {
    position: relative; z-index: 1;
    text-align: right; color: rgba(255,255,255,.8);
    font-size: 13px; font-weight: 600;
}
.welcome-date-day {
    font-size: 32px; font-weight: 800;
    color: white; line-height: 1; margin-bottom: 2px;
}

.dash-section-title {
    font-size: 12px; font-weight: 700;
    text-transform: uppercase; letter-spacing: 1px;
    color: #999; margin-bottom: 12px; margin-top: 8px;
}

.kpi-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
    gap: 14px; margin-bottom: 24px;
}
.kpi-card {
    background: white; border-radius: 10px;
    padding: 18px 20px; border: 1px solid #e8e8f0;
    cursor: pointer; transition: transform .15s, box-shadow .15s;
    display: flex; flex-direction: column; gap: 8px;
    text-decoration: none;
}
.kpi-card:hover {
    transform: translateY(-2px);
    box-shadow: 0 6px 20px rgba(0,0,0,.1);
}
.kpi-icon { font-size: 24px; line-height: 1; }
.kpi-value { font-size: 28px; font-weight: 800; color: #1a1a2e; line-height: 1; }
.kpi-label { font-size: 12px; font-weight: 600; color: #888; }
.kpi-card.kpi-warning .kpi-value { color: #e67e22; }
.kpi-card.kpi-danger .kpi-value { color: #e74c3c; }
.kpi-card.kpi-success .kpi-value { color: #27ae60; }
.kpi-card.kpi-warning { border-left: 3px solid #e67e22; }
.kpi-card.kpi-danger { border-left: 3px solid #e74c3c; }
.kpi-card.kpi-success { border-left: 3px solid #27ae60; }
.kpi-card.kpi-primary { border-left: 3px solid #667eea; }

.alerts-list { display: flex; flex-direction: column; gap: 8px; margin-bottom: 24px; }
.alert-item {
    background: white; border-radius: 8px;
    padding: 12px 16px; display: flex; align-items: center;
    gap: 12px; border: 1px solid #e8e8f0;
    cursor: pointer; transition: background .15s;
}
.alert-item:hover { background: #fafafe; }
.alert-item.alert-warning { border-left: 3px solid #e67e22; }
.alert-item.alert-danger { border-left: 3px solid #e74c3c; }
.alert-item.alert-info { border-left: 3px solid #667eea; }
.alert-icon { font-size: 18px; flex-shrink: 0; }
.alert-text { flex: 1; font-size: 13px; font-weight: 600; color: #333; }
.alert-sub { font-size: 11px; color: #888; margin-top: 2px; font-weight: 400; }
.alert-chevron { color: #ccc; font-size: 16px; }

/* ── Tuiles list ───────────────────────────────── */
.tile-list { display: flex; flex-direction: column; gap: 10px; }
.tile-item {
    display: flex; flex-direction: column;
    border-radius: var(--common-div-cornerradius); overflow: hidden;
    border: 1px solid var(--border-light); background: white;
    box-shadow: 0 1px 3px rgba(0,0,0,0.06);
    transition: box-shadow 0.15s;
}
.tile-item:hover { box-shadow: 0 2px 8px rgba(0,0,0,0.12); }
.tile-row {
    display: flex; cursor: pointer;
}
.tile-accent { width: 6px; flex-shrink: 0; }
.tile-body {
    display: flex; align-items: center; gap: 14px;
    padding: 12px 16px; flex: 1; min-width: 0;
}
.tile-icon { font-size: 22px; flex-shrink: 0; }
.tile-content { flex: 1; min-width: 0; }
.tile-title { font-weight: 600; font-size: 13px; color: #3d4f5f; }
.tile-subtitle { font-size: 12px; color: #4a5568; margin-top: 2px; }
.tile-badges { display: flex; gap: 6px; align-items: center; flex-wrap: wrap; margin-top: 4px; }
.tile-meta { font-size: 12px; color: var(--text-muted); flex-shrink: 0; text-align: right; }
.tile-actions { display: flex; gap: 6px; flex-shrink: 0; align-items: center; }
.tile-expand {
    border-top: 1px solid var(--border-light);
    padding: 14px 16px 14px 36px; background: #fafbfc;
    font-size: 13px; color: #333;
    animation: tileSlideDown 0.15s ease-out;
}
@keyframes tileSlideDown {
    from { opacity: 0; max-height: 0; padding-top: 0; padding-bottom: 0; }
    to { opacity: 1; max-height: 600px; }
}

/* Tile filter bar */
.tile-filter-bar {
    display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
    padding: 12px 16px; background: white;
    border-radius: var(--common-div-cornerradius);
    border: 1px solid var(--border-light); margin-bottom: 12px;
}

/* Tile pagination */
.tile-pagination { display: flex; justify-content: center; align-items: center; gap: 4px; padding: 16px 0; }
.tile-pagination button {
    background: none; border: 1px solid var(--border-light); border-radius: 6px;
    padding: 5px 12px; font-size: 13px; cursor: pointer; color: #3d4f5f;
    transition: background 0.12s;
}
.tile-pagination button:hover { background: var(--background-hover); }
.tile-pagination button.active {
    background: var(--color-primary); color: white;
    border-color: var(--color-primary); font-weight: 600;
}
.tile-pagination button:disabled { opacity: 0.4; cursor: default; }
.tile-pagination .tile-page-info { font-size: 12px; color: var(--text-muted); margin: 0 8px; }

.home-grid { display: grid; grid-template-columns: 1fr 320px; gap: 20px; }
.home-main { min-width: 0; }
.no-brick {
    background: white; border-radius: 10px;
    padding: 40px; text-align: center;
    color: #aaa; border: 1px dashed #ddd;
}

@media (max-width: 900px) {
    .home-grid { grid-template-columns: 1fr; }
    .welcome-date { display: none; }
}

/* ══════════════════════════════════════════════════════════════════
   MudBlazor — style unifié par défaut (fond blanc, 32px, 12px, 10px)
   S'applique à TOUS les MudSelect / MudTextField / MudDatePicker /
   MudNumericField dès qu'ils utilisent la variante Outlined (défaut
   dans notre app). Un opt-out est possible via .s3-field (fond gris)
   ou en désactivant via styles inline.
   ══════════════════════════════════════════════════════════════════ */

/* Le container MudSelect/MudTextField passe en flex colonne pour que le
   label flottant (Label="...") s'empile au-dessus du champ au lieu d'être
   compressé dans un champ de 32px. */
.mud-input-control {
    display: flex !important;
    flex-direction: column !important;
}

/* Le label flottant MudBlazor devient un label statique au-dessus du champ,
   même style que nos labels externes <label>…</label>. */
.mud-input-control .mud-input-label {
    position: static !important;
    transform: none !important;
    pointer-events: auto !important;
    font-size: 11px !important;
    font-weight: 600 !important;
    text-transform: uppercase !important;
    letter-spacing: 0.5px !important;
    color: var(--text-secondary) !important;
    margin: 0 0 4px 0 !important;
    padding: 0 !important;
    line-height: 1.2 !important;
    max-width: none !important;
    overflow: visible !important;
    background: transparent !important;
    display: block !important;
    order: -1 !important; /* remonter au-dessus de l'input dans le flex */
    height: auto !important;
    width: auto !important;
    top: auto !important;
    left: auto !important;
}

/* Wrapper interne MudBlazor (selon version) — on le met aussi en colonne */
.mud-input-control .mud-input-control-input-container {
    display: flex !important;
    flex-direction: column !important;
}

/* Sur les .s3-field (OCR) on utilise des <label> externes → on masque
   le label interne MudBlazor pour éviter le doublon. */
.mud-input-control.s3-field > .mud-input-label,
.mud-select.s3-field > .mud-input-label {
    display: none !important;
}

.mud-input-control .mud-input.mud-input-outlined {
    height: 32px !important;
    min-height: 32px !important;
    background: white !important;
    border-radius: 10px !important;
    display: flex !important;
    align-items: center !important;
}

/* Slot prend toute la largeur disponible, adornment/chevron collé à droite */
.mud-input-control .mud-input.mud-input-outlined > .mud-input-slot,
.mud-input-control .mud-input.mud-input-text > .mud-input-slot,
.mud-input-control .mud-input.mud-input-filled > .mud-input-slot {
    flex: 1 1 auto !important;
    min-width: 0 !important;
    width: auto !important;
}

.mud-input-control .mud-input-slot > input,
.mud-input-control .mud-input-slot > textarea {
    flex: 1 1 auto !important;
    min-width: 0 !important;
    width: 100% !important;
}

    .mud-input-control .mud-input.mud-input-outlined > fieldset.mud-input-outlined-border {
        border: 1px solid #e2e8f0 !important;
        border-radius: 10px !important;
        transition: border-color 0.15s;
    }

    .mud-input-control .mud-input.mud-input-outlined .mud-input-slot {
        height: 32px !important;
        padding-top: 0 !important;
        padding-bottom: 0 !important;
        margin-top: 0 !important;
        font-size: 12px !important;
        line-height: 1 !important;
        display: flex !important;
        align-items: center !important;
    }

    .mud-input-control .mud-input.mud-input-outlined .mud-select-input,
    .mud-input-control .mud-input.mud-input-text .mud-select-input,
    .mud-input-control .mud-input.mud-input-filled .mud-select-input {
        display: flex !important;
        align-items: center !important;
        height: 100% !important;
        padding-top: 0 !important;
        padding-bottom: 0 !important;
        line-height: 1.2 !important;
    }

        .mud-input-control .mud-input.mud-input-outlined .mud-input-slot input,
        .mud-input-control .mud-input.mud-input-outlined .mud-input-slot textarea {
            font-size: 12px !important;
            height: 32px !important;
            padding-top: 0 !important;
            padding-bottom: 0 !important;
        }

    .mud-input-control .mud-input.mud-input-outlined:hover > fieldset.mud-input-outlined-border {
        border-color: #cbd5e1 !important;
        border-width: 1px !important;
    }

    /* Focus : on garde la bordure inchangée (évite l'effet double-bordure
       quand l'input est dans un container déjà bordé) et on s'appuie uniquement
       sur un halo box-shadow qui se voit au-dessus de tout. */
    .mud-input-control .mud-input.mud-input-outlined.mud-focused > fieldset.mud-input-outlined-border {
        border: 1px solid #e2e8f0 !important;
        outline: none !important;
    }

    .mud-input-control .mud-input.mud-input-outlined.mud-focused {
        box-shadow: none !important;
        outline: none !important;
    }

    /* Neutraliser le <legend> MudBlazor qui crée un "notch" visible en haut
       du fieldset quand un label flottant est présent — on affiche nos labels
       au-dessus, donc pas besoin d'entaille. */
    .mud-input-control .mud-input.mud-input-outlined > fieldset.mud-input-outlined-border > legend {
        display: none !important;
        width: 0 !important;
        max-width: 0 !important;
        padding: 0 !important;
        visibility: hidden !important;
    }

    /* Supprimer l'outline navigateur sur les inputs internes */
    .mud-input-control .mud-input-slot input:focus,
    .mud-input-control .mud-input-slot textarea:focus {
        outline: none !important;
    }

/* Zone "value" interne de MudSelect — force la taille du contenu */
.mud-select .mud-select-input {
    font-size: 12px !important;
}

/* Textarea auto-height (cas multi-lignes) */
.mud-input-control .mud-input.mud-input-outlined.mud-input-multiline,
.mud-input-control .mud-input.mud-input-outlined.mud-input-multiline .mud-input-slot {
    height: auto !important;
    min-height: 32px !important;
}

/* ── Variantes Text / Filled (underline par défaut) → look outlined ── */
.mud-input-control .mud-input.mud-input-text,
.mud-input-control .mud-input.mud-input-filled {
    height: 32px !important;
    min-height: 32px !important;
    background: white !important;
    border: 1px solid #e2e8f0 !important;
    border-radius: 10px !important;
    padding: 0 12px !important;
    margin: 0 !important;
    display: flex !important;
    align-items: center !important;
}

/* Supprimer les underlines des variantes text/filled */
.mud-input-control .mud-input.mud-input-text::before,
.mud-input-control .mud-input.mud-input-text::after,
.mud-input-control .mud-input.mud-input-filled::before,
.mud-input-control .mud-input.mud-input-filled::after {
    display: none !important;
}

.mud-input-control .mud-input.mud-input-text .mud-input-slot,
.mud-input-control .mud-input.mud-input-filled .mud-input-slot {
    height: 32px !important;
    padding: 0 !important;
    margin-top: 0 !important;
    font-size: 12px !important;
    line-height: 1 !important;
    display: flex !important;
    align-items: center !important;
}

    .mud-input-control .mud-input.mud-input-text .mud-input-slot input,
    .mud-input-control .mud-input.mud-input-filled .mud-input-slot input,
    .mud-input-control .mud-input.mud-input-text .mud-input-slot textarea,
    .mud-input-control .mud-input.mud-input-filled .mud-input-slot textarea {
        font-size: 12px !important;
        height: 32px !important;
        padding: 0 !important;
    }

.mud-input-control .mud-input.mud-input-text:hover,
.mud-input-control .mud-input.mud-input-filled:hover {
    border-color: #cbd5e1 !important;
}

.mud-input-control .mud-input.mud-input-text.mud-focused,
.mud-input-control .mud-input.mud-input-filled.mud-focused,
.mud-input-control .mud-input.mud-focused {
    border-color: #e2e8f0 !important;
    box-shadow: none !important;
    outline: none !important;
}

/* Multiline variantes text/filled */
.mud-input-control .mud-input.mud-input-text.mud-input-multiline,
.mud-input-control .mud-input.mud-input-filled.mud-input-multiline,
.mud-input-control .mud-input.mud-input-text.mud-input-multiline .mud-input-slot,
.mud-input-control .mud-input.mud-input-filled.mud-input-multiline .mud-input-slot {
    height: auto !important;
    min-height: 32px !important;
    padding: 8px 12px !important;
}

/* MudDatePicker / MudTimePicker — même structure que MudTextField */
.mud-picker.mud-picker-inline .mud-input-control .mud-input {
    height: 32px !important;
    min-height: 32px !important;
}

/* ══════════════════════════════════════════════════════════════════
   S3 TABS FILTERS BAR — bandeau filtres/recherche attaché aux onglets

   Pattern : sur les pages Paramètres (Facturation, Lavage…) qui
   utilisent _FacturationTabsHeader / _StationTabsHeader, on attache
   un bandeau de filtres/recherche juste sous les onglets, sans gap
   visuel, avec une légère bordure grise qui prolonge celle des tabs.

   Usage :
     <_FacturationTabsHeader CurrentTab="produits" />
     <div class="s3-tabs-filters-bar">
         <div class="s3-field" style="min-width:240px;">
             <input type="search" placeholder="Rechercher…"
                    @bind="_recherche" @bind:event="oninput" />
         </div>
         <select @bind="_filtre" class="s3-field">...</select>
         <span class="s3-tabs-filters-spacer"></span>
         <button class="btn btn-primary">+ Nouveau</button>
     </div>

   Le margin-top négatif compense le margin-bottom: 12px des tabs
   pour que la barre soit collée. La border-top: none évite la
   double bordure avec la border-bottom des tabs.
   ══════════════════════════════════════════════════════════════════ */
.s3-tabs-filters-bar {
    margin-top: -12px;
    margin-bottom: 12px;
    background: white;
    border: 1px solid #e2e8f0;
    border-top: none;
    border-radius: 0 0 var(--common-div-cornerradius) var(--common-div-cornerradius);
    padding: 10px 14px;
    display: flex;
    gap: 12px;
    align-items: center;
    flex-wrap: wrap;
    flex-shrink: 0;
}
/* Spacer pousse les éléments suivants à droite (typique : bouton d'action). */
.s3-tabs-filters-spacer { flex: 1 1 auto; }
/* Compteur de résultats discret à droite (« 12 / 48 produits »). */
.s3-tabs-filters-bar .s3-results-count {
    font-size: 11px;
    color: var(--text-secondary);
    white-space: nowrap;
}
/* Loupe unicode 🔍 à gauche de tout champ recherche placé dans la barre :
   on positionne le wrapper .s3-field en relative et on rend la loupe via
   ::before. Le padding-left de l'input est augmenté pour ne pas chevaucher
   l'icône. Utilise :has() (Chrome/Edge 105+, Firefox 121+). */
.s3-tabs-filters-bar .s3-field:has(input[type="search"]) {
    position: relative;
}
.s3-tabs-filters-bar .s3-field:has(input[type="search"])::before {
    content: "🔍";
    position: absolute;
    left: 10px;
    top: 50%;
    transform: translateY(-50%);
    font-size: 13px;
    pointer-events: none;
    opacity: 0.55;
    z-index: 1;
}
.s3-tabs-filters-bar .s3-field:has(input[type="search"]) input[type="search"] {
    padding-left: 32px;
}

/* ══════════════════════════════════════════════════════════════════
   S3 FIELD — style d'input unifié (opt-in via class="s3-field")
   Variante fond gris clair pour emphase (OCR, dialogs interactifs).
   Compatible input natif, textarea, select, MudSelect/MudTextField.
   ══════════════════════════════════════════════════════════════════ */

:root {
    --s3-field-height: 32px;
    --s3-field-bg: #f1f5f9;
    --s3-field-bg-focus: #ffffff;
    --s3-field-border: #e2e8f0;
    --s3-field-border-focus: var(--color-primary);
    --s3-field-radius: 10px;
    --s3-field-padding-x: 12px;
    --s3-field-font-size: 12px;
    --s3-field-icon-size: 18px;
}

/* ── Version native (input/select/textarea) ── */
.s3-field input[type="text"],
.s3-field input[type="number"],
.s3-field input[type="search"],
.s3-field input[type="email"],
.s3-field input[type="password"],
.s3-field select,
input.s3-field,
select.s3-field,
textarea.s3-field {
    height: var(--s3-field-height);
    padding: 0 var(--s3-field-padding-x);
    background: var(--s3-field-bg);
    border: 1px solid var(--s3-field-border);
    border-radius: var(--s3-field-radius);
    font-size: 13px;
    transition: background 0.15s, border-color 0.15s, box-shadow 0.15s;
    box-shadow: none;
}

textarea.s3-field {
    height: auto;
    min-height: var(--s3-field-height);
    padding: 10px var(--s3-field-padding-x);
    line-height: 1.5;
}

.s3-field input[type="text"]:focus,
.s3-field select:focus,
input.s3-field:focus,
select.s3-field:focus,
textarea.s3-field:focus {
    outline: none;
    background: var(--s3-field-bg-focus);
    box-shadow: none;
}

/* ──────────────────────────────────────────────────────────────
   .s3-ai-field — champ rempli par une suggestion IA
   Bordure dorée supérieure + glow vers le haut UNIQUEMENT (pas de
   fond coloré). À poser directement sur le cadre conteneur (settings-
   card, wrapper d'un select inline, etc.).
   Une icône ✨ est ajoutée automatiquement à gauche QUAND le wrapper
   contient un <select> direct (sélecteurs inline IA).
   Quand l'utilisateur modifie manuellement le champ, retirer la
   classe et passer le flag "*ChoisieManuellement = true" en base.
   .s3-ai-field-top est conservé en alias rétrocompatible.
   ──────────────────────────────────────────────────────────── */
.s3-ai-field,
.s3-ai-field-top {
    box-shadow: 0 0 6px rgba(212, 160, 23, 0.35) !important;
    transition: box-shadow .2s;
    position: relative;
}

/* Icône ✨ + padding pour les sélecteurs inline */
.s3-ai-field > select,
.s3-ai-field-top > select {
    padding-left: 24px !important;
}

.s3-ai-field:has(> select)::before,
.s3-ai-field-top:has(> select)::before {
    content: "✨";
    position: absolute;
    left: 6px;
    top: 50%;
    transform: translateY(-50%);
    font-size: 11px;
    pointer-events: none;
    z-index: 2;
    line-height: 1;
}

/* Bouton "revert" qui restaure la saisie utilisateur précédant la suggestion IA. */
.s3-ai-revert {
    background: none;
    border: none;
    cursor: pointer;
    color: #b8860b;
    font-size: 11px;
    font-weight: 600;
    display: inline-flex;
    align-items: center;
    gap: 3px;
    padding: 0 2px;
}

    .s3-ai-revert:hover {
        text-decoration: underline;
    }

.s3-ai-icon {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    font-size: 11px;
    color: #b8860b;
    font-weight: 600;
}

/* ── Wrapper avec icône à gauche ── */
.s3-field-icon {
    position: relative;
    display: block;
}

    .s3-field-icon > .material-icons,
    .s3-field-icon > .s3-field-icon-left {
        position: absolute;
        left: 12px;
        top: 50%;
        transform: translateY(-50%);
        font-size: var(--s3-field-icon-size);
        color: var(--text-muted);
        pointer-events: none;
        line-height: 1;
    }

    .s3-field-icon input,
    .s3-field-icon select,
    .s3-field-icon .mud-input-slot {
        padding-left: calc(var(--s3-field-padding-x) + var(--s3-field-icon-size) + 8px) !important;
    }

/* ── MudSelect / MudTextField (class="s3-field") ── */
/* La spécificité de MudBlazor est élevée : on passe par !important sur les
   propriétés critiques (hauteur, fond, radius, bordure) pour empêcher les
   styles par défaut de reprendre la main après le rendu initial. */

.mud-select.s3-field,
.mud-input-control.s3-field {
    height: var(--s3-field-height) !important;
}

.mud-select.s3-field .mud-input.mud-input-outlined,
.mud-input-control.s3-field .mud-input.mud-input-outlined,
.mud-input.mud-input-outlined.s3-field {
    height: var(--s3-field-height) !important;
    min-height: var(--s3-field-height) !important;
    background: var(--s3-field-bg) !important;
    border-radius: var(--s3-field-radius) !important;
    transition: background 0.15s;
}

.mud-select.s3-field .mud-input.mud-input-outlined > fieldset.mud-input-outlined-border,
.mud-input-control.s3-field fieldset.mud-input-outlined-border,
.mud-input.mud-input-outlined.s3-field > fieldset.mud-input-outlined-border {
    border: 1px solid var(--s3-field-border) !important;
    border-radius: var(--s3-field-radius) !important;
    transition: border-color 0.15s;
}

.mud-select.s3-field .mud-input.mud-input-outlined .mud-input-slot,
.mud-input-control.s3-field .mud-input-slot,
.mud-input.mud-input-outlined.s3-field .mud-input-slot {
    height: var(--s3-field-height) !important;
    padding-top: 0 !important;
    padding-bottom: 0 !important;
    margin-top: 0 !important;
    font-size: var(--s3-field-font-size) !important;
    line-height: 1 !important;
    display: flex !important;
    align-items: center !important;
}

/* MudSelect : valeur affichée centrée verticalement */
.mud-select.s3-field .mud-select-input,
.mud-input-control.s3-field .mud-select-input {
    display: flex !important;
    align-items: center !important;
    height: 100% !important;
    padding-top: 0 !important;
    padding-bottom: 0 !important;
    line-height: 1.2 !important;
}

/* Input interne de MudSelect/MudTextField */
.mud-select.s3-field .mud-input.mud-input-outlined .mud-input-slot input,
.mud-input-control.s3-field .mud-input-slot input,
.mud-input.mud-input-outlined.s3-field .mud-input-slot input {
    font-size: var(--s3-field-font-size) !important;
    height: var(--s3-field-height) !important;
    padding-top: 0 !important;
    padding-bottom: 0 !important;
}

/* Hover */
.mud-select.s3-field .mud-input.mud-input-outlined:hover > fieldset.mud-input-outlined-border,
.mud-input-control.s3-field .mud-input.mud-input-outlined:hover > fieldset.mud-input-outlined-border,
.mud-input.mud-input-outlined.s3-field:hover > fieldset.mud-input-outlined-border {
    border-color: var(--s3-field-border) !important;
    border-width: 1px !important;
}

/* Focus — aucun changement visuel (ni halo ni changement bordure) */
.mud-select.s3-field .mud-input.mud-input-outlined.mud-focused,
.mud-input-control.s3-field .mud-input.mud-input-outlined.mud-focused,
.mud-input.mud-input-outlined.s3-field.mud-focused {
    background: var(--s3-field-bg-focus) !important;
    box-shadow: none !important;
    outline: none !important;
}

.mud-select.s3-field .mud-input.mud-input-outlined.mud-focused > fieldset.mud-input-outlined-border,
.mud-input-control.s3-field .mud-input.mud-input-outlined.mud-focused > fieldset.mud-input-outlined-border,
.mud-input.mud-input-outlined.s3-field.mud-focused > fieldset.mud-input-outlined-border {
    border: 1px solid var(--s3-field-border) !important;
    outline: none !important;
}

/* Label flottant MudBlazor — masqué, on utilise nos labels externes */
.mud-select.s3-field .mud-input-label,
.mud-input-control.s3-field .mud-input-label {
    display: none !important;
}

/* Chevron MudSelect */
.mud-select.s3-field .mud-input-adornment {
    font-size: 18px;
}

/* ══════════════════════════════════════════════════════════════════
   Clear button (Clearable="true") — croix blanche sur rond rouge,
   positionné à gauche du texte de l'input.
   S'applique à MudAutocomplete / MudSelect / MudTextField Clearable.
   ══════════════════════════════════════════════════════════════════ */

/* Repositionner le clear button à gauche via position absolute */
.mud-input-control .mud-input {
    position: relative;
}

.mud-input-control .mud-input button.mud-input-clear-button,
.mud-input-control .mud-input .mud-input-clear-button {
    position: absolute !important;
    left: 10px !important;
    top: 50% !important;
    transform: translateY(-50%) !important;
    background: url('/img/close_icon.svg') center / contain no-repeat !important;
    color: transparent !important;
    border: none !important;
    border-radius: 50% !important;
    width: 16px !important;
    height: 16px !important;
    min-width: 16px !important;
    min-height: 16px !important;
    padding: 0 !important;
    margin: 0 !important;
    z-index: 10;
    transition: transform 0.15s;
}

.mud-input-control .mud-input button.mud-input-clear-button:hover,
.mud-input-control .mud-input .mud-input-clear-button:hover {
    transform: translateY(-50%) scale(1.15);
}

/* On masque l'icône interne par défaut de MudBlazor (le SVG du background suffit). */
.mud-input-control .mud-input .mud-input-clear-button .mud-icon-root,
.mud-input-control .mud-input .mud-input-clear-button .material-icons,
.mud-input-control .mud-input .mud-input-clear-button > svg {
    display: none !important;
}

/* Décaler le texte/input : clear button (10px offset + 16px diamètre) + 5px gap = 31px
   On vise TOUT ce qui peut afficher du texte à l'intérieur (input, textarea, select value) */
.mud-input-control:has(.mud-input-clear-button) .mud-input-slot,
.mud-input-control:has(.mud-input-clear-button) .mud-input-slot > input,
.mud-input-control:has(.mud-input-clear-button) .mud-input-slot > textarea,
.mud-input-control:has(.mud-input-clear-button) .mud-select-input,
.mud-input-control:has(.mud-input-clear-button) .mud-input-slot > .mud-select-input {
    padding-left: 31px !important;
}

/* ══════════════════════════════════════════════════════════════════
   OCR — sections de tuile (harmonise salarié + véhicule)
   - .ocr-section-top  : bloc affectation / type document (fond gris pâle)
   - .ocr-section-body : bloc champs extraits (fond blanc encadré)
   ══════════════════════════════════════════════════════════════════ */
.ocr-section-top {
    background: #f8fafc;
    border: 1px solid #e2e8f0;
    border-radius: 10px;
    padding: 12px 14px;
    margin-bottom: 10px;
}

.ocr-section-body {
    background: white;
    border: 1px solid #e2e8f0;
    border-radius: 10px;
    padding: 12px 14px;
    margin-bottom: 10px;
}

/* Titre interne de section */
.ocr-section-body-title {
    font-size: 11px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.5px;
    color: var(--text-muted);
    margin-bottom: 8px;
}

/* ══════════════════════════════════════════════════════════════════
   MudSelect dropdown — forcer tous les items visibles après sélection.
   Correctif global : MudBlazor peut laisser un état de recherche
   clavier qui masque des items via hidden. On force l'affichage.
   ══════════════════════════════════════════════════════════════════ */
.mud-popover .mud-list .mud-list-item[hidden],
.mud-popover-open .mud-list .mud-list-item[hidden] {
    display: flex !important;
}

.mud-popover .mud-list {
    max-height: 320px;
    overflow-y: auto;
}

/* ══════════════════════════════════════════════════════════════════
   S3RichSelect — dropdown riche réutilisable (V2 : MudPopover custom)
   (composant S3-Hub.Web/Components/Shared/S3RichSelect.razor)
   ══════════════════════════════════════════════════════════════════ */

/* Wrapper root */
.s3-rich-select {
    position: relative;
    display: flex;
    flex-direction: column;
    gap: 4px;
}

.s3-rich-top-label {
    font-size: 11px;
    text-transform: uppercase;
    letter-spacing: 0.5px;
    color: var(--text-secondary);
    margin-bottom: 2px;
}

/* ── Trigger (champ cliquable) ── */
.s3-rich-trigger {
    display: flex;
    align-items: center;
    gap: 8px;
    min-height: 40px;
    min-width: 0;           /* indispensable en flex layout pour que l'ellipse marche */
    padding: 4px 10px;
    background: white;
    border: 1px solid #e2e8f0;
    border-radius: 10px;
    cursor: pointer;
    transition: border-color 0.15s ease;
    outline: none;
    user-select: none;
    overflow: hidden;       /* coupe les longs libellés (ex: nom de code déchet CED) */
}

.s3-rich-trigger:hover:not(.disabled) {
    border-color: var(--border-medium);
}

.s3-rich-trigger.open {
    border-color: var(--color-primary);
}

.s3-rich-trigger.disabled {
    opacity: 0.6;
    cursor: not-allowed;
    background: #f8fafc;
}

.s3-rich-placeholder {
    flex: 1;
    color: var(--text-muted);
    font-size: 13px;
}

.s3-rich-selected {
    display: flex;
    align-items: center;
    gap: 8px;
    flex: 1;
    min-width: 0;
}

/* ── Multi-sélection : chips dans le trigger ── */
.s3-rich-multi-summary {
    flex: 1;
    min-width: 0;
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 4px;
}

.s3-rich-multi-chip {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    background: var(--common-background-secondaire);
    color: var(--color-cyan-dark);
    border: 1px solid var(--color-cyan);
    border-radius: 12px;
    padding: 1px 4px 1px 8px;
    font-size: 11px;
    font-weight: 500;
    max-width: 160px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.s3-rich-multi-chip-x {
    border: none;
    background: transparent;
    color: inherit;
    font-size: 13px;
    line-height: 1;
    cursor: pointer;
    padding: 0 2px;
    opacity: 0.7;
    transition: opacity 0.1s ease;
}

.s3-rich-multi-chip-x:hover {
    opacity: 1;
}

.s3-rich-multi-count {
    font-size: 11px;
    font-weight: 600;
    color: var(--text-secondary);
    background: var(--background-hover);
    border-radius: 10px;
    padding: 2px 7px;
}

.s3-rich-selected-label {
    flex: 1;
    min-width: 0;
    font-size: 13px;
    font-weight: 500;
    color: var(--text-primary);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.s3-rich-clear-btn {
    flex-shrink: 0;
    width: 18px;
    height: 18px;
    border-radius: 50%;
    border: none;
    background: var(--color-danger);
    color: white;
    font-size: 13px;
    line-height: 1;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 0;
    transition: transform 0.1s ease;
}

.s3-rich-clear-btn:hover { transform: scale(1.15); }

.s3-rich-arrow {
    flex-shrink: 0;
    color: var(--text-muted);
    font-size: 12px;
    transition: transform 0.15s ease;
}

.s3-rich-trigger.open .s3-rich-arrow {
    transform: rotate(180deg);
}

.s3-rich-spinner {
    flex-shrink: 0;
    width: 14px;
    height: 14px;
    border: 2px solid #e2e8f0;
    border-top-color: #3b82f6;
    border-radius: 50%;
    animation: s3-spin 0.6s linear infinite;
}

@keyframes s3-spin {
    to { transform: rotate(360deg); }
}

/* ── Popover (panel) ── */
/* Le z-index est calculé dynamiquement en JS (s3RichSelect.computeZIndex)
   au moment de l'ouverture et appliqué inline. La règle ici sert juste de
   fallback si le JS n'a pas tourné — pas de !important pour ne pas écraser
   l'inline.                                                              */
.s3-rich-popover {
    z-index: 1310;
}

.s3-rich-panel {
    /* La largeur est calquée sur celle du trigger via
       MudPopover RelativeWidth="Relative". On garde juste un plancher
       très bas pour les inputs ultra-étroits.                          */
    min-width: 200px;
    width: 100%;
    background: white;
    border-radius: 10px;
    box-shadow: 0 10px 30px rgba(11, 46, 71, 0.18);
    border: 1px solid var(--border-light);
    overflow: hidden;
    display: flex;
    flex-direction: column;
    max-height: 440px;
}

/* ── Barre de recherche ── */
.s3-rich-search-wrap {
    position: relative;
    padding: 10px 10px 8px;
    border-bottom: 1px solid var(--border-light);
}

.s3-rich-search {
    width: 100%;
    height: 32px;
    border: 1px solid var(--border-medium);
    border-radius: 8px;
    padding: 0 28px 0 10px;
    font-size: 12px;
    background: #f8fafc;
    outline: none;
}

.s3-rich-search:focus { background: white; }

.s3-rich-search-clear {
    position: absolute;
    right: 18px;
    top: 50%;
    transform: translateY(-50%);
    width: 18px;
    height: 18px;
    border-radius: 50%;
    border: none;
    background: var(--text-muted);
    color: white;
    font-size: 12px;
    cursor: pointer;
    padding: 0;
}

/* ── Filtres (chips) ── */
.s3-rich-filters {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    padding: 8px 10px;
    border-bottom: 1px solid var(--border-light);
    background: #fafbfc;
}

.s3-rich-chip {
    border: 1px solid var(--border-medium);
    background: white;
    color: var(--text-secondary);
    font-size: 11px;
    font-weight: 500;
    padding: 4px 10px;
    border-radius: 999px;
    cursor: pointer;
    transition: all 0.15s ease;
    white-space: nowrap;
    line-height: 1.4;
}

.s3-rich-chip:hover {
    background: var(--background-hover);
    border-color: var(--color-primary);
    color: var(--text-primary);
}

.s3-rich-chip.active {
    background: var(--color-navy);
    border-color: var(--color-navy);
    color: white;
}

/* ── Liste scrollable ── */
.s3-rich-list {
    flex: 1;
    overflow-y: auto;
    padding: 4px 0;
    min-height: 60px;
}

/* ── Row (item cliquable dans la liste) ── */
.s3-rich-row {
    display: flex;
    align-items: center;
    gap: 10px;
    width: 100%;
    padding: 8px 12px;
    cursor: pointer;
    transition: background 0.1s ease;
    border: none;
    background: transparent;
    text-align: left;
}

.s3-rich-row:hover,
.s3-rich-row.highlighted {
    background: var(--background-hover);
}

.s3-rich-row.selected {
    background: var(--background-active);
}

.s3-rich-row.highlighted.selected {
    background: var(--background-active);
    box-shadow: inset 2px 0 0 0 var(--color-primary);
}

/* ── Section labels (Récents / Tous) ── */
.s3-rich-section-label {
    padding: 6px 12px 2px;
    font-size: 10px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.6px;
    color: var(--text-muted);
    background: white;
    position: sticky;
    top: 0;
}

.s3-rich-check {
    flex-shrink: 0;
    color: var(--color-primary);
    font-size: 14px;
    font-weight: 700;
    margin-left: 4px;
}

/* ── Item (legacy wrapper, conservé) ── */
.s3-rich-item {
    display: flex;
    align-items: center;
    gap: 10px;
    width: 100%;
    padding: 2px 0;
}

.s3-rich-avatar {
    flex-shrink: 0;
    width: 30px;
    height: 30px;
    border-radius: 8px;
    display: flex;
    align-items: center;
    justify-content: center;
    color: white;
    font-size: 12px;
    font-weight: 700;
    letter-spacing: 0.3px;
    text-transform: uppercase;
}

/* ── Miniature image (mode photo) ── */
.s3-rich-thumb {
    flex-shrink: 0;
    width: 36px;
    height: 36px;
    border-radius: 8px;
    object-fit: cover;
    border: 1px solid var(--border-light);
    background: #f8fafc;
    cursor: zoom-in;
    transition: transform 0.1s ease, box-shadow 0.1s ease;
}

.s3-rich-thumb:hover {
    transform: scale(1.05);
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
}

.s3-rich-thumb-placeholder {
    cursor: default;
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--text-muted);
    font-size: 16px;
    background: #f1f5f9;
}

.s3-rich-thumb-placeholder:hover {
    transform: none;
    box-shadow: none;
}

.s3-rich-text {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 1px;
}

.s3-rich-label {
    font-size: 13px;
    font-weight: 500;
    color: var(--text-primary);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.s3-rich-subtitle {
    font-size: 11px;
    color: var(--text-muted);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.s3-rich-badge {
    flex-shrink: 0;
    font-size: 10px;
    font-weight: 600;
    padding: 2px 7px;
    border-radius: 6px;
    background: var(--common-background-secondaire);
    color: var(--color-cyan-dark);
    text-transform: none;
    letter-spacing: 0;
}

.s3-rich-hl {
    background: #fff3a8;
    color: inherit;
    padding: 0 1px;
    border-radius: 2px;
}

/* ── Empty state ── */
.s3-rich-empty {
    padding: 18px 14px;
    text-align: center;
    color: var(--text-muted);
    font-size: 12px;
    font-style: italic;
}

/* ── Footer (compteur + bouton créer) ── */
.s3-rich-footer {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
    padding: 8px 12px;
    border-top: 1px solid var(--border-light);
    background: #fafbfc;
    position: sticky;
    bottom: 0;
    z-index: 2;
}

.s3-rich-count {
    font-size: 11px;
    color: var(--text-muted);
}

.s3-rich-create {
    border: none;
    background: var(--color-navy);
    color: white;
    font-size: 11px;
    font-weight: 600;
    padding: 5px 12px;
    border-radius: 6px;
    cursor: pointer;
    transition: all 0.15s ease;
    white-space: nowrap;
}

.s3-rich-create:hover {
    background: var(--color-navy-light);
    transform: translateY(-1px);
}

.s3-rich-create-external {
    align-self: flex-start;
    margin-top: 2px;
}

/* ── Bouton « agrandir » dans la barre de recherche du popover ── */
.s3-rich-search-expand {
    position: absolute;
    right: 14px;
    top: 50%;
    transform: translateY(-50%);
    width: 28px;
    height: 28px;
    border-radius: 6px;
    border: 1px solid var(--border-medium);
    background: #f1f5f9;
    color: var(--text-secondary);
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 0;
    transition: all 0.15s ease;
}

.s3-rich-search-expand:hover {
    background: var(--color-navy);
    color: white;
    border-color: var(--color-navy);
}

.s3-rich-search.s3-rich-search-with-expand {
    padding-right: 50px;
}

.s3-rich-search-clear.s3-rich-search-clear-shifted {
    right: 48px;
}

/* ══════════════════════════════════════════════════════════════
   ArticleBrowserDialog — dialog de recherche avancée pièces
   ══════════════════════════════════════════════════════════════ */

.ab-row {
    display: flex;
    align-items: flex-start;
    gap: 12px;
    padding: 10px 16px;
    border-bottom: 1px solid #f1f5f9;
    transition: background 0.1s ease;
}

.ab-row:hover { background: #f8fafc; }
.ab-row-in-cart { background: #f0fdf4; }
.ab-row-in-cart:hover { background: #dcfce7; }

.ab-thumb-col {
    flex-shrink: 0;
    width: 56px;
}

.ab-thumb {
    width: 56px;
    height: 56px;
    border-radius: 8px;
    object-fit: cover;
    border: 1px solid var(--border-light);
    cursor: zoom-in;
    transition: transform 0.1s ease;
}

.ab-thumb:hover { transform: scale(1.08); }

.ab-thumb-empty {
    display: flex;
    align-items: center;
    justify-content: center;
    background: #f1f5f9;
    color: var(--text-muted);
    font-size: 20px;
    cursor: default;
}

.ab-thumb-empty:hover { transform: none; }

.ab-info-col {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 3px;
}

.ab-designation {
    font-size: 13px;
    font-weight: 600;
    color: var(--text-primary);
    line-height: 1.3;
}

.ab-description {
    font-size: 11px;
    color: var(--text-secondary);
    line-height: 1.3;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.ab-refs {
    display: flex;
    flex-wrap: wrap;
    gap: 4px;
    margin-top: 2px;
}

.ab-ref-tag {
    font-size: 10px;
    padding: 1px 6px;
    border-radius: 4px;
    background: #eff6ff;
    color: #1e40af;
    white-space: nowrap;
}

.ab-suppliers {
    display: flex;
    flex-direction: column;
    gap: 2px;
    margin-top: 3px;
}

.ab-supplier-line {
    display: flex;
    align-items: center;
    gap: 8px;
    font-size: 11px;
}

.ab-supplier-name {
    font-weight: 500;
    color: var(--text-primary);
}

.ab-supplier-ref {
    color: var(--text-muted);
    font-size: 10px;
}

.ab-supplier-price {
    color: var(--text-secondary);
    font-weight: 600;
    margin-left: auto;
}

.ab-stock-col {
    flex-shrink: 0;
    width: 60px;
    text-align: center;
    padding-top: 4px;
}

.ab-action-col {
    flex-shrink: 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 4px;
    padding-top: 2px;
}

.ab-qty-input {
    width: 60px;
    height: 28px;
    text-align: center;
    border: 1px solid var(--border-medium);
    border-radius: 6px;
    font-size: 13px;
    background: white;
    padding: 0 4px;
}

.ab-add-btn {
    border: none;
    background: var(--color-navy);
    color: white;
    font-size: 11px;
    font-weight: 600;
    padding: 4px 12px;
    border-radius: 6px;
    cursor: pointer;
    white-space: nowrap;
    transition: all 0.15s ease;
}

.ab-add-btn:hover {
    background: var(--color-navy-light);
    transform: translateY(-1px);
}

.ab-add-btn-added {
    background: #16a34a;
}

.ab-add-btn-added:hover {
    background: #dc2626;
}

/* ──────────────────────────────────────────────────────────────────
   Dialogs Paramètres station Lavage (Section / Catégorie / Item)
   Utilisé par ParametresStation.razor. Placé ici plutôt qu'en
   <style> local car le parser Razor confondait les sélecteurs
   contenant « select » / « textarea » avec des tags HTML (RZ9980).
   ────────────────────────────────────────────────────────────────── */

/* Grille pour les inputs (label colonne gauche large + champ). */
.s3-prm-form {
    display: grid;
    grid-template-columns: 260px 1fr;
    gap: 6px 14px;
    align-items: center;
}

/* Force tous les inputs/selects/textareas de la grille à respecter
   la largeur de leur colonne (sinon long contenu déborde → scroll horizontal). */
.s3-prm-form > input,
.s3-prm-form > select,
.s3-prm-form > textarea {
    width: 100%;
    min-width: 0;
    max-width: 100%;
    box-sizing: border-box;
}

/* Sous-titres de section (Affichage / Certificat / Slider / Bulk). */
.s3-prm-section {
    grid-column: 1/-1;
    padding: 6px 0 2px 0;
    border-top: 1px solid #e2e8f0;
    margin-top: 2px;
    font-size: 12px;
    color: #475569;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.4px;
}

/* Ligne toggle : libellé pleine largeur à gauche + interrupteur à droite. */
.s3-prm-toggle-row {
    grid-column: 1/-1;
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 14px;
    padding: 4px 2px;
    border-bottom: 1px dashed #f1f5f9;
    font-size: 13px;
    color: #1e293b;
}

.s3-prm-toggle-row:last-child {
    border-bottom: none;
}

.s3-prm-toggle-row > .s3-prm-toggle-label {
    flex: 1;
    min-width: 0;
}

/* ── Barre panier en bas du dialog ── */
.ab-cart-bar {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 10px 16px;
    border-top: 2px solid var(--color-navy);
    background: #f8fafc;
}

.ab-cart-chip {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    background: white;
    border: 1px solid var(--border-medium);
    border-radius: 12px;
    padding: 2px 6px 2px 10px;
    font-size: 11px;
    font-weight: 500;
    white-space: nowrap;
}

.ab-cart-chip-x {
    border: none;
    background: transparent;
    color: var(--text-muted);
    font-size: 13px;
    cursor: pointer;
    padding: 0 2px;
    line-height: 1;
}

.ab-cart-chip-x:hover { color: #dc2626; }

.ab-vehicle-badge {
    display: inline-flex;
    align-items: center;
    gap: 3px;
    font-size: 11px;
    font-weight: 600;
    color: #92400e;
    background: #fef3c7;
    border: 1px solid #fde68a;
    border-radius: 6px;
    padding: 1px 7px;
    white-space: nowrap;
    cursor: default;
}

/* ══════════════════════════════════════════════════════════════
   S3 Alert — bandeau d'information / avertissement / erreur
   Remplace MudAlert partout dans l'app.
   Usage : <div class="s3-alert s3-alert-error">Message</div>
   Variantes : s3-alert-info (bleu), s3-alert-success (vert),
               s3-alert-warning (orange), s3-alert-error (rouge)
   ══════════════════════════════════════════════════════════════ */

.s3-alert {
    padding: 10px 12px;
    font-size: 12px;
    border-radius: 0 8px 8px 0;
    border-left: 3px solid;
    line-height: 1.5;
}

.s3-alert-info {
    background: #eff6ff;
    border-left-color: #3b82f6;
    color: #1e40af;
}

.s3-alert-success {
    background: #f0fdf4;
    border-left-color: #22c55e;
    color: #166534;
}

.s3-alert-warning {
    background: #fffbeb;
    border-left-color: #f59e0b;
    color: #92400e;
}

.s3-alert-error {
    background: #fef2f2;
    border-left-color: #ef4444;
    color: #991b1b;
}

/* =================================================================
   17. PLAQUE D'IMMATRICULATION — badge style FR
   ================================================================= */
.s3-plaque {
    display: inline-flex;
    align-items: center;
    border: 1.5px solid #1e3a5f;
    border-radius: 4px;
    overflow: hidden;
    font-family: 'Courier New', Courier, monospace;
    font-weight: 700;
    font-size: 13px;
    letter-spacing: 1.2px;
    line-height: 1;
    flex-shrink: 0;
    height: 26px;
}

.s3-plaque-band {
    background: #003399;
    color: white;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 20px;
    height: 100%;
    font-size: 9px;
    letter-spacing: 0;
}

.s3-plaque-text {
    background: white;
    color: #1e293b;
    padding: 0 8px;
    white-space: nowrap;
}

/* ═══════════════════════════════════════════════════════════
   PLANNING TRANSPORT — grille hebdo (abscisse = conducteurs,
   ordonnée = jours de la semaine) + puits de commandes
   ═══════════════════════════════════════════════════════════ */
:root {
    --planning-row-height: 88px;
    --planning-cell-pad: 6px;
    --planning-puits-width: 280px;
    --planning-header-bg: #f8fafc;
    --planning-border: #e2e8f0;
}

.planning-page {
    display: flex;
    flex-direction: column;
    height: 100%;
    overflow: hidden;
}

.planning-header {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 10px 16px;
    background: white;
    border-bottom: 1px solid var(--planning-border);
    flex-shrink: 0;
}

.planning-nav-btn {
    background: white;
    border: 1px solid var(--planning-border);
    border-radius: 8px;
    width: 32px;
    height: 32px;
    font-size: 14px;
    cursor: pointer;
    color: #475569;
    transition: all 0.15s;
}
.planning-nav-btn:hover {
    background: #f1f5f9;
    border-color: #94a3b8;
}

.planning-header-title {
    display: flex;
    flex-direction: column;
    gap: 0;
    line-height: 1.2;
}
.planning-header-title strong { font-size: 15px; }
.planning-header-sub {
    font-size: 11px;
    color: #64748b;
}

.planning-body {
    flex: 1;
    display: grid;
    grid-template-columns: 1fr var(--planning-puits-width);
    overflow: hidden;
    min-height: 0;
}

.planning-grid-wrap {
    overflow: auto;
    background: white;
    border-right: 1px solid var(--planning-border);
}

.planning-grid {
    display: grid;
    /* Pas de grid-template-rows — flux naturel : 1 ligne d'en-tête + 7 jours */
    min-width: 100%;
    width: max-content;
}

.planning-cell-header {
    background: var(--planning-header-bg);
    border-right: 1px solid var(--planning-border);
    border-bottom: 2px solid var(--planning-border);
    padding: 8px 10px;
    font-size: 11px;
    color: #334155;
    position: sticky;
    top: 0;
    z-index: 2;
}

.planning-corner {
    background: #f1f5f9;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.5px;
    font-size: 10px;
    position: sticky;
    left: 0;
    z-index: 3;
}

.planning-conducteur-header {
    display: flex;
    flex-direction: column;
    gap: 4px;
    align-items: flex-start;
}
.planning-conducteur-header strong {
    font-size: 12px;
    color: #1e293b;
}

.planning-act-chip {
    color: white;
    font-size: 10px;
    font-weight: 600;
    padding: 1px 6px;
    border-radius: 8px;
    text-transform: uppercase;
    letter-spacing: 0.3px;
}

.planning-cell-day-header {
    background: var(--planning-header-bg);
    border-right: 1px solid var(--planning-border);
    border-bottom: 1px solid var(--planning-border);
    padding: 6px 8px;
    font-size: 11px;
    color: #334155;
    display: flex;
    flex-direction: column;
    gap: 2px;
    line-height: 1.2;
    position: sticky;
    left: 0;
    z-index: 1;
}
.planning-cell-day-header strong { font-size: 12px; }
.planning-cell-day-header span { color: #64748b; font-size: 10px; }

.planning-cell {
    border-right: 1px solid var(--planning-border);
    border-bottom: 1px solid var(--planning-border);
    padding: var(--planning-cell-pad);
    min-height: var(--planning-row-height);
    display: flex;
    flex-direction: column;
    gap: 4px;
    background: white;
    transition: background 0.1s;
}
.planning-cell:hover {
    background: #f8fafc;
}

.planning-cell-absent {
    background: repeating-linear-gradient(
        45deg,
        #fef3c7 0,
        #fef3c7 8px,
        #fde68a 8px,
        #fde68a 16px
    );
}

.planning-absent-badge {
    align-self: center;
    margin: auto;
    background: #d97706;
    color: white;
    font-size: 12px;
    font-weight: 700;
    padding: 4px 12px;
    border-radius: 999px;
    letter-spacing: 0.5px;
}

.planning-vehicule {
    font-size: 10px;
    color: #475569;
    font-weight: 600;
    background: #f1f5f9;
    padding: 2px 6px;
    border-radius: 4px;
    align-self: flex-start;
}

.planning-segment-card {
    background: white;
    border: 1px solid var(--planning-border);
    border-left: 3px solid #3b82f6;
    border-radius: 6px;
    padding: 5px 8px;
    font-size: 11px;
    cursor: grab;
    line-height: 1.3;
    transition: all 0.1s;
}
.planning-segment-card:hover {
    box-shadow: 0 2px 6px rgba(0, 0, 0, 0.08);
    transform: translateY(-1px);
}
.planning-segment-card:active {
    cursor: grabbing;
}

.planning-segment-num {
    font-weight: 700;
    color: #1e293b;
    font-size: 10px;
}
.planning-segment-client {
    color: #475569;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.planning-empty-cell {
    color: #cbd5e1;
    text-align: center;
    font-size: 14px;
    margin: auto;
}

/* Puits de commandes (panneau droit) */
.planning-puits {
    background: #f8fafc;
    display: flex;
    flex-direction: column;
    overflow: hidden;
}

.planning-puits-header {
    padding: 10px 14px;
    display: flex;
    align-items: center;
    gap: 8px;
    background: white;
    border-bottom: 1px solid var(--planning-border);
    font-size: 13px;
}

.planning-puits-help {
    padding: 8px 14px;
    font-size: 11px;
    color: #64748b;
    background: #fef9c3;
    border-bottom: 1px solid #fde68a;
}

.planning-puits-list {
    flex: 1;
    overflow-y: auto;
    padding: 10px;
    display: flex;
    flex-direction: column;
    gap: 6px;
}

.planning-puits-item {
    background: white;
    border: 1px solid var(--planning-border);
    border-left: 3px solid #f59e0b;
    border-radius: 6px;
    padding: 7px 9px;
    font-size: 11px;
    cursor: grab;
    line-height: 1.35;
    transition: all 0.1s;
}
.planning-puits-item:hover {
    box-shadow: 0 2px 6px rgba(0, 0, 0, 0.08);
    border-left-color: #d97706;
}
.planning-puits-item:active { cursor: grabbing; }

.planning-puits-date {
    color: #64748b;
    font-size: 10px;
    margin-top: 2px;
}

.badge-count {
    background: #1e293b;
    color: white;
    font-size: 11px;
    font-weight: 700;
    padding: 2px 8px;
    border-radius: 999px;
    min-width: 22px;
    text-align: center;
}

/* ════════════════════════════════════════════════════════════════
   STATISTIQUES — Dashboard à widgets personnalisable
   La page utilise le wrapper standard .container + .page-header +
   .content-scrollable de l'app (cf. section 4). Les classes
   ci-dessous ne couvrent que la barre de filtres, la grille de
   widgets, le mode édition et la palette d'ajout — JAMAIS le
   chrome (titre, layout) qui reste celui de l'app pour rester
   visuellement cohérent.
   La grille est CSS Grid 12 colonnes maison (pas MudGrid) — mix
   Mud + grid maison crée des bugs de débordement.
   ════════════════════════════════════════════════════════════════ */

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

.stats-filter-bar {
    display: flex;
    flex-direction: column;
    gap: 10px;
    background: white;
    padding: 14px 16px;
    border-radius: var(--common-div-cornerradius);
    margin-bottom: 16px;
    box-shadow: 0 2px 4px rgba(0, 0, 0, 0.04);
}

/* Ligne « inputs » dans la barre de filtres : alignement par les BAS des
   inputs (align-items: end) pour que les labels soient au-dessus alignés. */
.stats-filter-bar-row {
    display: flex;
    flex-wrap: wrap;
    gap: 12px;
    align-items: end;
}

/* Force la hauteur identique entre <input type="date"> et le trigger du
   S3RichSelect. Le trigger porte min-height:40px (non négociable, il
   contient les avatars/chips multi qui ont besoin de cette hauteur), donc
   on aligne les inputs date sur 40px aussi pour avoir une baseline propre
   en bas (align-items:end). */
.stats-filter-bar input[type="date"],
.stats-filter-bar .s3-rich-trigger {
    height: 40px;
    min-height: 40px;
    box-sizing: border-box;
}

/* Pour aligner pixel-perfect input date / S3RichSelect dans .stats-filter,
   on bascule chaque .stats-filter en grid 2 lignes : ligne 1 = label hauteur
   auto, ligne 2 = champ avec hauteur EXACTE 40px. Sinon le wrapper
   .s3-rich-select (qui n'a pas de hauteur intrinsèque) flotte au pixel près
   différemment de l'input date selon le contenu — résultat : décalage
   vertical visible. */
.stats-filter-bar-row .stats-filter {
    display: grid;
    grid-template-rows: auto 40px;
    gap: 4px;
    align-items: stretch;
}

.stats-filter-bar-row .stats-filter > .s3-rich-select {
    height: 40px;
    display: flex;
    align-items: stretch;
}

.stats-filter-bar-row .stats-filter > .s3-rich-select > .s3-rich-trigger {
    flex: 1;
    width: 100%;
    height: 40px;
    min-height: 0;
}

/* ── Badges plages rapides DANS la barre de filtres stats ──
   Disposition 3 colonnes × 2 lignes, à droite (margin-left:auto), hauteur
   matchant celle du couple label(~15px) + input(40px) = 55px → 2× badge(24px)
   + gap(7px) = 55px. Cohérent avec align-items:end de la barre. */
.stats-filter-bar-row .s3-daterange-badges {
    display: grid;
    grid-template-columns: repeat(3, auto);
    grid-template-rows: auto auto;
    gap: 7px 6px;
    margin-left: auto;
    align-self: end;
}

.stats-filter-bar-row .s3-daterange-badge {
    height: 24px;
    padding: 0 10px;
    font-size: 11px;
}

@media (max-width: 900px) {
    /* Sur écran moyen, on retombe sur le flow naturel : les badges occupent
       toute la largeur sous les inputs, en wrap libre. */
    .stats-filter-bar-row .s3-daterange-badges {
        grid-template-columns: none;
        grid-template-rows: none;
        display: flex;
        flex-wrap: wrap;
        margin-left: 0;
        align-self: stretch;
        width: 100%;
    }
    .stats-filter-bar-row .s3-daterange-badge { height: 26px; padding: 0 12px; font-size: 12px; }
}

/* ── Composant S3DateRangeQuickBadges ──
   Badges de plage rapide « Aujourd'hui / Cette semaine / Mois en cours »,
   réutilisable sur stats Lavage + pages Facturation. */
.s3-daterange-badges {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
}

.s3-daterange-badge {
    height: 26px;
    padding: 0 12px;
    border-radius: 999px;
    border: 1px solid #cbd5e1;
    background: white;
    color: #475569;
    font-size: 12px;
    font-weight: 500;
    cursor: pointer;
    transition: all .15s;
    line-height: 1;
    display: inline-flex;
    align-items: center;
    white-space: nowrap;
}

    .s3-daterange-badge:hover {
        background: #f1f5f9;
        border-color: #94a3b8;
        color: #1e293b;
    }

    .s3-daterange-badge.active {
        background: #667eea;
        border-color: #667eea;
        color: white;
        font-weight: 600;
    }

        .s3-daterange-badge.active:hover {
            background: #5567d8;
            border-color: #5567d8;
        }

.stats-filter {
    display: flex;
    flex-direction: column;
    gap: 4px;
    min-width: 140px;
}

.stats-filter-grow {
    flex: 1 1 220px;
    min-width: 200px;
}

    .stats-filter label {
        font-size: 11px;
        text-transform: uppercase;
        color: #64748b;
        font-weight: 600;
        letter-spacing: .04em;
    }

/* ── Grille CSS 12 colonnes × hauteur unitaire ──
   Toutes les cellules ont la même hauteur de base (--stats-cell-height) pour
   donner un rendu régulier façon dashboard B2B. Un widget peut occuper N
   unités via data-height (cf. StatsWidgetDefinition.HeightUnits côté code).
   Unité fine 180px → granularité par demi pour la plupart des widgets KPI,
   les charts et tableaux montent à 2/3 unités selon leur densité. */
:root {
    --stats-cell-height: 180px;
}

.stats-grid {
    display: grid;
    grid-template-columns: repeat(12, 1fr);
    grid-auto-rows: var(--stats-cell-height);
    gap: 16px;
    align-items: stretch;
}

.stats-grid-cell {
    grid-column: span 6;
    grid-row: span 1;
    display: flex;
    min-height: 0; /* indispensable pour qu'un enfant en height:100% s'adapte */
}

.stats-grid-cell[data-size="3"]  { grid-column: span 3; }
.stats-grid-cell[data-size="6"]  { grid-column: span 6; }
.stats-grid-cell[data-size="9"]  { grid-column: span 9; }
.stats-grid-cell[data-size="12"] { grid-column: span 12; }

.stats-grid-cell[data-height="1"] { grid-row: span 1; }
.stats-grid-cell[data-height="2"] { grid-row: span 2; }
.stats-grid-cell[data-height="3"] { grid-row: span 3; }
.stats-grid-cell[data-height="4"] { grid-row: span 4; }
.stats-grid-cell[data-height="5"] { grid-row: span 5; }
.stats-grid-cell[data-height="6"] { grid-row: span 6; }

/* ── Top-listes : passent automatiquement sur 2 colonnes quand le widget
   est en taille L (9 cols) ou XL (12 cols). En M (6 cols) la liste reste
   en colonne unique pour ne pas tasser. column-count est natif et fluide :
   les items remplissent verticalement la 1re col puis débordent sur la 2e
   (effet « journal »), avec break-inside:avoid pour ne pas couper une ligne. */
.stats-grid-cell[data-size="9"] .stats-toplist,
.stats-grid-cell[data-size="12"] .stats-toplist {
    column-count: 2;
    column-gap: 18px;
    column-fill: balance;
}

.stats-grid-cell[data-size="9"] .stats-toplist-row,
.stats-grid-cell[data-size="12"] .stats-toplist-row {
    break-inside: avoid;
    -webkit-column-break-inside: avoid; /* Safari fallback */
}

/* ── Responsive tablette (< 900px) ──
   Tous les widgets passent en pleine largeur, les filtres aussi.
   Le wiggle est ralenti pour économiser la batterie et éviter le mal de mer. */
@media (max-width: 900px) {
    .stats-grid-cell { grid-column: span 12 !important; }
    .stats-filter { min-width: 100%; }
    .stats-dashboard-page .stats-grid-editing .stats-grid-cell { animation-duration: 1.1s; }
}

/* ── Responsive mobile (< 700px) ──
   Optimisations pour les écrans 360-700px (smartphones en portrait). Toutes
   les règles sont scopées par .stats-dashboard-page pour ne pas impacter le
   reste de l'app. */
@media (max-width: 700px) {
    /* Header : titre/sous-titre + toolbar empilés au lieu de cohabiter sur 1 ligne */
    .stats-dashboard-page .page-header {
        flex-direction: column;
        align-items: stretch;
        gap: 10px;
        padding: 14px 16px;
    }
    .stats-dashboard-page .page-header-title { font-size: 18px; margin-bottom: 4px; }
    .stats-dashboard-page .page-header-subtitle { font-size: 12px; line-height: 1.4; }
    .stats-dashboard-page .stats-toolbar {
        display: flex;
        flex-wrap: wrap;
        gap: 8px;
        justify-content: flex-end;
    }
    .stats-dashboard-page .stats-toolbar .btn { flex: 1 1 auto; min-width: 0; }

    /* Filtres : plus tassés, labels plus petits */
    .stats-dashboard-page .stats-filter-bar { padding: 10px 12px; gap: 8px; }
    .stats-dashboard-page .stats-filter { gap: 2px; }
    .stats-dashboard-page .stats-filter label { font-size: 10px; }

    /* Mode édition : les boutons S/M/L/XL sont inutiles puisque toutes les
       cells sont déjà en w=12 sur mobile. On les masque pour gagner de la
       place et garder ←/→ + × + le drag (largement suffisants). */
    .stats-dashboard-page .stats-edit-btn[title^="Largeur"] { display: none; }
    .stats-dashboard-page .stats-widget-edit-actions { gap: 8px; }
    .stats-dashboard-page .stats-edit-btn { height: 32px; min-width: 32px; font-size: 13px; }

    /* Tableau réductions / actions laveur : font plus petit + scroll
       horizontal en dernier recours si quand même trop large (cas rare). */
    .stats-dashboard-page .stats-widget-card { padding: 12px; }
    .stats-dashboard-page .stats-reductions-table { font-size: 11px; }
    .stats-dashboard-page .stats-reductions-table th,
    .stats-dashboard-page .stats-reductions-table td { padding: 6px 6px; }
    .stats-dashboard-page .stats-widget-card:has(table) { overflow-x: auto; }

    /* CA grid : déjà géré à 700px globalement, on resserre juste les paddings */
    .stats-dashboard-page .stats-ca-block { padding: 12px; }
    .stats-dashboard-page .stats-ca-ht { font-size: 20px; }

    /* Temps d'attente : le grand chiffre central reste lisible mais réduit */
    .stats-dashboard-page .stats-attente-big { font-size: 32px; }

    /* Top-list : compact mais reste lisible */
    .stats-dashboard-page .stats-toplist-row { padding: 4px 0; }
    .stats-dashboard-page .stats-toplist-label { font-size: 12px; }
    .stats-dashboard-page .stats-toplist-count { font-size: 13px; }

    /* Banner nouveautés : la liste des titres se rabat sur plusieurs lignes
       (on retire le ellipsis qui couperait après le 1er) */
    .stats-dashboard-page .stats-newbanner { padding: 12px; gap: 10px; }
    .stats-dashboard-page .stats-newbanner-icon { font-size: 20px; }
    .stats-dashboard-page .stats-newbanner-title { font-size: 12px; }
    .stats-dashboard-page .stats-newbanner-list {
        font-size: 11px;
        white-space: normal;
        line-height: 1.4;
    }

    /* Palette d'ajout : items en pile au lieu d'une grille à 2-3 colonnes */
    .stats-dashboard-page .stats-palette { padding: 12px; }
    .stats-dashboard-page .stats-palette-grid { grid-template-columns: 1fr; }

    /* Wiggle : un peu plus lent encore pour mobile (économie batterie) */
    .stats-dashboard-page .stats-grid-editing .stats-grid-cell {
        animation-duration: 1.3s;
    }

    /* Container racine : padding réduit pour gagner ~16px de largeur utile */
    .stats-dashboard-page.container { padding: 12px; }

    /* Grille : gap plus serré */
    .stats-dashboard-page .stats-grid { gap: 12px; }
}

.stats-widget-wrapper {
    position: relative;
    flex: 1 1 auto;
    display: flex;
    flex-direction: column;
    width: 100%;
    height: 100%;
    min-height: 0;
}

/* Le widget interne (card ou kpi) remplit toute la cellule en hauteur. Le
   contenu défilable (top-listes, tableaux) est géré via overflow-y interne. */
.stats-widget-wrapper > .stats-widget-card,
.stats-widget-wrapper > .stats-widget-kpi {
    flex: 1 1 auto;
    height: 100%;
    min-height: 0;
}

.stats-widget-card {
    overflow: hidden; /* le contenu défilable se gère via une zone interne */
}

/* KPI cards dans le dashboard stats : on centre le chiffre verticalement
   pour éviter qu'il reste en haut dans une cell vide. */
.stats-widget-wrapper > .stats-widget-kpi {
    justify-content: center;
}

/* Listes verticales (top-produits, top-items, palette etc.) et tableaux :
   - flex:0 1 auto = prennent leur hauteur NATURELLE (pas d'étirement), donc
     les peu de lignes restent tassées en haut et le vide va en bas
   - flex-shrink:1 + min-height:0 + overflow-y:auto = quand le contenu dépasse,
     scroll interne propre au lieu de débordement
   - vertical-align:top sur les cellules de tableau = même règle au niveau
     interne (sinon les <tr> peuvent étirer leur contenu verticalement) */
.stats-widget-card .stats-toplist,
.stats-widget-card .stats-reductions-table {
    overflow-y: auto;
    flex: 0 1 auto;
    min-height: 0;
}

.stats-widget-card .stats-reductions-table td,
.stats-widget-card .stats-reductions-table th {
    vertical-align: top;
}

/* ── Drag & drop des widgets (SortableJS, classes injectées par statsDragDrop.js) ──
   Les widgets ne sont déplaçables qu'en mode édition (.stats-grid-editing).
   Le curseur grab/grabbing est porté par l'overlay (qui couvre tout le widget en
   mode édition), pas par le widget lui-même — sinon on aurait un curseur "grab"
   sur les charts en mode lecture, c'est confusing. */
.stats-grid-editing .stats-widget-edit-overlay { cursor: grab; }
.stats-grid-cell-chosen .stats-widget-edit-overlay { cursor: grabbing; }

/* Placeholder (ghost) à l'endroit où la cellule arrivera si on lâche maintenant. */
.stats-grid-cell-ghost {
    opacity: 0.4;
}
    .stats-grid-cell-ghost .stats-widget-card,
    .stats-grid-cell-ghost .stats-widget-kpi {
        background: #eef2ff !important;
        border-style: dashed !important;
        border-color: #c7d2fe !important;
    }

/* Cellule sur laquelle on appuie pour démarrer un drag (avant le mouvement). */
.stats-grid-cell-chosen {
    z-index: 5;
}

/* Cellule en cours de déplacement — petite élévation pour donner du relief. */
.stats-grid-cell-drag {
    box-shadow: 0 12px 30px rgba(15, 23, 42, .22);
    transform: scale(1.02);
    z-index: 10;
    /* Désactive le wiggle pendant le drag — SortableJS gère sa propre transform. */
    animation: none !important;
}

/* ── Effet « wiggle » iPhone-like en mode édition ──
   Très léger (< 0.5°) et lent (0.7s) pour suggérer que les widgets sont
   réarrangeables sans devenir agressif visuellement. Désactivé pendant le
   drag (cellules chosen / drag / ghost) ET si l'utilisateur a demandé à
   réduire les animations (accessibilité). */
@keyframes stats-wiggle-a {
    0%, 100% { transform: rotate(-0.35deg); }
    50% { transform: rotate(0.35deg); }
}

@keyframes stats-wiggle-b {
    0%, 100% { transform: rotate(0.35deg); }
    50% { transform: rotate(-0.35deg); }
}

.stats-grid-editing .stats-grid-cell:not(.stats-grid-cell-chosen):not(.stats-grid-cell-drag):not(.stats-grid-cell-ghost) {
    animation: stats-wiggle-a 0.7s ease-in-out infinite;
    transform-origin: center center;
}

.stats-grid-editing .stats-grid-cell:nth-child(2n):not(.stats-grid-cell-chosen):not(.stats-grid-cell-drag):not(.stats-grid-cell-ghost) {
    animation-name: stats-wiggle-b;
}

@media (prefers-reduced-motion: reduce) {
    .stats-grid-editing .stats-grid-cell { animation: none !important; }
}

/* ── Cartes de widget ───────────────────────────────────────── */

.stats-widget-card {
    background: white;
    border: 1px solid #e2e8f0;
    border-radius: 10px;
    padding: 16px;
    display: flex;
    flex-direction: column;
    gap: 10px;
    width: 100%;
    box-shadow: 0 1px 2px rgba(15, 23, 42, .04);
}

.stats-widget-title {
    font-size: 13px;
    font-weight: 600;
    color: #334155;
    letter-spacing: .01em;
}

.stats-widget-loading,
.stats-widget-empty {
    font-size: 12px;
    color: #94a3b8;
    text-align: center;
    padding: 24px 8px;
}

/* Widget KPI — reprend .kpi-card existant en ajustant la marge */
.stats-widget-kpi {
    width: 100%;
    margin: 0;
}

    .stats-widget-kpi .kpi-sublabel {
        font-size: 11px;
        color: #94a3b8;
        margin-top: 2px;
    }

/* ── Mode édition ──────────────────────────────────────────── */

.stats-widget-edit-overlay {
    position: absolute;
    inset: 0;
    background: rgba(255, 255, 255, .82);
    backdrop-filter: blur(2px);
    border: 2px dashed #667eea;
    border-radius: 10px;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 12px;
    z-index: 5;
}

.stats-widget-edit-title {
    font-size: 13px;
    font-weight: 600;
    color: #1e293b;
    text-align: center;
    padding: 0 16px;
}

.stats-widget-edit-actions {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    justify-content: center;
}

.stats-edit-btn {
    height: 28px;
    min-width: 28px;
    padding: 0 8px;
    border-radius: 8px;
    border: 1px solid #e2e8f0;
    background: white;
    font-size: 12px;
    font-weight: 600;
    color: #334155;
    cursor: pointer;
    transition: all .15s;
}

    .stats-edit-btn:hover {
        background: #f1f5f9;
        border-color: #cbd5e1;
    }

    .stats-edit-btn.active {
        background: #667eea;
        color: white;
        border-color: #667eea;
    }

    .stats-edit-btn-danger:hover {
        background: #fee2e2;
        border-color: #fca5a5;
        color: #b91c1c;
    }

/* ── Palette d'ajout ──────────────────────────────────────── */

.stats-palette {
    margin-top: 24px;
    padding: 16px;
    background: #f8fafc;
    border-radius: 10px;
    border: 1px dashed #cbd5e1;
}

.stats-palette-title {
    font-size: 12px;
    text-transform: uppercase;
    color: #64748b;
    font-weight: 600;
    margin-bottom: 10px;
    letter-spacing: .04em;
}

.stats-palette-empty {
    font-size: 12px;
    color: #94a3b8;
    text-align: center;
    padding: 8px;
}

.stats-palette-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
    gap: 10px;
}

.stats-palette-item {
    background: white;
    border: 1px solid #e2e8f0;
    border-radius: 8px;
    padding: 10px 12px;
    text-align: left;
    cursor: pointer;
    transition: all .15s;
    display: flex;
    flex-direction: column;
    gap: 4px;
}

    .stats-palette-item:hover {
        border-color: #667eea;
        background: #f5f7ff;
        transform: translateY(-1px);
    }

.stats-palette-item-title {
    font-size: 13px;
    font-weight: 600;
    color: #1e293b;
}

.stats-palette-item-desc {
    font-size: 11px;
    color: #64748b;
    line-height: 1.35;
}

.stats-empty {
    background: #f8fafc;
    border: 1px dashed #cbd5e1;
    border-radius: 10px;
    padding: 32px;
    text-align: center;
    color: #64748b;
    font-size: 13px;
}

/* ── Note de bas de widget (estimation, méthodologie, top tronqué…) ── */
.stats-widget-note {
    margin-top: 8px;
    font-size: 11px;
    color: #94a3b8;
    line-height: 1.4;
    border-top: 1px dashed #e2e8f0;
    padding-top: 8px;
}

/* ── Widget « CA facturé & à facturer » — 3 blocs côte à côte ── */
.stats-ca-grid {
    display: grid;
    grid-template-columns: 1fr 1fr 1fr;
    gap: 12px;
}

@media (max-width: 700px) {
    .stats-ca-grid { grid-template-columns: 1fr; }
}

.stats-ca-block {
    background: #f8fafc;
    border-radius: 8px;
    padding: 14px 16px;
    border-left: 3px solid #cbd5e1;
}

.stats-ca-block-facture { border-left-color: #27ae60; }
.stats-ca-block-pending { border-left-color: #f59e0b; }
.stats-ca-block-total { border-left-color: #667eea; background: #eef2ff; }
.stats-ca-block-panier { border-left-color: #8b5cf6; }

/* Variante 4 colonnes pour intégrer le panier moyen sans empiéter sur le reste */
.stats-ca-grid-4 {
    grid-template-columns: repeat(4, 1fr);
}

@media (max-width: 900px) {
    .stats-ca-grid-4 { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 500px) {
    .stats-ca-grid-4 { grid-template-columns: 1fr; }
}

.stats-ca-label {
    font-size: 11px;
    text-transform: uppercase;
    color: #64748b;
    font-weight: 600;
    letter-spacing: .04em;
    margin-bottom: 6px;
}

.stats-ca-estim {
    text-transform: none;
    font-weight: 400;
    color: #94a3b8;
}

.stats-ca-ht {
    font-size: 22px;
    font-weight: 700;
    color: #1e293b;
    line-height: 1.1;
}

.stats-ca-unit {
    font-size: 12px;
    font-weight: 500;
    color: #94a3b8;
    margin-left: 4px;
}

.stats-ca-ttc {
    font-size: 13px;
    color: #475569;
    margin-top: 2px;
}

.stats-ca-detail {
    font-size: 11px;
    color: #94a3b8;
    margin-top: 6px;
}

/* ── Widget « Réductions par client » — tableau ── */
.stats-reductions-table {
    width: 100%;
    border-collapse: collapse;
    font-size: 12px;
}

    .stats-reductions-table th {
        text-align: left;
        font-size: 11px;
        text-transform: uppercase;
        color: #64748b;
        font-weight: 600;
        letter-spacing: .04em;
        padding: 8px 10px;
        border-bottom: 1px solid #e2e8f0;
    }

        .stats-reductions-table th.num { text-align: right; }

    .stats-reductions-table td {
        padding: 10px;
        border-bottom: 1px solid #f1f5f9;
    }

        .stats-reductions-table td.num {
            text-align: right;
            font-variant-numeric: tabular-nums;
            white-space: nowrap;
        }

    .stats-reductions-table tfoot td {
        border-top: 2px solid #e2e8f0;
        border-bottom: none;
        background: #f8fafc;
    }

.stats-reduc-client { color: #1e293b; font-weight: 500; }
.stats-reduc-meta { font-size: 11px; color: #94a3b8; margin-top: 2px; }
.stats-reduc-total { color: #b91c1c; font-weight: 600; }

/* ── Widget « Temps d'attente » — grand chiffre + secondaires ── */
.stats-attente-main {
    text-align: center;
    padding: 6px 0 10px;
}

.stats-attente-big {
    font-size: 38px;
    font-weight: 700;
    color: #1e293b;
    line-height: 1;
}

.stats-attente-caption {
    font-size: 12px;
    color: #64748b;
    margin-top: 6px;
}

.stats-attente-secondary {
    display: flex;
    gap: 12px;
    justify-content: space-around;
    border-top: 1px solid #f1f5f9;
    padding-top: 12px;
}

.stats-attente-cell {
    text-align: center;
}

.stats-attente-label {
    font-size: 11px;
    text-transform: uppercase;
    color: #64748b;
    font-weight: 600;
    letter-spacing: .04em;
}

.stats-attente-value {
    font-size: 18px;
    font-weight: 600;
    color: #1e293b;
    margin-top: 2px;
}

/* ── Widget « Nombre de lavages » — surcharge couleur annulés / remboursés ── */
.stats-nblavages-main { text-align: center; padding: 6px 0 10px; }
.stats-nblavages-cancel-label { color: #b91c1c; }
.stats-nblavages-cancel-value { color: #b91c1c; }
.stats-nblavages-refund-label { color: #b45309; }
.stats-nblavages-refund-value { color: #b45309; }
.stats-nblavages-sub {
    font-size: 11px;
    color: #94a3b8;
    margin-top: 2px;
}

/* ── Variante compacte (HeightUnits=1) — 3 chiffres côte à côte ── */
.stats-nblavages-row {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 12px;
    align-items: center;
}

.stats-nblavages-cell {
    text-align: center;
}

.stats-nblavages-mini-label {
    font-size: 11px;
    text-transform: uppercase;
    color: #64748b;
    font-weight: 600;
    letter-spacing: .04em;
    margin-bottom: 4px;
}

.stats-nblavages-mini-value {
    font-size: 26px;
    font-weight: 700;
    color: #1e293b;
    line-height: 1;
    font-variant-numeric: tabular-nums;
}

.stats-nblavages-mini-sub {
    font-size: 11px;
    color: #94a3b8;
    margin-top: 2px;
}

/* ── Top liste (produits transportés / items sélectionnés / etc.) ──
   Pattern : rang à gauche, label + meta + barre proportionnelle au milieu,
   compteur à droite. Pas de chart pour rester sobre et performant. */
.stats-toplist {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 6px;
}

.stats-toplist-row {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 6px 0;
    border-bottom: 1px solid #f1f5f9;
}

    .stats-toplist-row:last-child { border-bottom: none; }

.stats-toplist-rank {
    flex: 0 0 24px;
    text-align: center;
    font-size: 12px;
    font-weight: 700;
    color: #94a3b8;
    font-variant-numeric: tabular-nums;
}

.stats-toplist-body {
    flex: 1 1 auto;
    min-width: 0;
}

.stats-toplist-label {
    font-size: 13px;
    color: #1e293b;
    font-weight: 500;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.stats-toplist-meta {
    font-size: 11px;
    color: #94a3b8;
    margin-top: 1px;
}

.stats-toplist-bar {
    height: 4px;
    background: #f1f5f9;
    border-radius: 999px;
    margin-top: 4px;
    overflow: hidden;
}

.stats-toplist-bar-fill {
    height: 100%;
    background: #667eea;
    border-radius: 999px;
    transition: width .25s ease;
}

.stats-toplist-count {
    flex: 0 0 auto;
    font-size: 14px;
    font-weight: 700;
    color: #1e293b;
    font-variant-numeric: tabular-nums;
    min-width: 36px;
    text-align: right;
}

/* ── Bandeau « nouveaux blocs disponibles » ──
   Apparaît au-dessus de la grille de widgets quand le catalogue a été enrichi
   côté code et que l'utilisateur n'a pas encore acquitté (« Explorer » ou « × »).
   Ne pas confondre avec .s3-alert : c'est un bandeau d'annonce d'évolution
   produit, plus visuel, avec un bouton d'action et un dismiss explicite. */
.stats-newbanner {
    display: flex;
    align-items: center;
    gap: 14px;
    background: linear-gradient(135deg, #eef2ff 0%, #faf5ff 100%);
    border: 1px solid #c7d2fe;
    border-radius: 10px;
    padding: 14px 16px;
    margin-bottom: 16px;
    box-shadow: 0 1px 2px rgba(102, 126, 234, .08);
}

.stats-newbanner-icon {
    flex: 0 0 auto;
    font-size: 24px;
    line-height: 1;
}

.stats-newbanner-body {
    flex: 1 1 auto;
    min-width: 0;
}

.stats-newbanner-title {
    font-size: 13px;
    font-weight: 600;
    color: #4338ca;
    margin-bottom: 2px;
}

.stats-newbanner-list {
    font-size: 12px;
    color: #475569;
    line-height: 1.4;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.stats-newbanner-actions {
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    gap: 8px;
}

.stats-newbanner-close {
    background: transparent;
    border: 1px solid transparent;
    color: #6366f1;
    width: 28px;
    height: 28px;
    border-radius: 8px;
    cursor: pointer;
    font-size: 18px;
    line-height: 1;
    display: flex;
    align-items: center;
    justify-content: center;
    transition: all .15s;
}

    .stats-newbanner-close:hover {
        background: rgba(99, 102, 241, .1);
        border-color: #c7d2fe;
    }

@media (max-width: 700px) {
    .stats-newbanner { flex-wrap: wrap; }
    .stats-newbanner-actions { width: 100%; justify-content: flex-end; }
}

